97
98 while (top_op_precedence() && op_precedence(c) <= top_op_precedence()) {
99 op = pop_op();
100 right = pop_rl(&rl_stack);
101 left = pop_rl(&rl_stack);
102 res = rl_binop(left, op, right);
103 if (!res)
104 res = alloc_whole_rl(&llong_ctype);
105 push_rl(&rl_stack, res);
106 }
107 }
108
109 static void rl_discard_stacks(void)
110 {
111 while (op_list)
112 pop_op();
113 while (rl_stack)
114 pop_rl(&rl_stack);
115 }
116
117 static int read_rl_from_var(struct expression *call, char *p, char **end, struct range_list **rl)
118 {
119 struct expression *arg;
120 struct smatch_state *state;
121 long param;
122 char *name;
123 struct symbol *sym;
124 char buf[256];
125 int star;
126
127 p++;
128 param = strtol(p, &p, 10);
129
130 arg = get_argument_from_call_expr(call->args, param);
131 if (!arg)
132 return 0;
133
134 if (*p != '-' && *p != '.') {
135 get_absolute_rl(arg, rl);
136 *end = p;
137 return 1;
138 }
139
140 *end = strchr(p, ' ');
141
142 if (arg->type == EXPR_PREOP && arg->op == '&') {
143 arg = strip_expr(arg->unop);
144 star = 0;
145 p++;
146 } else {
147 star = 1;
148 p += 2;
149 }
150
151 name = expr_to_var_sym(arg, &sym);
152 if (!name)
153 return 0;
154 snprintf(buf, sizeof(buf), "%s%s", name, star ? "->" : ".");
155 free_string(name);
156
157 if (*end - p + strlen(buf) >= sizeof(buf))
158 return 0;
159 strncat(buf, p, *end - p);
160
161 state = get_state(SMATCH_EXTRA, buf, sym);
162 if (!state)
163 return 0;
164 *rl = estate_rl(state);
165 return 1;
166 }
167
168 static int read_var_num(struct expression *call, char *p, char **end, struct range_list **rl)
169 {
170 sval_t sval;
171
172 while (*p == ' ')
173 p++;
174
175 if (*p == '$')
176 return read_rl_from_var(call, p, end, rl);
177
178 sval.type = &llong_ctype;
179 sval.value = strtoll(p, end, 10);
180 if (*end == p)
181 return 0;
182 *rl = alloc_rl(sval, sval);
183 return 1;
184 }
185
186 static char *read_op(char *p)
187 {
188 while (*p == ' ')
189 p++;
190
191 switch (*p) {
192 case '+':
193 case '-':
194 case '*':
195 case '/':
196 return p;
197 default:
198 return NULL;
199 }
200 }
201
202 int parse_call_math_rl(struct expression *call, char *math, struct range_list **rl)
203 {
204 struct range_list *tmp;
205 char *c;
206
207 /* try to implement shunting yard algorithm. */
208
209 c = (char *)math;
210 while (1) {
211 if (option_debug)
212 sm_msg("parsing %s", c);
213
214 /* read a number and push it onto the number stack */
215 if (!read_var_num(call, c, &c, &tmp))
216 goto fail;
217 push_rl(&rl_stack, tmp);
218
219 if (option_debug)
220 sm_msg("val = %s remaining = %s", show_rl(tmp), c);
221
222 if (!*c)
223 break;
224 if (*c == ']' && *(c + 1) == '\0')
225 break;
226
227 c = read_op(c);
228 if (!c)
229 goto fail;
327 char *name;
328 struct symbol *sym;
329
330 name = expr_to_var_sym(expr, &sym);
331 if (param_was_set_var_sym(name, sym))
332 return 0;
333 return format_name_sym_helper(buf, remaining, name, sym);
334 }
335
336 static int format_call_to_param_mapping(char *buf, int remaining, struct expression *expr)
337 {
338 char *name;
339 struct symbol *sym;
340
341 name = map_call_to_param_name_sym(expr, &sym);
342 if (param_was_set_var_sym(name, sym))
343 return 0;
344 return format_name_sym_helper(buf, remaining, name, sym);
345 }
346
347 static int format_expr_helper(char *buf, int remaining, struct expression *expr)
348 {
349 sval_t sval;
350 int ret;
351 char *cur;
352
353 if (!expr)
354 return 0;
355
356 cur = buf;
357
358 if (expr->type == EXPR_BINOP) {
359 ret = format_expr_helper(cur, remaining, expr->left);
360 if (ret == 0)
361 return 0;
362 remaining -= ret;
363 if (remaining <= 0)
364 return 0;
365 cur += ret;
366
367 ret = snprintf(cur, remaining, " %s ", show_special(expr->op));
368 remaining -= ret;
369 if (remaining <= 0)
370 return 0;
371 cur += ret;
372
373 ret = format_expr_helper(cur, remaining, expr->right);
374 if (ret == 0)
375 return 0;
376 remaining -= ret;
377 if (remaining <= 0)
378 return 0;
379 cur += ret;
380 return cur - buf;
381 }
382
383 if (get_implied_value(expr, &sval)) {
384 ret = snprintf(cur, remaining, "%s", sval_to_str(sval));
385 remaining -= ret;
386 if (remaining <= 0)
387 return 0;
388 return ret;
389 }
390
391 if (expr->type == EXPR_CALL)
392 return format_call_to_param_mapping(cur, remaining, expr);
393
394 return format_variable_helper(cur, remaining, expr);
395 }
396
397 static char *format_expr(struct expression *expr)
398 {
399 char buf[256] = "";
400 int ret;
401
402 ret = format_expr_helper(buf, sizeof(buf), expr);
403 if (ret == 0)
418 expr = tmp;
419 if (param_was_set(expr))
420 return NULL;
421
422 if (get_implied_value(expr, &dummy))
423 return NULL;
424
425 ret = format_expr_helper(buf, sizeof(buf), expr);
426 if (ret == 0)
427 return NULL;
428
429 return alloc_sname(buf);
430 }
431
432 char *get_value_in_terms_of_parameter_math_var_sym(const char *name, struct symbol *sym)
433 {
434 struct expression *tmp, *expr;
435 char buf[256] = "";
436 int ret;
437 int cnt = 0;
438
439 expr = get_assigned_expr_name_sym(name, sym);
440 if (!expr)
441 return NULL;
442 while ((tmp = get_assigned_expr(expr))) {
443 expr = strip_expr(tmp);
444 if (++cnt > 3)
445 break;
446 }
447
448 ret = format_expr_helper(buf, sizeof(buf), expr);
449 if (ret == 0)
450 return NULL;
451
452 return alloc_sname(buf);
453
454 }
455
456 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
457 {
458 int size_arg = PTR_INT(_size_arg);
459 struct expression *right;
460 struct expression *size_expr;
461 char *sname;
462
463 right = strip_expr(expr->right);
464 size_expr = get_argument_from_call_expr(right->args, size_arg);
465
466 sname = format_expr(size_expr);
467 if (!sname)
476 long param;
477 struct expression *arg;
478 char *p;
479 char *out;
480 int ret;
481
482 if (format[0] == '$' && format[2] == '\0') {
483 param = strtol(format + 1, NULL, 10);
484 arg = get_argument_from_call_expr(call->args, param);
485 if (!arg)
486 return NULL;
487 return format_expr(arg);
488 }
489
490 buf[0] = '\0';
491 p = format;
492 out = buf;
493 while (*p) {
494 if (*p == '$') {
495 p++;
496 param = strtol(p, &p, 10);
497 arg = get_argument_from_call_expr(call->args, param);
498 if (!arg)
499 return NULL;
500 param = get_arg_number(arg);
501 if (param >= 0) {
502 ret = snprintf(out, buf + sizeof(buf) - out, "$%ld", param);
503 out += ret;
504 if (out >= buf + sizeof(buf))
505 return NULL;
506 } else if (get_implied_value(arg, &sval)) {
507 ret = snprintf(out, buf + sizeof(buf) - out, "%s", sval_to_str(sval));
508 out += ret;
509 if (out >= buf + sizeof(buf))
510 return NULL;
511 } else {
512 return NULL;
513 }
514 }
515 *out = *p;
516 p++;
626 name = expr_to_var_sym(expr, &sym);
627 if (!name || !sym)
628 goto free;
629
630 state = get_state(my_id, name, sym);
631 if (!state || !state->data)
632 goto free;
633
634 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
635 state->name);
636 free:
637 free_string(name);
638 }
639
640 void register_parse_call_math(int id)
641 {
642 int i;
643
644 my_id = id;
645
646 for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
647 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
648 INT_PTR(alloc_functions[i].param));
649 add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
650 add_split_return_callback(print_returned_allocations);
651 }
652
|
97
98 while (top_op_precedence() && op_precedence(c) <= top_op_precedence()) {
99 op = pop_op();
100 right = pop_rl(&rl_stack);
101 left = pop_rl(&rl_stack);
102 res = rl_binop(left, op, right);
103 if (!res)
104 res = alloc_whole_rl(&llong_ctype);
105 push_rl(&rl_stack, res);
106 }
107 }
108
109 static void rl_discard_stacks(void)
110 {
111 while (op_list)
112 pop_op();
113 while (rl_stack)
114 pop_rl(&rl_stack);
115 }
116
117 static int read_rl_from_var(struct expression *call, const char *p, const char **end, struct range_list **rl)
118 {
119 struct expression *arg;
120 struct smatch_state *state;
121 long param;
122 char *name;
123 struct symbol *sym;
124 char buf[256];
125 int star;
126
127 p++;
128 param = strtol(p, (char **)&p, 10);
129
130 arg = get_argument_from_call_expr(call->args, param);
131 if (!arg)
132 return 0;
133
134 if (*p != '-' && *p != '.') {
135 get_absolute_rl(arg, rl);
136 *end = p;
137 return 1;
138 }
139
140 *end = strchr(p, ' ');
141
142 if (arg->type == EXPR_PREOP && arg->op == '&') {
143 arg = strip_expr(arg->unop);
144 star = 0;
145 p++;
146 } else {
147 star = 1;
148 p += 2;
149 }
150
151 name = expr_to_var_sym(arg, &sym);
152 if (!name)
153 return 0;
154 snprintf(buf, sizeof(buf), "%s%s", name, star ? "->" : ".");
155 free_string(name);
156
157 if (*end - p + strlen(buf) >= sizeof(buf))
158 return 0;
159 strncat(buf, p, *end - p);
160
161 state = get_state(SMATCH_EXTRA, buf, sym);
162 if (!state)
163 return 0;
164 *rl = estate_rl(state);
165 return 1;
166 }
167
168 static int read_var_num(struct expression *call, const char *p, const char **end, struct range_list **rl)
169 {
170 sval_t sval;
171
172 while (*p == ' ')
173 p++;
174
175 if (*p == '$')
176 return read_rl_from_var(call, p, end, rl);
177
178 sval.type = &llong_ctype;
179 sval.value = strtoll(p, (char **)end, 10);
180 if (*end == p)
181 return 0;
182 *rl = alloc_rl(sval, sval);
183 return 1;
184 }
185
186 static const char *read_op(const char *p)
187 {
188 while (*p == ' ')
189 p++;
190
191 switch (*p) {
192 case '+':
193 case '-':
194 case '*':
195 case '/':
196 return p;
197 default:
198 return NULL;
199 }
200 }
201
202 int parse_call_math_rl(struct expression *call, const char *math, struct range_list **rl)
203 {
204 struct range_list *tmp;
205 const char *c;
206
207 /* try to implement shunting yard algorithm. */
208
209 c = math;
210 while (1) {
211 if (option_debug)
212 sm_msg("parsing %s", c);
213
214 /* read a number and push it onto the number stack */
215 if (!read_var_num(call, c, &c, &tmp))
216 goto fail;
217 push_rl(&rl_stack, tmp);
218
219 if (option_debug)
220 sm_msg("val = %s remaining = %s", show_rl(tmp), c);
221
222 if (!*c)
223 break;
224 if (*c == ']' && *(c + 1) == '\0')
225 break;
226
227 c = read_op(c);
228 if (!c)
229 goto fail;
327 char *name;
328 struct symbol *sym;
329
330 name = expr_to_var_sym(expr, &sym);
331 if (param_was_set_var_sym(name, sym))
332 return 0;
333 return format_name_sym_helper(buf, remaining, name, sym);
334 }
335
336 static int format_call_to_param_mapping(char *buf, int remaining, struct expression *expr)
337 {
338 char *name;
339 struct symbol *sym;
340
341 name = map_call_to_param_name_sym(expr, &sym);
342 if (param_was_set_var_sym(name, sym))
343 return 0;
344 return format_name_sym_helper(buf, remaining, name, sym);
345 }
346
347 static int is_mtag_sval(sval_t sval)
348 {
349 if (!is_ptr_type(sval.type))
350 return 0;
351 if (sval_cmp(sval, valid_ptr_min_sval) >= 0 &&
352 sval_cmp(sval, valid_ptr_max_sval) <= 0)
353 return 1;
354 return 0;
355 }
356
357 static int format_expr_helper(char *buf, int remaining, struct expression *expr)
358 {
359 sval_t sval;
360 int ret;
361 char *cur;
362
363 if (!expr)
364 return 0;
365
366 cur = buf;
367
368 if (expr->type == EXPR_BINOP) {
369 ret = format_expr_helper(cur, remaining, expr->left);
370 if (ret == 0)
371 return 0;
372 remaining -= ret;
373 if (remaining <= 0)
374 return 0;
375 cur += ret;
376
377 ret = snprintf(cur, remaining, " %s ", show_special(expr->op));
378 remaining -= ret;
379 if (remaining <= 0)
380 return 0;
381 cur += ret;
382
383 ret = format_expr_helper(cur, remaining, expr->right);
384 if (ret == 0)
385 return 0;
386 remaining -= ret;
387 if (remaining <= 0)
388 return 0;
389 cur += ret;
390 return cur - buf;
391 }
392
393 if (!param_was_set(expr) && get_implied_value(expr, &sval) && !is_mtag_sval(sval)) {
394 ret = snprintf(cur, remaining, "%s", sval_to_str(sval));
395 remaining -= ret;
396 if (remaining <= 0)
397 return 0;
398 return ret;
399 }
400
401 if (expr->type == EXPR_CALL)
402 return format_call_to_param_mapping(cur, remaining, expr);
403
404 return format_variable_helper(cur, remaining, expr);
405 }
406
407 static char *format_expr(struct expression *expr)
408 {
409 char buf[256] = "";
410 int ret;
411
412 ret = format_expr_helper(buf, sizeof(buf), expr);
413 if (ret == 0)
428 expr = tmp;
429 if (param_was_set(expr))
430 return NULL;
431
432 if (get_implied_value(expr, &dummy))
433 return NULL;
434
435 ret = format_expr_helper(buf, sizeof(buf), expr);
436 if (ret == 0)
437 return NULL;
438
439 return alloc_sname(buf);
440 }
441
442 char *get_value_in_terms_of_parameter_math_var_sym(const char *name, struct symbol *sym)
443 {
444 struct expression *tmp, *expr;
445 char buf[256] = "";
446 int ret;
447 int cnt = 0;
448 sval_t sval;
449
450 expr = get_assigned_expr_name_sym(name, sym);
451 if (!expr)
452 return NULL;
453 while ((tmp = get_assigned_expr(expr))) {
454 expr = strip_expr(tmp);
455 if (++cnt > 3)
456 break;
457 }
458
459 if (get_implied_value(expr, &sval))
460 return NULL;
461
462 ret = format_expr_helper(buf, sizeof(buf), expr);
463 if (ret == 0)
464 return NULL;
465
466 return alloc_sname(buf);
467
468 }
469
470 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
471 {
472 int size_arg = PTR_INT(_size_arg);
473 struct expression *right;
474 struct expression *size_expr;
475 char *sname;
476
477 right = strip_expr(expr->right);
478 size_expr = get_argument_from_call_expr(right->args, size_arg);
479
480 sname = format_expr(size_expr);
481 if (!sname)
490 long param;
491 struct expression *arg;
492 char *p;
493 char *out;
494 int ret;
495
496 if (format[0] == '$' && format[2] == '\0') {
497 param = strtol(format + 1, NULL, 10);
498 arg = get_argument_from_call_expr(call->args, param);
499 if (!arg)
500 return NULL;
501 return format_expr(arg);
502 }
503
504 buf[0] = '\0';
505 p = format;
506 out = buf;
507 while (*p) {
508 if (*p == '$') {
509 p++;
510 param = strtol(p, (char **)&p, 10);
511 arg = get_argument_from_call_expr(call->args, param);
512 if (!arg)
513 return NULL;
514 param = get_arg_number(arg);
515 if (param >= 0) {
516 ret = snprintf(out, buf + sizeof(buf) - out, "$%ld", param);
517 out += ret;
518 if (out >= buf + sizeof(buf))
519 return NULL;
520 } else if (get_implied_value(arg, &sval)) {
521 ret = snprintf(out, buf + sizeof(buf) - out, "%s", sval_to_str(sval));
522 out += ret;
523 if (out >= buf + sizeof(buf))
524 return NULL;
525 } else {
526 return NULL;
527 }
528 }
529 *out = *p;
530 p++;
640 name = expr_to_var_sym(expr, &sym);
641 if (!name || !sym)
642 goto free;
643
644 state = get_state(my_id, name, sym);
645 if (!state || !state->data)
646 goto free;
647
648 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
649 state->name);
650 free:
651 free_string(name);
652 }
653
654 void register_parse_call_math(int id)
655 {
656 int i;
657
658 my_id = id;
659
660 set_dynamic_states(my_id);
661
662 for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
663 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
664 INT_PTR(alloc_functions[i].param));
665 add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
666 add_split_return_callback(print_returned_allocations);
667 }
668
|