Print this page
11506 smatch resync


  19  * What we're doing here is saving all the possible values for static variables.
  20  * Later on we might do globals as well.
  21  *
  22  */
  23 
  24 #include "smatch.h"
  25 #include "smatch_slist.h"
  26 #include "smatch_extra.h"
  27 
  28 static int my_id;
  29 static struct stree *vals;
  30 
  31 static int save_rl(void *_rl, int argc, char **argv, char **azColName)
  32 {
  33         unsigned long *rl = _rl;
  34 
  35         *rl = strtoul(argv[0], NULL, 10);
  36         return 0;
  37 }
  38 
  39 static struct range_list *select_orig_rl(sval_t sval)
  40 {
  41         struct range_list *rl = NULL;
  42         mtag_t tag = sval.uvalue & ~MTAG_OFFSET_MASK;
  43         int offset = sval.uvalue & MTAG_OFFSET_MASK;
  44 
  45         mem_sql(&save_rl, &rl, "select value from mtag_data where tag = %lld and offset = %d;",
  46                 tag, offset);
  47         return rl;
  48 }
  49 
  50 static int is_kernel_param(const char *name)
  51 {
  52         struct sm_state *tmp;
  53         char buf[256];
  54 
  55         /*
  56          * I'm ignoring these because otherwise Smatch thinks that kernel
  57          * parameters are always set to the default.
  58          *
  59          */
  60 
  61         if (option_project != PROJ_KERNEL)
  62                 return 0;
  63 
  64         snprintf(buf, sizeof(buf), "__param_%s.arg", name);
  65 
  66         FOR_EACH_SM(vals, tmp) {
  67                 if (strcmp(tmp->name, buf) == 0)
  68                         return 1;
  69         } END_FOR_EACH_SM(tmp);
  70 
  71         return 0;
  72 }
  73 
  74 void insert_mtag_data(sval_t sval, struct range_list *rl)
  75 {
  76         mtag_t tag = sval.uvalue & ~MTAG_OFFSET_MASK;
  77         int offset = sval.uvalue & MTAG_OFFSET_MASK;
  78 
  79         rl = clone_rl_permanent(rl);
  80 
  81         mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
  82                 tag, offset, DATA_VALUE);
  83         mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",
  84                 tag, offset, DATA_VALUE, (unsigned long)rl);
  85 }
  86 
  87 void update_mtag_data(struct expression *expr)
  88 {
  89         struct range_list *orig, *new, *rl;

  90         char *name;
  91         sval_t sval;

  92 
  93         name = expr_to_var(expr);
  94         if (is_kernel_param(name)) {
  95                 free_string(name);
  96                 return;
  97         }
  98         free_string(name);
  99 
 100         if (!get_mtag_addr_sval(expr, &sval))
 101                 return;
 102 






 103         get_absolute_rl(expr, &rl);
 104 
 105         orig = select_orig_rl(sval);
 106         new = rl_union(orig, rl);
 107         insert_mtag_data(sval, new);
 108 }
 109 
 110 static void match_global_assign(struct expression *expr)
 111 {
 112         struct range_list *rl;
 113         sval_t sval;

 114         char *name;
 115 
 116         name = expr_to_var(expr->left);
 117         if (is_kernel_param(name)) {
 118                 free_string(name);
 119                 return;
 120         }
 121         free_string(name);
 122 
 123         if (!get_mtag_addr_sval(expr->left, &sval))
 124                 return;
 125 
 126         get_absolute_rl(expr->right, &rl);
 127         insert_mtag_data(sval, rl);
 128 }
 129 
 130 static int save_mtag_data(void *_unused, int argc, char **argv, char **azColName)
 131 {
 132         struct range_list *rl;
 133 
 134         if (argc != 4) {
 135                 sm_msg("Error saving mtag data");
 136                 return 0;
 137         }
 138         if (!option_info)
 139                 return 0;
 140 
 141         rl = (struct range_list *)strtoul(argv[3], NULL, 10);
 142         sm_msg("SQL: insert into mtag_data values ('%s', '%s', '%s', '%s');",
 143                argv[0], argv[1], argv[2], show_rl(rl));
 144 
 145         return 0;
 146 }
 147 


 154 struct db_info {
 155         struct symbol *type;
 156         struct range_list *rl;
 157 };
 158 
 159 static int get_vals(void *_db_info, int argc, char **argv, char **azColName)
 160 {
 161         struct db_info *db_info = _db_info;
 162         struct range_list *tmp;
 163 
 164         str_to_rl(db_info->type, argv[0], &tmp);
 165         if (db_info->rl)
 166                 db_info->rl = rl_union(db_info->rl, tmp);
 167         else
 168                 db_info->rl = tmp;
 169 
 170         return 0;
 171 }
 172 
 173 struct db_cache_results {
 174         sval_t sval;
 175         struct range_list *rl;
 176 };
 177 static struct db_cache_results cached_results[8];
 178 
 179 static int get_rl_from_mtag_sval(sval_t sval, struct symbol *type, struct range_list **rl)
 180 {
 181         struct db_info db_info = {};
 182         mtag_t tag;
 183         int offset;
 184         static int idx;
 185         int ret;
 186         int i;
 187 




 188         for (i = 0; i < ARRAY_SIZE(cached_results); i++) {
 189                 if (sval.uvalue == cached_results[i].sval.uvalue) {
 190                         if (cached_results[i].rl) {
 191                                 *rl = cached_results[i].rl;
 192                                 return 1;
 193                         }
 194                         return 0;
 195                 }
 196         }
 197 
 198         tag = sval.uvalue & ~MTAG_OFFSET_MASK;
 199         offset = sval.uvalue & MTAG_OFFSET_MASK;
 200         if (offset == MTAG_OFFSET_MASK) {
 201                 ret = 0;
 202                 goto update_cache;
 203         }
 204         db_info.type = type;
 205 
 206         run_sql(get_vals, &db_info,
 207                 "select value from mtag_data where tag = %lld and offset = %d and type = %d;",
 208                 tag, offset, DATA_VALUE);
 209         if (!db_info.rl || is_whole_rl(db_info.rl)) {
 210                 db_info.rl = NULL;
 211                 ret = 0;
 212                 goto update_cache;
 213         }
 214 
 215         *rl = db_info.rl;
 216         ret = 1;
 217 
 218 update_cache:
 219         cached_results[idx].sval = sval;
 220         cached_results[idx].rl = db_info.rl;
 221         idx = (idx + 1) % ARRAY_SIZE(cached_results);
 222 
 223         return ret;
 224 }
 225 
 226 static void clear_cache(struct symbol *sym)
 227 {
 228         memset(cached_results, 0, sizeof(cached_results));
 229 }
 230 
 231 int get_mtag_rl(struct expression *expr, struct range_list **rl)
 232 {
 233         struct symbol *type;
 234         sval_t sval;

 235 
 236         if (!get_mtag_addr_sval(expr, &sval))
 237                 return 0;


 238 
 239         type = get_type(expr);
 240         if (!type)
 241                 return 0;
 242 
 243         return get_rl_from_mtag_sval(sval, type, rl);
 244 }
 245 
 246 void register_mtag_data(int id)
 247 {
 248         my_id = id;
 249 
 250         add_hook(&clear_cache, FUNC_DEF_HOOK);
 251 
 252 //      if (!option_info)
 253 //              return;
 254         add_hook(&match_global_assign, GLOBAL_ASSIGNMENT_HOOK);
 255         add_hook(&match_end_file, END_FILE_HOOK);
 256 }
 257 


  19  * What we're doing here is saving all the possible values for static variables.
  20  * Later on we might do globals as well.
  21  *
  22  */
  23 
  24 #include "smatch.h"
  25 #include "smatch_slist.h"
  26 #include "smatch_extra.h"
  27 
  28 static int my_id;
  29 static struct stree *vals;
  30 
  31 static int save_rl(void *_rl, int argc, char **argv, char **azColName)
  32 {
  33         unsigned long *rl = _rl;
  34 
  35         *rl = strtoul(argv[0], NULL, 10);
  36         return 0;
  37 }
  38 
  39 static struct range_list *select_orig(mtag_t tag, int offset)
  40 {
  41         struct range_list *rl = NULL;


  42 
  43         mem_sql(&save_rl, &rl, "select value from mtag_data where tag = %lld and offset = %d;",
  44                 tag, offset);
  45         return rl;
  46 }
  47 
  48 static int is_kernel_param(const char *name)
  49 {
  50         struct sm_state *tmp;
  51         char buf[256];
  52 
  53         /*
  54          * I'm ignoring these because otherwise Smatch thinks that kernel
  55          * parameters are always set to the default.
  56          *
  57          */
  58 
  59         if (option_project != PROJ_KERNEL)
  60                 return 0;
  61 
  62         snprintf(buf, sizeof(buf), "__param_%s.arg", name);
  63 
  64         FOR_EACH_SM(vals, tmp) {
  65                 if (strcmp(tmp->name, buf) == 0)
  66                         return 1;
  67         } END_FOR_EACH_SM(tmp);
  68 
  69         return 0;
  70 }
  71 
  72 static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
  73 {



  74         rl = clone_rl_permanent(rl);
  75 
  76         mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
  77                 tag, offset, DATA_VALUE);
  78         mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",
  79                 tag, offset, DATA_VALUE, (unsigned long)rl);
  80 }
  81 
  82 void update_mtag_data(struct expression *expr)
  83 {
  84         struct range_list *orig, *new, *rl;
  85         struct symbol *type;
  86         char *name;
  87         mtag_t tag;
  88         int offset;
  89 
  90         name = expr_to_var(expr);
  91         if (is_kernel_param(name)) {
  92                 free_string(name);
  93                 return;
  94         }
  95         free_string(name);
  96 
  97         if (!expr_to_mtag_offset(expr, &tag, &offset))
  98                 return;
  99 
 100         type = get_type(expr);
 101         if ((offset == 0) &&
 102             (!type || type == &void_ctype ||
 103              type->type == SYM_STRUCT || type->type == SYM_UNION || type->type == SYM_ARRAY))
 104                 return;
 105 
 106         get_absolute_rl(expr, &rl);
 107 
 108         orig = select_orig(tag, offset);
 109         new = rl_union(orig, rl);
 110         insert_mtag_data(tag, offset, new);
 111 }
 112 
 113 static void match_global_assign(struct expression *expr)
 114 {
 115         struct range_list *rl;
 116         mtag_t tag;
 117         int offset;
 118         char *name;
 119 
 120         name = expr_to_var(expr->left);
 121         if (is_kernel_param(name)) {
 122                 free_string(name);
 123                 return;
 124         }
 125         free_string(name);
 126 
 127         if (!expr_to_mtag_offset(expr->left, &tag, &offset))
 128                 return;
 129 
 130         get_absolute_rl(expr->right, &rl);
 131         insert_mtag_data(tag, offset, rl);
 132 }
 133 
 134 static int save_mtag_data(void *_unused, int argc, char **argv, char **azColName)
 135 {
 136         struct range_list *rl;
 137 
 138         if (argc != 4) {
 139                 sm_msg("Error saving mtag data");
 140                 return 0;
 141         }
 142         if (!option_info)
 143                 return 0;
 144 
 145         rl = (struct range_list *)strtoul(argv[3], NULL, 10);
 146         sm_msg("SQL: insert into mtag_data values ('%s', '%s', '%s', '%s');",
 147                argv[0], argv[1], argv[2], show_rl(rl));
 148 
 149         return 0;
 150 }
 151 


 158 struct db_info {
 159         struct symbol *type;
 160         struct range_list *rl;
 161 };
 162 
 163 static int get_vals(void *_db_info, int argc, char **argv, char **azColName)
 164 {
 165         struct db_info *db_info = _db_info;
 166         struct range_list *tmp;
 167 
 168         str_to_rl(db_info->type, argv[0], &tmp);
 169         if (db_info->rl)
 170                 db_info->rl = rl_union(db_info->rl, tmp);
 171         else
 172                 db_info->rl = tmp;
 173 
 174         return 0;
 175 }
 176 
 177 struct db_cache_results {
 178         mtag_t tag;
 179         struct range_list *rl;
 180 };
 181 static struct db_cache_results cached_results[8];
 182 
 183 static int get_rl_from_mtag_offset(mtag_t tag, int offset, struct symbol *type, struct range_list **rl)
 184 {
 185         struct db_info db_info = {};
 186         mtag_t merged = tag | offset;

 187         static int idx;
 188         int ret;
 189         int i;
 190 
 191         if (!type || type == &void_ctype ||
 192             (type->type == SYM_STRUCT || type->type == SYM_ARRAY || type->type == SYM_UNION))
 193                 return 0;
 194 
 195         for (i = 0; i < ARRAY_SIZE(cached_results); i++) {
 196                 if (merged == cached_results[i].tag) {
 197                         if (cached_results[i].rl) {
 198                                 *rl = cached_results[i].rl;
 199                                 return 1;
 200                         }
 201                         return 0;
 202                 }
 203         }
 204 






 205         db_info.type = type;
 206 
 207         run_sql(get_vals, &db_info,
 208                 "select value from mtag_data where tag = %lld and offset = %d and type = %d;",
 209                 tag, offset, DATA_VALUE);
 210         if (!db_info.rl || is_whole_rl(db_info.rl)) {
 211                 db_info.rl = NULL;
 212                 ret = 0;
 213                 goto update_cache;
 214         }
 215 
 216         *rl = db_info.rl;
 217         ret = 1;
 218 
 219 update_cache:
 220         cached_results[idx].tag = merged;
 221         cached_results[idx].rl = db_info.rl;
 222         idx = (idx + 1) % ARRAY_SIZE(cached_results);
 223 
 224         return ret;
 225 }
 226 
 227 static void clear_cache(struct symbol *sym)
 228 {
 229         memset(cached_results, 0, sizeof(cached_results));
 230 }
 231 
 232 int get_mtag_rl(struct expression *expr, struct range_list **rl)
 233 {
 234         struct symbol *type;
 235         mtag_t tag;
 236         int offset;
 237 
 238         if (!expr_to_mtag_offset(expr, &tag, &offset))
 239                 return 0;
 240         if (offset >= MTAG_OFFSET_MASK)
 241                 return 0;
 242 
 243         type = get_type(expr);
 244         if (!type)
 245                 return 0;
 246 
 247         return get_rl_from_mtag_offset(tag, offset, type, rl);
 248 }
 249 
 250 void register_mtag_data(int id)
 251 {
 252         my_id = id;
 253 
 254         add_hook(&clear_cache, FUNC_DEF_HOOK);
 255 
 256 //      if (!option_info)
 257 //              return;
 258         add_hook(&match_global_assign, GLOBAL_ASSIGNMENT_HOOK);
 259         add_hook(&match_end_file, END_FILE_HOOK);
 260 }
 261