27
28 int __in_fake_assign;
29 int __in_fake_struct_assign;
30 int in_fake_env;
31 int final_pass;
32 int __inline_call;
33 struct expression *__inline_fn;
34
35 static int __smatch_lineno = 0;
36
37 static char *base_file;
38 static const char *filename;
39 static char *pathname;
40 static char *full_filename;
41 static char *full_base_file;
42 static char *cur_func;
43 static unsigned int loop_count;
44 static int last_goto_statement_handled;
45 int __expr_stmt_count;
46 int __in_function_def;
47 static struct expression_list *switch_expr_stack = NULL;
48 static struct expression_list *post_op_stack = NULL;
49
50 static struct ptr_list *backup;
51
52 struct expression_list *big_expression_stack;
53 struct statement_list *big_statement_stack;
54 struct statement *__prev_stmt;
55 struct statement *__cur_stmt;
56 struct statement *__next_stmt;
57 int __in_pre_condition = 0;
58 int __bail_on_rest_of_function = 0;
59 static struct timeval fn_start_time;
60 static struct timeval outer_fn_start_time;
61 char *get_function(void) { return cur_func; }
62 int get_lineno(void) { return __smatch_lineno; }
63 int inside_loop(void) { return !!loop_count; }
64 int definitely_inside_loop(void) { return !!(loop_count & ~0x08000000); }
65 struct expression *get_switch_expr(void) { return top_expression(switch_expr_stack); }
66 int in_expression_statement(void) { return !!__expr_stmt_count; }
443 break;
444 /* foo = ({frob(); frob(); frob(); 1;}) */
445 if (__handle_expr_statement_assigns(expr))
446 break;
447 /* foo = (3, 4); */
448 if (handle_comma_assigns(expr))
449 break;
450 if (handle_postop_assigns(expr))
451 break;
452 if (handle__builtin_choose_expr_assigns(expr))
453 break;
454
455 __split_expr(expr->right);
456 if (outside_of_function())
457 __pass_to_client(expr, GLOBAL_ASSIGNMENT_HOOK);
458 else
459 __pass_to_client(expr, ASSIGNMENT_HOOK);
460
461 __fake_struct_member_assignments(expr);
462
463 if (expr->op == '=' && right->type == EXPR_CALL)
464 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
465
466 if (get_macro_name(right->pos) &&
467 get_macro_name(expr->pos) != get_macro_name(right->pos))
468 __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
469
470 __pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
471
472 __split_expr(expr->left);
473 break;
474 }
475 case EXPR_DEREF:
476 expr_set_parent_expr(expr->deref, expr);
477
478 __pass_to_client(expr, DEREF_HOOK);
479 __split_expr(expr->deref);
480 break;
481 case EXPR_SLICE:
482 expr_set_parent_expr(expr->base, expr);
510 }
511 if (known_condition_false(expr->conditional)) {
512 __split_expr(expr->cond_false);
513 break;
514 }
515 __pass_to_client(expr, SELECT_HOOK);
516 __split_whole_condition(expr->conditional);
517 __split_expr(expr->cond_true);
518 __push_true_states();
519 __use_false_states();
520 __split_expr(expr->cond_false);
521 __merge_true_states();
522 break;
523 case EXPR_CALL:
524 expr_set_parent_expr(expr->fn, expr);
525
526 if (sym_name_is("__builtin_constant_p", expr->fn))
527 break;
528 if (handle__builtin_choose_expr(expr))
529 break;
530 split_expr_list(expr->args, expr);
531 __split_expr(expr->fn);
532 if (is_inline_func(expr->fn))
533 add_inline_function(expr->fn->symbol);
534 if (inlinable(expr->fn))
535 __inline_call = 1;
536 __process_post_op_stack();
537 __pass_to_client(expr, FUNCTION_CALL_HOOK_BEFORE);
538 __pass_to_client(expr, FUNCTION_CALL_HOOK);
539 __inline_call = 0;
540 if (inlinable(expr->fn)) {
541 parse_inline(expr);
542 }
543 __pass_to_client(expr, CALL_HOOK_AFTER_INLINE);
544 if (is_noreturn_func(expr->fn))
545 nullify_path();
546 handle_builtin_overflow_func(expr);
547 break;
548 case EXPR_INITIALIZER:
549 split_expr_list(expr->expr_list, expr);
550 break;
551 case EXPR_IDENTIFIER:
552 expr_set_parent_expr(expr->ident_expression, expr);
553 __split_expr(expr->ident_expression);
554 break;
555 case EXPR_INDEX:
556 expr_set_parent_expr(expr->idx_expression, expr);
557 __split_expr(expr->idx_expression);
558 break;
559 case EXPR_POS:
560 expr_set_parent_expr(expr->init_expr, expr);
561 __split_expr(expr->init_expr);
562 break;
563 case EXPR_SYMBOL:
564 __pass_to_client(expr, SYM_HOOK);
565 break;
566 case EXPR_STRING:
567 __pass_to_client(expr, STRING_HOOK);
568 break;
569 default:
570 break;
571 };
572 pop_expression(&big_expression_stack);
573 }
574
575 static int is_forever_loop(struct statement *stmt)
576 {
577 struct expression *expr;
578 sval_t sval;
579
580 expr = strip_expr(stmt->iterator_pre_condition);
581 if (!expr)
582 expr = stmt->iterator_post_condition;
583 if (!expr) {
584 /* this is a for(;;) loop... */
585 return 1;
586 }
587
588 if (get_value(expr, &sval) && sval.value != 0)
589 return 1;
590
591 return 0;
683 }
684 loop_count--;
685 }
686
687 /*
688 * Post loops are do {} while();
689 */
690 static void handle_post_loop(struct statement *stmt)
691 {
692 char *loop_name;
693
694 loop_name = get_loop_name(loop_num);
695 loop_num++;
696 loop_count++;
697
698 __push_continues();
699 __push_breaks();
700 __merge_gotos(loop_name, NULL);
701 __split_stmt(stmt->iterator_statement);
702 __merge_continues();
703 if (!is_zero(stmt->iterator_post_condition))
704 __save_gotos(loop_name, NULL);
705
706 if (is_forever_loop(stmt)) {
707 __use_breaks();
708 } else {
709 __split_whole_condition(stmt->iterator_post_condition);
710 __use_false_states();
711 __merge_breaks();
712 }
713 loop_count--;
714 }
715
716 static int empty_statement(struct statement *stmt)
717 {
718 if (!stmt)
719 return 0;
720 if (stmt->type == STMT_EXPRESSION && !stmt->expression)
721 return 1;
722 return 0;
723 }
1597 __pass_to_client(sym, AFTER_FUNC_HOOK);
1598
1599 clear_all_states();
1600
1601 gettimeofday(&stop, NULL);
1602 if (option_time && stop.tv_sec - fn_start_time.tv_sec > 2) {
1603 final_pass++;
1604 sm_msg("func_time: %lu", stop.tv_sec - fn_start_time.tv_sec);
1605 final_pass--;
1606 }
1607 cur_func_sym = NULL;
1608 cur_func = NULL;
1609 free_data_info_allocs();
1610 free_expression_stack(&switch_expr_stack);
1611 __free_ptr_list((struct ptr_list **)&big_statement_stack);
1612 __bail_on_rest_of_function = 0;
1613 }
1614
1615 static void save_flow_state(void)
1616 {
1617 __add_ptr_list(&backup, INT_PTR(loop_num << 2), 0);
1618 __add_ptr_list(&backup, INT_PTR(loop_count << 2), 0);
1619 __add_ptr_list(&backup, INT_PTR(final_pass << 2), 0);
1620
1621 __add_ptr_list(&backup, big_statement_stack, 0);
1622 __add_ptr_list(&backup, big_expression_stack, 0);
1623 __add_ptr_list(&backup, big_condition_stack, 0);
1624 __add_ptr_list(&backup, switch_expr_stack, 0);
1625
1626 __add_ptr_list(&backup, cur_func_sym, 0);
1627
1628 __add_ptr_list(&backup, __prev_stmt, 0);
1629 __add_ptr_list(&backup, __cur_stmt, 0);
1630 __add_ptr_list(&backup, __next_stmt, 0);
1631
1632 }
1633
1634 static void *pop_backup(void)
1635 {
1636 void *ret;
1637
1638 ret = last_ptr_list(backup);
1639 delete_ptr_list_last(&backup);
1640 return ret;
1641 }
1642
1643 static void restore_flow_state(void)
1644 {
1645 __next_stmt = pop_backup();
1646 __cur_stmt = pop_backup();
1647 __prev_stmt = pop_backup();
1648
1649 cur_func_sym = pop_backup();
1650 switch_expr_stack = pop_backup();
1651 big_condition_stack = pop_backup();
|
27
28 int __in_fake_assign;
29 int __in_fake_struct_assign;
30 int in_fake_env;
31 int final_pass;
32 int __inline_call;
33 struct expression *__inline_fn;
34
35 static int __smatch_lineno = 0;
36
37 static char *base_file;
38 static const char *filename;
39 static char *pathname;
40 static char *full_filename;
41 static char *full_base_file;
42 static char *cur_func;
43 static unsigned int loop_count;
44 static int last_goto_statement_handled;
45 int __expr_stmt_count;
46 int __in_function_def;
47 int __in_unmatched_hook;
48 static struct expression_list *switch_expr_stack = NULL;
49 static struct expression_list *post_op_stack = NULL;
50
51 static struct ptr_list *backup;
52
53 struct expression_list *big_expression_stack;
54 struct statement_list *big_statement_stack;
55 struct statement *__prev_stmt;
56 struct statement *__cur_stmt;
57 struct statement *__next_stmt;
58 int __in_pre_condition = 0;
59 int __bail_on_rest_of_function = 0;
60 static struct timeval fn_start_time;
61 static struct timeval outer_fn_start_time;
62 char *get_function(void) { return cur_func; }
63 int get_lineno(void) { return __smatch_lineno; }
64 int inside_loop(void) { return !!loop_count; }
65 int definitely_inside_loop(void) { return !!(loop_count & ~0x08000000); }
66 struct expression *get_switch_expr(void) { return top_expression(switch_expr_stack); }
67 int in_expression_statement(void) { return !!__expr_stmt_count; }
444 break;
445 /* foo = ({frob(); frob(); frob(); 1;}) */
446 if (__handle_expr_statement_assigns(expr))
447 break;
448 /* foo = (3, 4); */
449 if (handle_comma_assigns(expr))
450 break;
451 if (handle_postop_assigns(expr))
452 break;
453 if (handle__builtin_choose_expr_assigns(expr))
454 break;
455
456 __split_expr(expr->right);
457 if (outside_of_function())
458 __pass_to_client(expr, GLOBAL_ASSIGNMENT_HOOK);
459 else
460 __pass_to_client(expr, ASSIGNMENT_HOOK);
461
462 __fake_struct_member_assignments(expr);
463
464 /* Re-examine ->right for inlines. See the commit message */
465 right = strip_expr(expr->right);
466 if (expr->op == '=' && right->type == EXPR_CALL)
467 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
468
469 if (get_macro_name(right->pos) &&
470 get_macro_name(expr->pos) != get_macro_name(right->pos))
471 __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
472
473 __pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
474
475 __split_expr(expr->left);
476 break;
477 }
478 case EXPR_DEREF:
479 expr_set_parent_expr(expr->deref, expr);
480
481 __pass_to_client(expr, DEREF_HOOK);
482 __split_expr(expr->deref);
483 break;
484 case EXPR_SLICE:
485 expr_set_parent_expr(expr->base, expr);
513 }
514 if (known_condition_false(expr->conditional)) {
515 __split_expr(expr->cond_false);
516 break;
517 }
518 __pass_to_client(expr, SELECT_HOOK);
519 __split_whole_condition(expr->conditional);
520 __split_expr(expr->cond_true);
521 __push_true_states();
522 __use_false_states();
523 __split_expr(expr->cond_false);
524 __merge_true_states();
525 break;
526 case EXPR_CALL:
527 expr_set_parent_expr(expr->fn, expr);
528
529 if (sym_name_is("__builtin_constant_p", expr->fn))
530 break;
531 if (handle__builtin_choose_expr(expr))
532 break;
533 __split_expr(expr->fn);
534 split_expr_list(expr->args, expr);
535 if (is_inline_func(expr->fn))
536 add_inline_function(expr->fn->symbol);
537 if (inlinable(expr->fn))
538 __inline_call = 1;
539 __process_post_op_stack();
540 __pass_to_client(expr, FUNCTION_CALL_HOOK_BEFORE);
541 __pass_to_client(expr, FUNCTION_CALL_HOOK);
542 __inline_call = 0;
543 if (inlinable(expr->fn)) {
544 parse_inline(expr);
545 }
546 __pass_to_client(expr, CALL_HOOK_AFTER_INLINE);
547 if (is_noreturn_func(expr->fn))
548 nullify_path();
549 handle_builtin_overflow_func(expr);
550 break;
551 case EXPR_INITIALIZER:
552 split_expr_list(expr->expr_list, expr);
553 break;
554 case EXPR_IDENTIFIER:
555 expr_set_parent_expr(expr->ident_expression, expr);
556 __split_expr(expr->ident_expression);
557 break;
558 case EXPR_INDEX:
559 expr_set_parent_expr(expr->idx_expression, expr);
560 __split_expr(expr->idx_expression);
561 break;
562 case EXPR_POS:
563 expr_set_parent_expr(expr->init_expr, expr);
564 __split_expr(expr->init_expr);
565 break;
566 case EXPR_SYMBOL:
567 __pass_to_client(expr, SYM_HOOK);
568 break;
569 case EXPR_STRING:
570 __pass_to_client(expr, STRING_HOOK);
571 break;
572 default:
573 break;
574 };
575 __pass_to_client(expr, EXPR_HOOK_AFTER);
576 pop_expression(&big_expression_stack);
577 }
578
579 static int is_forever_loop(struct statement *stmt)
580 {
581 struct expression *expr;
582 sval_t sval;
583
584 expr = strip_expr(stmt->iterator_pre_condition);
585 if (!expr)
586 expr = stmt->iterator_post_condition;
587 if (!expr) {
588 /* this is a for(;;) loop... */
589 return 1;
590 }
591
592 if (get_value(expr, &sval) && sval.value != 0)
593 return 1;
594
595 return 0;
687 }
688 loop_count--;
689 }
690
691 /*
692 * Post loops are do {} while();
693 */
694 static void handle_post_loop(struct statement *stmt)
695 {
696 char *loop_name;
697
698 loop_name = get_loop_name(loop_num);
699 loop_num++;
700 loop_count++;
701
702 __push_continues();
703 __push_breaks();
704 __merge_gotos(loop_name, NULL);
705 __split_stmt(stmt->iterator_statement);
706 __merge_continues();
707 if (!expr_is_zero(stmt->iterator_post_condition))
708 __save_gotos(loop_name, NULL);
709
710 if (is_forever_loop(stmt)) {
711 __use_breaks();
712 } else {
713 __split_whole_condition(stmt->iterator_post_condition);
714 __use_false_states();
715 __merge_breaks();
716 }
717 loop_count--;
718 }
719
720 static int empty_statement(struct statement *stmt)
721 {
722 if (!stmt)
723 return 0;
724 if (stmt->type == STMT_EXPRESSION && !stmt->expression)
725 return 1;
726 return 0;
727 }
1601 __pass_to_client(sym, AFTER_FUNC_HOOK);
1602
1603 clear_all_states();
1604
1605 gettimeofday(&stop, NULL);
1606 if (option_time && stop.tv_sec - fn_start_time.tv_sec > 2) {
1607 final_pass++;
1608 sm_msg("func_time: %lu", stop.tv_sec - fn_start_time.tv_sec);
1609 final_pass--;
1610 }
1611 cur_func_sym = NULL;
1612 cur_func = NULL;
1613 free_data_info_allocs();
1614 free_expression_stack(&switch_expr_stack);
1615 __free_ptr_list((struct ptr_list **)&big_statement_stack);
1616 __bail_on_rest_of_function = 0;
1617 }
1618
1619 static void save_flow_state(void)
1620 {
1621 __add_ptr_list(&backup, INT_PTR(loop_num << 2));
1622 __add_ptr_list(&backup, INT_PTR(loop_count << 2));
1623 __add_ptr_list(&backup, INT_PTR(final_pass << 2));
1624
1625 __add_ptr_list(&backup, big_statement_stack);
1626 __add_ptr_list(&backup, big_expression_stack);
1627 __add_ptr_list(&backup, big_condition_stack);
1628 __add_ptr_list(&backup, switch_expr_stack);
1629
1630 __add_ptr_list(&backup, cur_func_sym);
1631
1632 __add_ptr_list(&backup, __prev_stmt);
1633 __add_ptr_list(&backup, __cur_stmt);
1634 __add_ptr_list(&backup, __next_stmt);
1635 }
1636
1637 static void *pop_backup(void)
1638 {
1639 void *ret;
1640
1641 ret = last_ptr_list(backup);
1642 delete_ptr_list_last(&backup);
1643 return ret;
1644 }
1645
1646 static void restore_flow_state(void)
1647 {
1648 __next_stmt = pop_backup();
1649 __cur_stmt = pop_backup();
1650 __prev_stmt = pop_backup();
1651
1652 cur_func_sym = pop_backup();
1653 switch_expr_stack = pop_backup();
1654 big_condition_stack = pop_backup();
|