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");
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 }
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
|
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 bool is_ignored_macro(struct expression *expr)
73 {
74 char *macro;
75
76 macro = get_macro_name(expr->pos);
77 if (!macro)
78 return false;
79 if (strcmp(macro, "EXPORT_SYMBOL") == 0)
80 return true;
81 return false;
82 }
83
84 static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
85 {
86 rl = clone_rl_permanent(rl);
87
88 mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
89 tag, offset, DATA_VALUE);
90 mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",
91 tag, offset, DATA_VALUE, (unsigned long)rl);
92 }
93
94 static bool invalid_type(struct symbol *type)
95 {
96 if (!type)
97 return true;
98 if (type == &void_ctype)
99 return true;
100 if (type->type == SYM_STRUCT ||
101 type->type == SYM_ARRAY ||
102 type->type == SYM_UNION)
103 return true;
104 return false;
105 }
106
107 void update_mtag_data(struct expression *expr, struct smatch_state *state)
108 {
109 struct range_list *orig, *new;
110 struct symbol *type;
111 char *name;
112 mtag_t tag;
113 int offset;
114
115 if (!expr)
116 return;
117 if (is_local_variable(expr))
118 return;
119 if (is_ignored_macro(expr))
120 return;
121 name = expr_to_var(expr);
122 if (is_kernel_param(name)) {
123 free_string(name);
124 return;
125 }
126 free_string(name);
127
128 if (!expr_to_mtag_offset(expr, &tag, &offset))
129 return;
130
131 type = get_type(expr);
132 if (offset == 0 && invalid_type(type))
133 return;
134
135 orig = select_orig(tag, offset);
136 new = rl_union(orig, estate_rl(state));
137 insert_mtag_data(tag, offset, new);
138 }
139
140 static void match_global_assign(struct expression *expr)
141 {
142 struct range_list *rl;
143 mtag_t tag;
144 int offset;
145 char *name;
146
147 if (is_ignored_macro(expr))
148 return;
149 name = expr_to_var(expr->left);
150 if (is_kernel_param(name)) {
151 free_string(name);
152 return;
153 }
154 free_string(name);
155
156 if (!expr_to_mtag_offset(expr->left, &tag, &offset))
157 return;
158
159 get_absolute_rl(expr->right, &rl);
160 insert_mtag_data(tag, offset, rl);
161 }
162
163 static int save_mtag_data(void *_unused, int argc, char **argv, char **azColName)
164 {
165 struct range_list *rl;
166
167 if (argc != 4) {
168 sm_msg("Error saving mtag data");
200 else
201 db_info->rl = tmp;
202
203 return 0;
204 }
205
206 struct db_cache_results {
207 mtag_t tag;
208 struct range_list *rl;
209 };
210 static struct db_cache_results cached_results[8];
211
212 static int get_rl_from_mtag_offset(mtag_t tag, int offset, struct symbol *type, struct range_list **rl)
213 {
214 struct db_info db_info = {};
215 mtag_t merged = tag | offset;
216 static int idx;
217 int ret;
218 int i;
219
220 for (i = 0; i < ARRAY_SIZE(cached_results); i++) {
221 if (merged == cached_results[i].tag) {
222 if (cached_results[i].rl) {
223 *rl = cached_results[i].rl;
224 return 1;
225 }
226 return 0;
227 }
228 }
229
230 db_info.type = type;
231
232 run_sql(get_vals, &db_info,
233 "select value from mtag_data where tag = %lld and offset = %d and type = %d;",
234 tag, offset, DATA_VALUE);
235 if (!db_info.rl || is_whole_rl(db_info.rl)) {
236 db_info.rl = NULL;
237 ret = 0;
238 goto update_cache;
239 }
243
244 update_cache:
245 cached_results[idx].tag = merged;
246 cached_results[idx].rl = db_info.rl;
247 idx = (idx + 1) % ARRAY_SIZE(cached_results);
248
249 return ret;
250 }
251
252 static void clear_cache(struct symbol *sym)
253 {
254 memset(cached_results, 0, sizeof(cached_results));
255 }
256
257 int get_mtag_rl(struct expression *expr, struct range_list **rl)
258 {
259 struct symbol *type;
260 mtag_t tag;
261 int offset;
262
263 if (is_local_variable(expr))
264 return 0;
265 if (!expr_to_mtag_offset(expr, &tag, &offset))
266 return 0;
267 if (offset >= MTAG_OFFSET_MASK)
268 return 0;
269
270 type = get_type(expr);
271 if (invalid_type(type))
272 return 0;
273
274 return get_rl_from_mtag_offset(tag, offset, type, rl);
275 }
276
277 void register_mtag_data(int id)
278 {
279 my_id = id;
280
281 add_hook(&clear_cache, FUNC_DEF_HOOK);
282
283 // if (!option_info)
284 // return;
285 add_hook(&match_global_assign, GLOBAL_ASSIGNMENT_HOOK);
286 add_hook(&match_end_file, END_FILE_HOOK);
287 }
288
|