Print this page
12257 resync smatch to 0.6.1-rc1-il-4


 751         return ret_info.return_range_list;
 752 }
 753 
 754 static void match_call_marker(struct expression *expr)
 755 {
 756         struct symbol *type;
 757 
 758         type = get_type(expr->fn);
 759         if (type && type->type == SYM_PTR)
 760                 type = get_real_base_type(type);
 761 
 762         /*
 763          * we just want to record something in the database so that if we have
 764          * two calls like:  frob(4); frob(some_unkown); then on the receiving
 765          * side we know that sometimes frob is called with unknown parameters.
 766          */
 767 
 768         sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
 769 }
 770 
 771 static char *show_offset(int offset)
 772 {
 773         static char buf[64];
 774 
 775         buf[0] = '\0';
 776         if (offset != -1)
 777                 snprintf(buf, sizeof(buf), "(-%d)", offset);
 778         return buf;
 779 }
 780 
 781 int is_recursive_member(const char *name)
 782 {
 783         char buf[256];
 784         const char *p, *next;
 785         int size;
 786 
 787         p = strchr(name, '>');
 788         if (!p)
 789                 return 0;
 790         p++;
 791         while (true) {
 792                 next = strchr(p, '>');
 793                 if (!next)
 794                         return 0;
 795                 next++;
 796 
 797                 size = next - p;
 798                 if (size >= sizeof(buf))
 799                         return 0;
 800                 memcpy(buf, p, size);


 843                 goto free;
 844         if (sm_name[len] == '\0') {
 845                 snprintf(buf, sizeof(buf), "%s%s$",
 846                          add_star ? "*" : "", is_address ? "*" : "");
 847         } else {
 848                 if (sm_name[len] != '.' && sm_name[len] != '-')
 849                         goto free;
 850                 if (sm_name[len] == '-')
 851                         len++;
 852                 // FIXME does is_address really imply that sm_name[len] == '-'
 853                 snprintf(buf, sizeof(buf), "%s$->%s", add_star ? "*" : "",
 854                          sm_name + len);
 855         }
 856 
 857         ret = alloc_sname(buf);
 858 free:
 859         free_string(name);
 860         return ret;
 861 }
 862 
 863 static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 864         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 865 {
 866         struct sm_state *sm;
 867         const char *sm_name;
 868         char *name;
 869         struct symbol *sym;
 870         int len;
 871         char printed_name[256];
 872         int is_address = 0;
 873         bool add_star;
 874         struct symbol *type;
 875 
 876         expr = strip_expr(expr);
 877         if (!expr)
 878                 return;
 879         type = get_type(expr);
 880         if (type && type_bits(type) < type_bits(&ulong_ctype))
 881                 return;
 882 
 883         if (expr->type == EXPR_PREOP && expr->op == '&') {


 885                 is_address = 1;
 886         }
 887 
 888         name = expr_to_var_sym(expr, &sym);
 889         if (!name || !sym)
 890                 goto free;
 891 
 892         len = strlen(name);
 893         FOR_EACH_SM(stree, sm) {
 894                 if (sm->sym != sym)
 895                         continue;
 896                 sm_name = sm->name;
 897                 add_star = false;
 898                 if (sm_name[0] == '*') {
 899                         add_star = true;
 900                         sm_name++;
 901                 }
 902                 // FIXME: simplify?
 903                 if (!add_star && strcmp(name, sm_name) == 0) {
 904                         if (is_address)
 905                                 snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 906                         else /* these are already handled. fixme: handle them here */
 907                                 continue;
 908                 } else if (add_star && strcmp(name, sm_name) == 0) {
 909                         snprintf(printed_name, sizeof(printed_name), "%s*$%s",
 910                                  is_address ? "*" : "", show_offset(offset));
 911                 } else if (strncmp(name, sm_name, len) == 0) {
 912                         if (sm_name[len] != '.' && sm_name[len] != '-')
 913                                 continue;
 914                         if (is_address)
 915                                 snprintf(printed_name, sizeof(printed_name),
 916                                          "%s$%s->%s", add_star ? "*" : "",
 917                                          show_offset(offset), sm_name + len + 1);
 918                         else
 919                                 snprintf(printed_name, sizeof(printed_name),
 920                                          "%s$%s%s", add_star ? "*" : "",
 921                                          show_offset(offset), sm_name + len);
 922                 } else {
 923                         continue;
 924                 }
 925                 if (is_recursive_member(printed_name))
 926                         continue;
 927                 callback(call, param, printed_name, sm);
 928         } END_FOR_EACH_SM(sm);
 929 free:
 930         free_string(name);
 931 }
 932 
 933 static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
 934 {
 935         char **container = _container;
 936         static char buf[256];
 937 
 938         snprintf(buf, sizeof(buf), "%s", argv[0]);
 939         *container = buf;
 940         return 0;
 941 }
 942 
 943 static void print_container_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
 944         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 945 {
 946         struct expression *tmp;
 947         char *container = NULL;
 948         int offset;
 949         int holder_offset;
 950         char *p;
 951 
 952         if (!call->fn || call->fn->type != EXPR_SYMBOL || !call->fn->symbol)
 953                 return;
 954 
 955         /*
 956          * We can't use the in-mem DB because we have to parse the function
 957          * first, then we know if it takes a container, then we know to pass it
 958          * the container data.
 959          *
 960          */
 961         run_sql(&param_used_callback, &container,
 962                 "select key from return_implies where %s and type = %d and key like '%%$(%%' and parameter = %d limit 1;",
 963                 get_static_filter(call->fn->symbol), CONTAINER, param);
 964         if (!container)
 965                 return;
 966 
 967         p = strchr(container, '-');
 968         if (!p)
 969                 return;
 970         offset = atoi(p);
 971         p = strchr(p, ')');
 972         if (!p)
 973                 return;
 974         p++;
 975 
 976         tmp = get_assigned_expr(expr);
 977         if (tmp)
 978                 expr = tmp;
 979 
 980         if (expr->type != EXPR_PREOP || expr->op != '&')
 981                 return;
 982         expr = strip_expr(expr->unop);
 983         holder_offset = get_member_offset_from_deref(expr);
 984         if (-holder_offset != offset)
 985                 return;
 986 
 987         expr = strip_expr(expr->deref);
 988         if (expr->type == EXPR_PREOP && expr->op == '*')
 989                 expr = strip_expr(expr->unop);
 990 
 991         print_struct_members(call, expr, param, holder_offset, stree, callback);
 992 }
 993 
 994 static void match_call_info(struct expression *call)
 995 {
 996         struct member_info_callback *cb;
 997         struct expression *arg;
 998         struct stree *stree;
 999         char *name;
1000         int i;
1001 
1002         name = get_fnptr_name(call->fn);
1003         if (!name)
1004                 return;
1005 
1006         FOR_EACH_PTR(member_callbacks, cb) {
1007                 stree = get_all_states_stree(cb->owner);
1008                 i = 0;
1009                 FOR_EACH_PTR(call->args, arg) {
1010                         print_struct_members(call, arg, i, -1, stree, cb->callback);
1011                         print_container_struct_members(call, arg, i, stree, cb->callback);
1012                         i++;
1013                 } END_FOR_EACH_PTR(arg);
1014                 free_stree(&stree);
1015         } END_FOR_EACH_PTR(cb);
1016 
1017         free_string(name);
1018 }
1019 
1020 static int get_param(int param, char **name, struct symbol **sym)
1021 {
1022         struct symbol *arg;
1023         int i;
1024 
1025         i = 0;
1026         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
1027                 /*
1028                  * this is a temporary hack to work around a bug (I think in sparse?)
1029                  * 2.6.37-rc1:fs/reiserfs/journal.o
1030                  * If there is a function definition without parameter name found
1031                  * after a function implementation then it causes a crash.




 751         return ret_info.return_range_list;
 752 }
 753 
 754 static void match_call_marker(struct expression *expr)
 755 {
 756         struct symbol *type;
 757 
 758         type = get_type(expr->fn);
 759         if (type && type->type == SYM_PTR)
 760                 type = get_real_base_type(type);
 761 
 762         /*
 763          * we just want to record something in the database so that if we have
 764          * two calls like:  frob(4); frob(some_unkown); then on the receiving
 765          * side we know that sometimes frob is called with unknown parameters.
 766          */
 767 
 768         sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
 769 }
 770 










 771 int is_recursive_member(const char *name)
 772 {
 773         char buf[256];
 774         const char *p, *next;
 775         int size;
 776 
 777         p = strchr(name, '>');
 778         if (!p)
 779                 return 0;
 780         p++;
 781         while (true) {
 782                 next = strchr(p, '>');
 783                 if (!next)
 784                         return 0;
 785                 next++;
 786 
 787                 size = next - p;
 788                 if (size >= sizeof(buf))
 789                         return 0;
 790                 memcpy(buf, p, size);


 833                 goto free;
 834         if (sm_name[len] == '\0') {
 835                 snprintf(buf, sizeof(buf), "%s%s$",
 836                          add_star ? "*" : "", is_address ? "*" : "");
 837         } else {
 838                 if (sm_name[len] != '.' && sm_name[len] != '-')
 839                         goto free;
 840                 if (sm_name[len] == '-')
 841                         len++;
 842                 // FIXME does is_address really imply that sm_name[len] == '-'
 843                 snprintf(buf, sizeof(buf), "%s$->%s", add_star ? "*" : "",
 844                          sm_name + len);
 845         }
 846 
 847         ret = alloc_sname(buf);
 848 free:
 849         free_string(name);
 850         return ret;
 851 }
 852 
 853 static void print_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
 854         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 855 {
 856         struct sm_state *sm;
 857         const char *sm_name;
 858         char *name;
 859         struct symbol *sym;
 860         int len;
 861         char printed_name[256];
 862         int is_address = 0;
 863         bool add_star;
 864         struct symbol *type;
 865 
 866         expr = strip_expr(expr);
 867         if (!expr)
 868                 return;
 869         type = get_type(expr);
 870         if (type && type_bits(type) < type_bits(&ulong_ctype))
 871                 return;
 872 
 873         if (expr->type == EXPR_PREOP && expr->op == '&') {


 875                 is_address = 1;
 876         }
 877 
 878         name = expr_to_var_sym(expr, &sym);
 879         if (!name || !sym)
 880                 goto free;
 881 
 882         len = strlen(name);
 883         FOR_EACH_SM(stree, sm) {
 884                 if (sm->sym != sym)
 885                         continue;
 886                 sm_name = sm->name;
 887                 add_star = false;
 888                 if (sm_name[0] == '*') {
 889                         add_star = true;
 890                         sm_name++;
 891                 }
 892                 // FIXME: simplify?
 893                 if (!add_star && strcmp(name, sm_name) == 0) {
 894                         if (is_address)
 895                                 snprintf(printed_name, sizeof(printed_name), "*$");
 896                         else /* these are already handled. fixme: handle them here */
 897                                 continue;
 898                 } else if (add_star && strcmp(name, sm_name) == 0) {
 899                         snprintf(printed_name, sizeof(printed_name), "%s*$",
 900                                  is_address ? "*" : "");
 901                 } else if (strncmp(name, sm_name, len) == 0) {
 902                         if (sm_name[len] != '.' && sm_name[len] != '-')
 903                                 continue;
 904                         if (is_address)
 905                                 snprintf(printed_name, sizeof(printed_name),
 906                                          "%s$->%s", add_star ? "*" : "",
 907                                          sm_name + len + 1);
 908                         else
 909                                 snprintf(printed_name, sizeof(printed_name),
 910                                          "%s$%s", add_star ? "*" : "",
 911                                          sm_name + len);
 912                 } else {
 913                         continue;
 914                 }
 915                 if (is_recursive_member(printed_name))
 916                         continue;
 917                 callback(call, param, printed_name, sm);
 918         } END_FOR_EACH_SM(sm);
 919 free:
 920         free_string(name);
 921 }
 922 





























































 923 static void match_call_info(struct expression *call)
 924 {
 925         struct member_info_callback *cb;
 926         struct expression *arg;
 927         struct stree *stree;
 928         char *name;
 929         int i;
 930 
 931         name = get_fnptr_name(call->fn);
 932         if (!name)
 933                 return;
 934 
 935         FOR_EACH_PTR(member_callbacks, cb) {
 936                 stree = get_all_states_stree(cb->owner);
 937                 i = 0;
 938                 FOR_EACH_PTR(call->args, arg) {
 939                         print_struct_members(call, arg, i, stree, cb->callback);

 940                         i++;
 941                 } END_FOR_EACH_PTR(arg);
 942                 free_stree(&stree);
 943         } END_FOR_EACH_PTR(cb);
 944 
 945         free_string(name);
 946 }
 947 
 948 static int get_param(int param, char **name, struct symbol **sym)
 949 {
 950         struct symbol *arg;
 951         int i;
 952 
 953         i = 0;
 954         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
 955                 /*
 956                  * this is a temporary hack to work around a bug (I think in sparse?)
 957                  * 2.6.37-rc1:fs/reiserfs/journal.o
 958                  * If there is a function definition without parameter name found
 959                  * after a function implementation then it causes a crash.