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");
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
|
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 bool is_head_next(struct expression *expr)
85 {
86 struct symbol *type;
87
88 /* Smatch thinks head->next == head is always true. *sad face* */
89
90 if (option_project != PROJ_KERNEL)
91 return false;
92
93 if (expr->type != EXPR_DEREF)
94 return false;
95 if (!expr->member || !expr->member->name ||
96 strcmp(expr->member->name, "next") != 0)
97 return false;
98
99 type = get_type(expr->deref);
100 if (!type)
101 return false;
102 if (type->type == SYM_PTR)
103 type = get_real_base_type(type);
104 if (type->type != SYM_STRUCT)
105 return false;
106 if (!type->ident || !type->ident->name ||
107 strcmp(type->ident->name, "list_head") != 0)
108 return false;
109 return true;
110 }
111
112 mtag_t ignored_mtag;
113 static bool is_ignored_tag(mtag_t tag)
114 {
115 if (tag == ignored_mtag)
116 return true;
117 return false;
118 }
119
120 static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
121 {
122 if (is_ignored_tag(tag))
123 return;
124
125 rl = clone_rl_permanent(rl);
126
127 mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
128 tag, offset, DATA_VALUE);
129 mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",
130 tag, offset, DATA_VALUE, (unsigned long)rl);
131 }
132
133 static bool invalid_type(struct symbol *type)
134 {
135 if (!type)
136 return true;
137 if (type == &void_ctype)
138 return true;
139 if (type->type == SYM_STRUCT ||
140 type->type == SYM_ARRAY ||
141 type->type == SYM_UNION)
142 return true;
143 return false;
144 }
145
146 static bool parent_is_fresh_alloc(struct expression *expr)
147 {
148 struct symbol *sym;
149
150 sym = expr_to_sym(expr);
151 if (!sym || !sym->ident)
152 return false;
153 return is_fresh_alloc_var_sym(sym->ident->name, sym);
154 }
155
156 void update_mtag_data(struct expression *expr, struct smatch_state *state)
157 {
158 struct range_list *orig, *new;
159 struct symbol *type;
160 char *name;
161 mtag_t tag;
162 int offset;
163
164 if (!expr)
165 return;
166 if (is_local_variable(expr))
167 return;
168 if (is_ignored_macro(expr))
169 return;
170 if (is_head_next(expr))
171 return;
172 name = expr_to_var(expr);
173 if (is_kernel_param(name)) {
174 free_string(name);
175 return;
176 }
177 free_string(name);
178
179 if (!expr_to_mtag_offset(expr, &tag, &offset))
180 return;
181
182 type = get_type(expr);
183 if (offset == 0 && invalid_type(type))
184 return;
185
186 if (parent_is_fresh_alloc(expr))
187 orig = NULL;
188 else
189 orig = select_orig(tag, offset);
190 new = rl_union(orig, estate_rl(state));
191 insert_mtag_data(tag, offset, new);
192 }
193
194 static void match_global_assign(struct expression *expr)
195 {
196 struct range_list *rl;
197 mtag_t tag;
198 int offset;
199 char *name;
200
201 if (is_ignored_macro(expr))
202 return;
203 if (is_head_next(expr->left))
204 return;
205 name = expr_to_var(expr->left);
206 if (is_kernel_param(name)) {
207 free_string(name);
208 return;
209 }
210 free_string(name);
211
212 if (!expr_to_mtag_offset(expr->left, &tag, &offset))
213 return;
214
215 get_absolute_rl(expr->right, &rl);
216 insert_mtag_data(tag, offset, rl);
217 }
218
219 static int save_mtag_data(void *_unused, int argc, char **argv, char **azColName)
220 {
221 struct range_list *rl;
222
223 if (argc != 4) {
224 sm_msg("Error saving mtag data");
317 int offset;
318
319 if (is_local_variable(expr))
320 return 0;
321 if (!expr_to_mtag_offset(expr, &tag, &offset))
322 return 0;
323 if (offset >= MTAG_OFFSET_MASK)
324 return 0;
325
326 type = get_type(expr);
327 if (invalid_type(type))
328 return 0;
329
330 return get_rl_from_mtag_offset(tag, offset, type, rl);
331 }
332
333 void register_mtag_data(int id)
334 {
335 my_id = id;
336
337 ignored_mtag = str_to_mtag("extern boot_params");
338 add_hook(&clear_cache, FUNC_DEF_HOOK);
339
340 // if (!option_info)
341 // return;
342 add_hook(&match_global_assign, GLOBAL_ASSIGNMENT_HOOK);
343 add_hook(&match_end_file, END_FILE_HOOK);
344 }
345
|