59 data->tag = tag;
60 data->offset = offset;
61
62 state = __alloc_smatch_state(0);
63 state->name = alloc_sname(name);
64 state->data = data;
65 return state;
66 }
67
68 struct smatch_state *merge_tag_info(struct smatch_state *s1, struct smatch_state *s2)
69 {
70 /* Basically ignore undefined states */
71 if (s1 == &undefined)
72 return s2;
73 if (s2 == &undefined)
74 return s1;
75
76 return &merged;
77 }
78
79 static void match_assign(struct expression *expr)
80 {
81 struct expression *left;
82 struct symbol *right_sym;
83 char *name;
84 mtag_t tag;
85 int offset;
86 int param;
87
88 if (expr->op != '=')
89 return;
90 left = strip_expr(expr->left);
91 right_sym = expr_to_sym(expr->right);
92 if (!right_sym)
93 return;
94
95 param = get_param_num_from_sym(right_sym);
96 if (param < 0)
97 return;
98 // FIXME: modify param_has_filter_data() to take a name/sym
99 if (!expr_to_mtag_offset(left, &tag, &offset))
100 return;
101 name = expr_to_str(left);
102 if (!name)
103 return;
104 set_state_expr(my_id, expr->right, alloc_tag_data_state(tag, name, offset));
105 free_string(name);
106 }
107
108 #if 0
109 static void save_mtag_to_map(struct expression *expr, mtag_t tag, int offset, int param, char *key, char *value)
110 {
111 struct expression *arg, *gen_expr;
112 mtag_t arg_tag;
113
114 arg = get_argument_from_call_expr(expr->args, param);
115 if (!arg)
116 return;
117
118 gen_expr = gen_expression_from_key(arg, key);
119 if (!gen_expr)
120 return;
121
122 if (!get_mtag(gen_expr, &arg_tag))
123 arg_tag = 0;
124
125 if (local_debug)
126 sm_msg("finding mtag for '%s' %lld", expr_to_str(gen_expr), arg_tag);
127 }
128 #endif
129
130 static void propogate_assignment(struct expression *expr, mtag_t tag, int offset, int param, char *key)
131 {
132 struct expression *arg;
133 int orig_param;
134 char buf[32];
135 char *name;
136 struct symbol *sym;
137
138 arg = get_argument_from_call_expr(expr->args, param);
139 if (!arg)
140 return;
141 name = get_variable_from_key(arg, key, &sym);
142 if (!name || !sym)
143 goto free;
144
145 orig_param = get_param_num_from_sym(sym);
146 if (orig_param < 0)
147 goto free;
148
149 snprintf(buf, sizeof(buf), "$->[%d]", offset);
150 set_state(my_id, name, sym, alloc_tag_data_state(tag, buf, offset));
151 free:
152 free_string(name);
153 }
154
155 static void assign_to_alias(struct expression *expr, int param, mtag_t tag, int offset, char *key)
156 {
157 struct expression *arg, *gen_expr;
158 struct range_list *rl;
159 mtag_t arg_tag;
160 mtag_t alias;
161
162 arg = get_argument_from_call_expr(expr->args, param);
163 if (!arg)
164 return;
165
166 gen_expr = gen_expression_from_key(arg, key);
167 if (!gen_expr)
168 return;
169
170 get_absolute_rl(gen_expr, &rl);
171
172 if (!create_mtag_alias(tag, expr, &alias))
173 return;
174
175 // insert_mtag_data(alias, offset, rl);
176
177 if (get_mtag(gen_expr, &arg_tag))
178 sql_insert_mtag_map(arg_tag, -offset, alias);
179 }
180
181 static void call_does_mtag_assign(struct expression *expr, int param, char *key, char *value)
182 {
183 char *p;
184 mtag_t tag;
185 int offset;
186
187 while (expr->type == EXPR_ASSIGNMENT)
188 expr = strip_expr(expr->right);
189 if (expr->type != EXPR_CALL)
190 return;
191
192 tag = strtoul(value, NULL, 10);
193 p = strchr(value, '+');
194 if (!p)
195 return;
196 offset = atoi(p + 1);
197
212 if (!sm->state->data)
213 continue;
214
215 param = get_param_num_from_sym(sm->sym);
216 if (param < 0)
217 continue;
218 param_name = get_param_name(sm);
219 if (!param_name)
220 continue;
221
222 data = sm->state->data;
223 snprintf(buf, sizeof(buf), "%lld+%d", data->tag, data->offset);
224 sql_insert_return_states(return_id, return_ranges, MTAG_ASSIGN, param, param_name, buf);
225 } END_FOR_EACH_SM(sm);
226 }
227
228 void register_param_to_mtag_data(int id)
229 {
230 my_id = id;
231
232 add_hook(&match_assign, ASSIGNMENT_HOOK);
233 select_return_states_hook(MTAG_ASSIGN, &call_does_mtag_assign);
234 add_merge_hook(my_id, &merge_tag_info);
235 add_split_return_callback(&print_stored_to_mtag);
236 }
237
|
59 data->tag = tag;
60 data->offset = offset;
61
62 state = __alloc_smatch_state(0);
63 state->name = alloc_sname(name);
64 state->data = data;
65 return state;
66 }
67
68 struct smatch_state *merge_tag_info(struct smatch_state *s1, struct smatch_state *s2)
69 {
70 /* Basically ignore undefined states */
71 if (s1 == &undefined)
72 return s2;
73 if (s2 == &undefined)
74 return s1;
75
76 return &merged;
77 }
78
79 static bool is_local_var(struct expression *expr)
80 {
81 struct symbol *sym;
82
83 if (!expr || expr->type != EXPR_SYMBOL)
84 return false;
85 sym = expr->symbol;
86 if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
87 return true;
88 return false;
89 }
90
91 static void match_assign(struct expression *expr)
92 {
93 struct expression *left;
94 struct symbol *right_sym;
95 char *name;
96 mtag_t tag;
97 int offset;
98 int param;
99
100 if (expr->op != '=')
101 return;
102 left = strip_expr(expr->left);
103 if (is_local_var(left))
104 return;
105 right_sym = expr_to_sym(expr->right);
106 if (!right_sym)
107 return;
108
109 param = get_param_num_from_sym(right_sym);
110 if (param < 0)
111 return;
112 // FIXME: modify param_has_filter_data() to take a name/sym
113 if (!expr_to_mtag_offset(left, &tag, &offset))
114 return;
115 name = expr_to_str(left);
116 if (!name)
117 return;
118 set_state_expr(my_id, expr->right, alloc_tag_data_state(tag, name, offset));
119 free_string(name);
120 }
121
122 static void propogate_assignment(struct expression *expr, mtag_t tag, int offset, int param, char *key)
123 {
124 struct expression *arg;
125 int orig_param;
126 char buf[32];
127 char *name;
128 struct symbol *sym;
129
130 arg = get_argument_from_call_expr(expr->args, param);
131 if (!arg)
132 return;
133 name = get_variable_from_key(arg, key, &sym);
134 if (!name || !sym)
135 goto free;
136
137 orig_param = get_param_num_from_sym(sym);
138 if (orig_param < 0)
139 goto free;
140
141 snprintf(buf, sizeof(buf), "$->[%d]", offset);
142 set_state(my_id, name, sym, alloc_tag_data_state(tag, buf, offset));
143 free:
144 free_string(name);
145 }
146
147 static void assign_to_alias(struct expression *expr, int param, mtag_t tag, int offset, char *key)
148 {
149 struct expression *arg, *gen_expr;
150 struct range_list *rl;
151 mtag_t arg_tag;
152 mtag_t alias;
153 int arg_offset;
154
155 arg = get_argument_from_call_expr(expr->args, param);
156 if (!arg)
157 return;
158
159 gen_expr = gen_expression_from_key(arg, key);
160 if (!gen_expr)
161 return;
162
163 get_absolute_rl(gen_expr, &rl);
164
165 if (!create_mtag_alias(tag, expr, &alias))
166 return;
167
168 // insert_mtag_data(alias, offset, rl);
169
170 // FIXME: is arg_offset handled correctly?
171 if (expr_to_mtag_offset(gen_expr, &arg_tag, &arg_offset) && arg_offset == 0)
172 sql_insert_mtag_map(arg_tag, -offset, alias);
173 }
174
175 static void call_does_mtag_assign(struct expression *expr, int param, char *key, char *value)
176 {
177 char *p;
178 mtag_t tag;
179 int offset;
180
181 while (expr->type == EXPR_ASSIGNMENT)
182 expr = strip_expr(expr->right);
183 if (expr->type != EXPR_CALL)
184 return;
185
186 tag = strtoul(value, NULL, 10);
187 p = strchr(value, '+');
188 if (!p)
189 return;
190 offset = atoi(p + 1);
191
206 if (!sm->state->data)
207 continue;
208
209 param = get_param_num_from_sym(sm->sym);
210 if (param < 0)
211 continue;
212 param_name = get_param_name(sm);
213 if (!param_name)
214 continue;
215
216 data = sm->state->data;
217 snprintf(buf, sizeof(buf), "%lld+%d", data->tag, data->offset);
218 sql_insert_return_states(return_id, return_ranges, MTAG_ASSIGN, param, param_name, buf);
219 } END_FOR_EACH_SM(sm);
220 }
221
222 void register_param_to_mtag_data(int id)
223 {
224 my_id = id;
225
226 set_dynamic_states(my_id);
227 add_hook(&match_assign, ASSIGNMENT_HOOK);
228 select_return_states_hook(MTAG_ASSIGN, &call_does_mtag_assign);
229 add_merge_hook(my_id, &merge_tag_info);
230 add_split_return_callback(&print_stored_to_mtag);
231 }
232
|