smatch: add a --succeed option
[smatch.git] / check_implicit_dependencies_tester.c
blob6dcb4b52d1f4f007435c5e47c7642244fa77c1b3
1 #include "smatch.h"
2 #include "linearize.h"
4 static int my_id;
5 static struct symbol *cur_syscall;
7 static const char *expression_type_name(enum expression_type type)
9 static const char *expression_type_name[] = {
10 [EXPR_VALUE] = "EXPR_VALUE",
11 [EXPR_STRING] = "EXPR_STRING",
12 [EXPR_SYMBOL] = "EXPR_SYMBOL",
13 [EXPR_TYPE] = "EXPR_TYPE",
14 [EXPR_BINOP] = "EXPR_BINOP",
15 [EXPR_ASSIGNMENT] = "EXPR_ASSIGNMENT",
16 [EXPR_LOGICAL] = "EXPR_LOGICAL",
17 [EXPR_DEREF] = "EXPR_DEREF",
18 [EXPR_PREOP] = "EXPR_PREOP",
19 [EXPR_POSTOP] = "EXPR_POSTOP",
20 [EXPR_CAST] = "EXPR_CAST",
21 [EXPR_FORCE_CAST] = "EXPR_FORCE_CAST",
22 [EXPR_IMPLIED_CAST] = "EXPR_IMPLIED_CAST",
23 [EXPR_SIZEOF] = "EXPR_SIZEOF",
24 [EXPR_ALIGNOF] = "EXPR_ALIGNOF",
25 [EXPR_PTRSIZEOF] = "EXPR_PTRSIZEOF",
26 [EXPR_CONDITIONAL] = "EXPR_CONDITIONAL",
27 [EXPR_SELECT] = "EXPR_SELECT",
28 [EXPR_STATEMENT] = "EXPR_STATEMENT",
29 [EXPR_CALL] = "EXPR_CALL",
30 [EXPR_COMMA] = "EXPR_COMMA",
31 [EXPR_COMPARE] = "EXPR_COMPARE",
32 [EXPR_LABEL] = "EXPR_LABEL",
33 [EXPR_INITIALIZER] = "EXPR_INITIALIZER",
34 [EXPR_IDENTIFIER] = "EXPR_IDENTIFIER",
35 [EXPR_INDEX] = "EXPR_INDEX",
36 [EXPR_POS] = "EXPR_POS",
37 [EXPR_FVALUE] = "EXPR_FVALUE",
38 [EXPR_SLICE] = "EXPR_SLICE",
39 [EXPR_OFFSETOF] = "EXPR_OFFSETOF",
41 return expression_type_name[type] ?: "UNKNOWN_EXPRESSION_TYPE";
44 static inline void prefix() {
45 printf("%s:%d %s() ", get_filename(), get_lineno(), get_function());
48 static void match_syscall_definition(struct symbol *sym)
50 // struct symbol *arg;
51 char *macro;
52 char *name;
53 int is_syscall = 0;
55 macro = get_macro_name(sym->pos);
56 if (macro &&
57 (strncmp("SYSCALL_DEFINE", macro, strlen("SYSCALL_DEFINE")) == 0 ||
58 strncmp("COMPAT_SYSCALL_DEFINE", macro, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
59 is_syscall = 1;
61 name = get_function();
63 /*
64 if (!option_no_db && get_state(my_id, "this_function", NULL) != &called) {
65 if (name && strncmp(name, "sys_", 4) == 0)
66 is_syscall = 1;
70 /* Ignore compat_sys b/c syzkaller doesn't fuzz these?
71 if (name && strncmp(name, "compat_sys_", 11) == 0)
72 is_syscall = 1;
75 if (!is_syscall)
76 return;
77 printf("-------------------------\n");
78 printf("\nsyscall found: %s at: ", name);
79 prefix(); printf("\n");
80 cur_syscall = sym;
83 FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
84 set_state(my_id, arg->ident->name, arg, &user_data_set);
85 } END_FOR_EACH_PTR(arg);
89 static void match_after_syscall(struct symbol *sym) {
90 if (cur_syscall && sym == cur_syscall) {
91 printf("\n"); prefix();
92 printf("exiting scope of syscall %s\n", get_function());
93 printf("-------------------------\n");
94 cur_syscall = NULL;
98 static void print_member_type(struct expression *expr)
100 char *member;
102 member = get_member_name(expr);
103 if (!member)
104 return;
105 // sm_msg("info: uses %s", member);
106 prefix();
107 printf("info: uses %s\n", member);
108 free_string(member);
111 static void match_condition(struct expression *expr) {
112 if (!cur_syscall)
113 return;
116 prefix();
117 printf("found conditional %s on line %d\n", expression_type_name(expr->type), get_lineno());
118 printf("expr_str: %s\n", expr_to_str(expr));
122 switch (expr->type) {
123 case EXPR_COMPARE:
124 match_condition(expr->left);
125 match_condition(expr->right);
126 break;
127 case EXPR_SYMBOL:
128 printf("symbol: %s\n", expr->symbol_name->name);
129 break;
130 case EXPR_CALL:
131 break;
135 prefix(); printf("-- condition found\n");
137 if (expr->type == EXPR_COMPARE || expr->type == EXPR_BINOP
138 || expr->type == EXPR_LOGICAL
139 || expr->type == EXPR_ASSIGNMENT
140 || expr->type == EXPR_COMMA) {
141 match_condition(expr->left);
142 match_condition(expr->right);
143 return;
145 print_member_type(expr);
149 static void match_function_call(struct expression *expr) {
150 if (!cur_syscall)
151 return;
152 prefix();
153 printf("function call %s\n", expression_type_name(expr->type));
156 void check_implicit_dependencies_tester(int id)
158 my_id = id;
160 if (option_project != PROJ_KERNEL)
161 return;
163 add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
164 add_hook(&match_after_syscall, AFTER_FUNC_HOOK);
165 add_hook(&match_condition, CONDITION_HOOK);
166 add_hook(&match_function_call, FUNCTION_CALL_HOOK);