Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_mtag.c
+++ new/usr/src/tools/smatch/src/smatch_mtag.c
1 1 /*
2 2 * Copyright (C) 2017 Oracle. All rights reserved.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 /*
19 19 * One problem that I have is that it's really hard to track how pointers are
20 20 * passed around. For example, it would be nice to know that the probe() and
21 21 * remove() functions get the same pci_dev pointer. It would be good to know
22 22 * what pointers we're passing to the open() and close() functions. But that
23 23 * information gets lost in a call tree full of function pointer calls.
24 24 *
25 25 * I think the first step is to start naming specific pointers. So when a
26 26 * pointer is allocated, then it gets a tag. So calls to kmalloc() generate a
27 27 * tag. But we might not use that, because there might be a better name like
28 28 * framebuffer_alloc(). The framebuffer_alloc() is interesting because there is
29 29 * one per driver and it's passed around to all the file operations.
30 30 *
31 31 * Perhaps we could make a list of functions like framebuffer_alloc() which take
32 32 * a size and say that those are the interesting alloc functions.
33 33 *
34 34 * Another place where we would maybe name the pointer is when they are passed
35 35 * to the probe(). Because that's an important pointer, since there is one
36 36 * per driver (sort of).
37 37 *
38 38 * My vision is that you could take a pointer and trace it back to a global. So
39 39 * I'm going to track that pointer_tag - 28 bytes takes you to another pointer
40 40 * tag. You could follow that one back and so on. Also when we pass a pointer
41 41 * to a function that would be recorded as sort of a link or path or something.
42 42 *
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
43 43 */
44 44
45 45 #include "smatch.h"
46 46 #include "smatch_slist.h"
47 47 #include "smatch_extra.h"
48 48
49 49 #include <openssl/md5.h>
50 50
51 51 static int my_id;
52 52
53 -static struct smatch_state *alloc_tag_state(mtag_t tag)
54 -{
55 - struct smatch_state *state;
56 - char buf[64];
57 -
58 - state = __alloc_smatch_state(0);
59 - snprintf(buf, sizeof(buf), "%lld", tag);
60 - state->name = alloc_sname(buf);
61 - state->data = malloc(sizeof(mtag_t));
62 - *(mtag_t *)state->data = tag;
63 -
64 - return state;
65 -}
66 -
67 53 static mtag_t str_to_tag(const char *str)
68 54 {
69 55 unsigned char c[MD5_DIGEST_LENGTH];
70 56 unsigned long long *tag = (unsigned long long *)&c;
71 57 MD5_CTX mdContext;
72 58 int len;
73 59
74 60 len = strlen(str);
75 61 MD5_Init(&mdContext);
76 62 MD5_Update(&mdContext, str, len);
77 63 MD5_Final(c, &mdContext);
78 64
79 65 *tag &= ~MTAG_ALIAS_BIT;
80 66 *tag &= ~MTAG_OFFSET_MASK;
81 67
82 68 return *tag;
83 69 }
84 70
85 -static void alloc_assign(const char *fn, struct expression *expr, void *unused)
71 +const struct {
72 + const char *name;
73 + int size_arg;
74 +} allocator_info[] = {
75 + { "kmalloc", 0 },
76 + { "kzalloc", 0 },
77 + { "devm_kmalloc", 1},
78 + { "devm_kzalloc", 1},
79 +};
80 +
81 +static bool is_mtag_call(struct expression *expr)
86 82 {
83 + struct expression *arg;
84 + int i;
85 + sval_t sval;
86 +
87 + if (expr->type != EXPR_CALL ||
88 + expr->fn->type != EXPR_SYMBOL ||
89 + !expr->fn->symbol)
90 + return false;
91 +
92 + for (i = 0; i < ARRAY_SIZE(allocator_info); i++) {
93 + if (strcmp(expr->fn->symbol->ident->name, allocator_info[i].name) == 0)
94 + break;
95 + }
96 + if (i == ARRAY_SIZE(allocator_info))
97 + return false;
98 +
99 + arg = get_argument_from_call_expr(expr->args, allocator_info[i].size_arg);
100 + if (!get_implied_value(arg, &sval))
101 + return false;
102 +
103 + return true;
104 +}
105 +
106 +struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_state *state)
107 +{
87 108 struct expression *left, *right;
88 109 char *left_name, *right_name;
89 110 struct symbol *left_sym;
111 + struct range_list *rl;
90 112 char buf[256];
91 113 mtag_t tag;
114 + sval_t tag_sval;
92 115
116 + if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=')
117 + return state;
93 118
94 - // FIXME: This should only happen when the size is not a paramter of
95 - // the caller
96 - return;
119 + if (!estate_rl(state) || strcmp(state->name, "0,4096-ptr_max") != 0)
120 + return state;
97 121
98 - if (expr->type != EXPR_ASSIGNMENT || expr->op != '=')
99 - return;
100 122 left = strip_expr(expr->left);
101 123 right = strip_expr(expr->right);
102 - if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
103 - return;
104 124
125 + if (!is_mtag_call(right))
126 + return state;
127 +
105 128 left_name = expr_to_str_sym(left, &left_sym);
129 + if (!left_name || !left_sym)
130 + return state;
106 131 right_name = expr_to_str(right);
107 132
108 133 snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(),
109 134 left_name, right_name);
110 135 tag = str_to_tag(buf);
136 + tag_sval.type = estate_type(state);
137 + tag_sval.uvalue = tag;
111 138
112 - sql_insert_mtag_about(tag, left_name, right_name);
139 + rl = rl_filter(estate_rl(state), valid_ptr_rl);
140 + rl = clone_rl(rl);
141 + add_range(&rl, tag_sval, tag_sval);
113 142
114 - if (left_name && left_sym)
115 - set_state(my_id, left_name, left_sym, alloc_tag_state(tag));
143 + sql_insert_mtag_about(tag, left_name, buf);
116 144
117 145 free_string(left_name);
118 146 free_string(right_name);
147 +
148 + return alloc_estate_rl(rl);
119 149 }
120 150
121 151 int get_string_mtag(struct expression *expr, mtag_t *tag)
122 152 {
123 153 mtag_t xor;
124 154
125 155 if (expr->type != EXPR_STRING || !expr->string)
126 156 return 0;
127 157
128 158 /* I was worried about collisions so I added a xor */
129 159 xor = str_to_tag("__smatch string");
130 160 *tag = str_to_tag(expr->string->data);
131 161 *tag = *tag ^ xor;
132 162
133 163 return 1;
134 164 }
135 165
136 166 int get_toplevel_mtag(struct symbol *sym, mtag_t *tag)
137 167 {
138 168 char buf[256];
139 169
140 170 if (!sym)
141 171 return 0;
142 172
143 173 if (!sym->ident ||
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
144 174 !(sym->ctype.modifiers & MOD_TOPLEVEL))
145 175 return 0;
146 176
147 177 snprintf(buf, sizeof(buf), "%s %s",
148 178 (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern",
149 179 sym->ident->name);
150 180 *tag = str_to_tag(buf);
151 181 return 1;
152 182 }
153 183
154 -int get_deref_mtag(struct expression *expr, mtag_t *tag)
184 +bool get_symbol_mtag(struct symbol *sym, mtag_t *tag)
155 185 {
156 - mtag_t container_tag, member_tag;
157 - int offset;
186 + char buf[256];
158 187
159 - /*
160 - * I'm not totally sure what I'm doing...
161 - *
162 - * This is supposed to get something like "global_var->ptr", but I don't
163 - * feel like it's complete at all.
164 - *
165 - */
188 + if (!sym || !sym->ident)
189 + return false;
166 190
167 - if (!get_mtag(expr->unop, &container_tag))
168 - return 0;
191 + if (get_toplevel_mtag(sym, tag))
192 + return true;
169 193
170 - offset = get_member_offset_from_deref(expr);
171 - if (offset < 0)
172 - return 0;
194 + if (get_param_num_from_sym(sym) >= 0)
195 + return false;
173 196
174 - if (!mtag_map_select_tag(container_tag, -offset, &member_tag))
175 - return 0;
176 -
177 - *tag = member_tag;
178 - return 1;
197 + snprintf(buf, sizeof(buf), "%s %s %s",
198 + get_filename(), get_function(), sym->ident->name);
199 + *tag = str_to_tag(buf);
200 + return true;
179 201 }
180 202
181 203 static void global_variable(struct symbol *sym)
182 204 {
183 205 mtag_t tag;
184 206
185 207 if (!get_toplevel_mtag(sym, &tag))
186 208 return;
187 209
188 210 sql_insert_mtag_about(tag,
189 211 sym->ident->name,
190 212 (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern");
191 213 }
192 214
193 -static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math)
194 -{
195 - struct expression *call;
196 - struct range_list *rl;
197 -
198 - if (expr->type != EXPR_ASSIGNMENT)
199 - return;
200 - call = strip_expr(expr->right);
201 -
202 - if (!parse_call_math_rl(call, math, &rl))
203 - return;
204 -// rl = cast_rl(&int_ctype, rl);
205 -// set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
206 -}
207 -
208 -static void db_returns_memory_tag(struct expression *expr, int param, char *key, char *value)
209 -{
210 - struct expression *call, *arg;
211 - mtag_t tag, alias;
212 - char *name;
213 - struct symbol *sym;
214 -
215 - call = strip_expr(expr);
216 - while (call->type == EXPR_ASSIGNMENT)
217 - call = strip_expr(call->right);
218 - if (call->type != EXPR_CALL)
219 - return;
220 -
221 - tag = strtoul(value, NULL, 10);
222 -
223 - if (!create_mtag_alias(tag, call, &alias))
224 - return;
225 -
226 - arg = get_argument_from_call_expr(call->args, param);
227 - if (!arg)
228 - return;
229 -
230 - name = get_variable_from_key(arg, key, &sym);
231 - if (!name || !sym)
232 - goto free;
233 -
234 - set_state(my_id, name, sym, alloc_tag_state(alias));
235 -free:
236 - free_string(name);
237 -}
238 -
239 -static void match_call_info(struct expression *expr)
240 -{
241 - struct smatch_state *state;
242 - struct expression *arg;
243 - int i = -1;
244 -
245 - FOR_EACH_PTR(expr->args, arg) {
246 - i++;
247 - state = get_state_expr(my_id, arg);
248 - if (!state || !state->data)
249 - continue;
250 - sql_insert_caller_info(expr, MEMORY_TAG, i, "$", state->name);
251 - } END_FOR_EACH_PTR(arg);
252 -}
253 -
254 -static void save_caller_info(const char *name, struct symbol *sym, char *key, char *value)
255 -{
256 - struct smatch_state *state;
257 - char fullname[256];
258 - mtag_t tag;
259 -
260 - if (strncmp(key, "$", 1) != 0)
261 - return;
262 -
263 - tag = atoll(value);
264 - snprintf(fullname, 256, "%s%s", name, key + 1);
265 - state = alloc_tag_state(tag);
266 - set_state(my_id, fullname, sym, state);
267 -}
268 -
269 215 static int get_array_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
270 216 {
271 217 struct expression *array, *offset_expr;
272 218 struct symbol *type;
273 219 sval_t sval;
220 + int start_offset;
274 221
275 222 if (!is_array(expr))
276 223 return 0;
277 224
278 225 array = get_array_base(expr);
279 226 if (!array)
280 227 return 0;
281 228 type = get_type(array);
282 229 if (!type || type->type != SYM_ARRAY)
283 230 return 0;
284 231 type = get_real_base_type(type);
285 232 if (!type_bytes(type))
286 233 return 0;
287 234
288 - if (!get_mtag(array, tag))
235 + if (!expr_to_mtag_offset(array, tag, &start_offset))
289 236 return 0;
290 237
291 238 offset_expr = get_array_offset(expr);
292 239 if (!get_value(offset_expr, &sval))
293 240 return 0;
294 - *offset = sval.value * type_bytes(type);
241 + *offset = start_offset + sval.value * type_bytes(type);
295 242
296 243 return 1;
297 244 }
298 245
299 -static int get_implied_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
246 +struct range_list *swap_mtag_seed(struct expression *expr, struct range_list *rl)
300 247 {
301 - struct smatch_state *state;
302 - struct symbol *type;
248 + char buf[256];
249 + char *name;
303 250 sval_t sval;
251 + mtag_t tag;
304 252
305 - type = get_type(expr);
306 - if (!type_is_ptr(type))
307 - return 0;
308 - state = get_extra_state(expr);
309 - if (!state || !estate_get_single_value(state, &sval) || sval.value == 0)
310 - return 0;
253 + if (!rl_to_sval(rl, &sval))
254 + return rl;
255 + if (sval.type->type != SYM_PTR || sval.uvalue != MTAG_SEED)
256 + return rl;
311 257
312 - *tag = sval.uvalue & ~MTAG_OFFSET_MASK;
313 - *offset = sval.uvalue & MTAG_OFFSET_MASK;
314 - return 1;
258 + name = expr_to_str(expr);
259 + snprintf(buf, sizeof(buf), "%s %s %s", get_filename(), get_function(), name);
260 + free_string(name);
261 + tag = str_to_tag(buf);
262 + sval.value = tag;
263 + return alloc_rl(sval, sval);
315 264 }
316 265
317 -static int get_mtag_cnt;
318 -int get_mtag(struct expression *expr, mtag_t *tag)
319 -{
320 - struct smatch_state *state;
321 - int ret = 0;
322 -
323 - expr = strip_expr(expr);
324 - if (!expr)
325 - return 0;
326 -
327 - if (get_mtag_cnt > 0)
328 - return 0;
329 -
330 - get_mtag_cnt++;
331 -
332 - switch (expr->type) {
333 - case EXPR_STRING:
334 - if (get_string_mtag(expr, tag)) {
335 - ret = 1;
336 - goto dec_cnt;
337 - }
338 - break;
339 - case EXPR_SYMBOL:
340 - if (get_toplevel_mtag(expr->symbol, tag)) {
341 - ret = 1;
342 - goto dec_cnt;
343 - }
344 - break;
345 - case EXPR_DEREF:
346 - if (get_deref_mtag(expr, tag)) {
347 - ret = 1;
348 - goto dec_cnt;
349 - }
350 - break;
351 - }
352 -
353 - state = get_state_expr(my_id, expr);
354 - if (!state)
355 - goto dec_cnt;
356 - if (state->data) {
357 - *tag = *(mtag_t *)state->data;
358 - ret = 1;
359 - goto dec_cnt;
360 - }
361 -
362 -dec_cnt:
363 - get_mtag_cnt--;
364 - return ret;
365 -}
366 -
367 -int get_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
368 -{
369 - int val;
370 -
371 - if (!expr)
372 - return 0;
373 - if (expr->type == EXPR_PREOP && expr->op == '*')
374 - return get_mtag_offset(expr->unop, tag, offset);
375 - if (get_implied_mtag_offset(expr, tag, offset))
376 - return 1;
377 - if (!get_mtag(expr, tag))
378 - return 0;
379 - expr = strip_expr(expr);
380 - if (expr->type == EXPR_SYMBOL) {
381 - *offset = 0;
382 - return 1;
383 - }
384 - val = get_member_offset_from_deref(expr);
385 - if (val < 0)
386 - return 0;
387 - *offset = val;
388 - return 1;
389 -}
390 -
391 266 int create_mtag_alias(mtag_t tag, struct expression *expr, mtag_t *new)
392 267 {
393 268 char buf[256];
394 269 int lines_from_start;
395 270 char *str;
396 271
397 272 /*
398 273 * We need the alias to be unique. It's not totally required that it
399 274 * be the same from one DB build to then next, but it makes debugging
400 275 * a bit simpler.
401 276 *
402 277 */
403 278
404 279 if (!cur_func_sym)
405 280 return 0;
406 281
407 282 lines_from_start = expr->pos.line - cur_func_sym->pos.line;
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
408 283 str = expr_to_str(expr);
409 284 snprintf(buf, sizeof(buf), "%lld %d %s", tag, lines_from_start, str);
410 285 free_string(str);
411 286
412 287 *new = str_to_tag(buf);
413 288 sql_insert_mtag_alias(tag, *new);
414 289
415 290 return 1;
416 291 }
417 292
293 +static int get_implied_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
294 +{
295 + struct smatch_state *state;
296 + struct symbol *type;
297 + sval_t sval;
298 +
299 + type = get_type(expr);
300 + if (!type_is_ptr(type))
301 + return 0;
302 + state = get_extra_state(expr);
303 + if (!state || !estate_get_single_value(state, &sval) || sval.value == 0)
304 + return 0;
305 +
306 + *tag = sval.uvalue & ~MTAG_OFFSET_MASK;
307 + *offset = sval.uvalue & MTAG_OFFSET_MASK;
308 + return 1;
309 +}
310 +
311 +/*
312 + * The point of this function is to give you the mtag and the offset so
313 + * you can look up the data in the DB. It takes an expression.
314 + *
315 + * So say you give it "foo->bar". Then it would give you the offset of "bar"
316 + * and the implied value of "foo". Or if you lookup "*foo" then the offset is
317 + * zero and we look up the implied value of "foo. But if the expression is
318 + * foo, then if "foo" is a global variable, then we get the mtag and the offset
319 + * is zero. If "foo" is a local variable, then there is nothing to look up in
320 + * the mtag_data table because that's handled by smatch_extra.c to this returns
321 + * false.
322 + *
323 + */
418 324 int expr_to_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
419 325 {
326 + *tag = 0;
420 327 *offset = 0;
421 328
329 + if (bits_in_pointer != 64)
330 + return 0;
331 +
422 332 expr = strip_expr(expr);
423 333 if (!expr)
424 334 return 0;
425 335
426 336 if (is_array(expr))
427 337 return get_array_mtag_offset(expr, tag, offset);
428 338
429 - if (expr->type == EXPR_DEREF) {
430 - *offset = get_member_offset_from_deref(expr);
431 - if (*offset < 0)
432 - return 0;
433 - return get_mtag(expr->deref, tag);
434 - }
339 + if (expr->type == EXPR_PREOP && expr->op == '*') {
340 + expr = strip_expr(expr->unop);
341 + return get_implied_mtag_offset(expr, tag, offset);
342 + } else if (expr->type == EXPR_DEREF) {
343 + int tmp, tmp_offset = 0;
435 344
436 - if (get_implied_mtag_offset(expr, tag, offset))
437 - return 1;
345 + while (expr->type == EXPR_DEREF) {
346 + tmp = get_member_offset_from_deref(expr);
347 + if (tmp < 0)
348 + return 0;
349 + tmp_offset += tmp;
350 + expr = expr->deref;
351 + }
352 + *offset = tmp_offset;
353 + if (expr->type == EXPR_PREOP && expr->op == '*') {
354 + expr = strip_expr(expr->unop);
438 355
439 - return get_mtag(expr, tag);
356 + if (get_implied_mtag_offset(expr, tag, &tmp_offset)) {
357 + // FIXME: look it up recursively?
358 + if (tmp_offset)
359 + return 0;
360 + return 1;
361 + }
362 + return 0;
363 + } else if (expr->type == EXPR_SYMBOL) {
364 + return get_symbol_mtag(expr->symbol, tag);
365 + }
366 + return 0;
367 + } else if (expr->type == EXPR_SYMBOL) {
368 + return get_symbol_mtag(expr->symbol, tag);
369 + }
370 + return 0;
440 371 }
441 372
373 +/*
374 + * This function takes an address and returns an sval. Let's take some
375 + * example things you might pass to it:
376 + * foo->bar:
377 + * If we were only called from smatch_math, we wouldn't need to bother with
378 + * this because it's already been looked up in smatch_extra.c but this is
379 + * also called from other places so we have to check smatch_extra.c.
380 + * &foo
381 + * If "foo" is global return the mtag for "foo".
382 + * &foo.bar
383 + * If "foo" is global return the mtag for "foo" + the offset of ".bar".
384 + * It also handles string literals.
385 + *
386 + */
442 387 int get_mtag_sval(struct expression *expr, sval_t *sval)
443 388 {
444 389 struct symbol *type;
445 390 mtag_t tag;
446 391 int offset = 0;
447 392
448 393 if (bits_in_pointer != 64)
449 394 return 0;
450 395
451 396 expr = strip_expr(expr);
452 397
453 398 type = get_type(expr);
454 399 if (!type_is_ptr(type))
455 400 return 0;
456 401 /*
457 - * There are only three options:
402 + * There are several options:
458 403 *
459 - * 1) An array address:
460 - * p = array;
461 - * 2) An address like so:
462 - * p = &my_struct->member;
463 - * 3) A pointer:
464 - * p = pointer;
404 + * If the expr is a string literal, that's an address/mtag.
405 + * SYM_ARRAY and SYM_FN are mtags. There are "&foo" type addresses.
406 + * And there are saved pointers "p = &foo;"
465 407 *
466 408 */
467 409
468 410 if (expr->type == EXPR_STRING && get_string_mtag(expr, &tag))
469 411 goto found;
470 412
471 - if (type->type == SYM_ARRAY && get_toplevel_mtag(expr->symbol, &tag))
413 + if (expr->type == EXPR_SYMBOL &&
414 + (type->type == SYM_ARRAY || type->type == SYM_FN) &&
415 + get_toplevel_mtag(expr->symbol, &tag))
472 416 goto found;
473 417
418 + if (expr->type == EXPR_PREOP && expr->op == '&') {
419 + expr = strip_expr(expr->unop);
420 + if (expr_to_mtag_offset(expr, &tag, &offset))
421 + goto found;
422 + return 0;
423 + }
424 +
474 425 if (get_implied_mtag_offset(expr, &tag, &offset))
475 426 goto found;
476 427
477 - if (expr->type != EXPR_PREOP || expr->op != '&')
428 + return 0;
429 +found:
430 + if (offset >= MTAG_OFFSET_MASK)
478 431 return 0;
479 - expr = strip_expr(expr->unop);
480 432
481 - if (!expr_to_mtag_offset(expr, &tag, &offset))
482 - return 0;
483 - if (offset > MTAG_OFFSET_MASK)
484 - offset = MTAG_OFFSET_MASK;
485 -
486 -found:
487 433 sval->type = type;
488 434 sval->uvalue = tag | offset;
489 435
490 436 return 1;
491 437 }
492 438
493 -static struct expression *remove_dereference(struct expression *expr)
494 -{
495 - expr = strip_expr(expr);
496 -
497 - if (expr->type == EXPR_PREOP && expr->op == '*')
498 - return strip_expr(expr->unop);
499 - return preop_expression(expr, '&');
500 -}
501 -
502 -int get_mtag_addr_sval(struct expression *expr, sval_t *sval)
503 -{
504 - return get_mtag_sval(remove_dereference(expr), sval);
505 -}
506 -
507 -static void print_stored_to_mtag(int return_id, char *return_ranges, struct expression *expr)
508 -{
509 - struct sm_state *sm;
510 - char buf[256];
511 - const char *param_name;
512 - int param;
513 -
514 - FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
515 - if (!sm->state->data)
516 - continue;
517 -
518 - param = get_param_num_from_sym(sm->sym);
519 - if (param < 0)
520 - continue;
521 - param_name = get_param_name(sm);
522 - if (!param_name)
523 - continue;
524 - if (strcmp(param_name, "$") == 0)
525 - continue;
526 -
527 - snprintf(buf, sizeof(buf), "%lld", *(mtag_t *)sm->state->data);
528 - sql_insert_return_states(return_id, return_ranges, MEMORY_TAG, param, param_name, buf);
529 - } END_FOR_EACH_SM(sm);
530 -}
531 -
532 439 void register_mtag(int id)
533 440 {
534 441 my_id = id;
535 442
536 443
537 444 /*
538 445 * The mtag stuff only works on 64 systems because we store the
539 446 * information in the pointer itself.
540 447 * bit 63 : set for alias mtags
541 448 * bit 62-12: mtag hash
542 449 * bit 11-0 : offset
543 450 *
544 451 */
545 - if (bits_in_pointer != 64)
546 - return;
547 452
548 453 add_hook(&global_variable, BASE_HOOK);
549 -
550 - add_function_assign_hook("kmalloc", &alloc_assign, NULL);
551 - add_function_assign_hook("kzalloc", &alloc_assign, NULL);
552 -
553 - select_return_states_hook(BUF_SIZE, &db_returns_buf_size);
554 -
555 - add_hook(&match_call_info, FUNCTION_CALL_HOOK);
556 - select_caller_info_hook(save_caller_info, MEMORY_TAG);
557 - add_split_return_callback(&print_stored_to_mtag);
558 - select_return_states_hook(MEMORY_TAG, db_returns_memory_tag);
559 454 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX