Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c
+++ new/usr/src/tools/smatch/src/smatch_param_to_mtag_data.c
1 1 /*
2 2 * Copyright (C) 2017 Oracle.
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 * Take a look at request_threaded_irq(). It takes thread_fn and dev_id. Then
20 20 * it does:
21 21 *
22 22 * action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
23 23 * action->thread_fn = thread_fn;
24 24 * action->dev_id = dev_id;
25 25 *
26 26 * It doesn't ever pass action back to the higher levels, but instead registers
27 27 * it with the lower levels.
28 28 *
29 29 * The kzalloc() allocation creates a new mtag. We don't know at this point
30 30 * what "thread_fn" and "dev_id" are because they come from many different
31 31 * sources.
32 32 *
33 33 * So what we do is we pass the information back to the callers that thread_fn
34 34 * and dev_id are stored as a specific mtag data. Then when the callers *do*
35 35 * know what values are passed they create an mtag_alias. An mtag_alias is a
36 36 * many to one relationship. Then they store that in mtag_data using the
37 37 * mtag_alias.
38 38 *
39 39 */
40 40
41 41 #include "smatch.h"
42 42 #include "smatch_extra.h"
43 43 #include "smatch_slist.h"
44 44
45 45 static int my_id;
46 46
47 47 struct tag_assign_info {
48 48 mtag_t tag;
49 49 int offset;
50 50 };
51 51 ALLOCATOR(tag_assign_info, "tag name offset");
52 52
53 53 static struct smatch_state *alloc_tag_data_state(mtag_t tag, char *name, int offset)
54 54 {
55 55 struct smatch_state *state;
56 56 struct tag_assign_info *data;
57 57
58 58 data = __alloc_tag_assign_info(0);
59 59 data->tag = tag;
60 60 data->offset = offset;
61 61
62 62 state = __alloc_smatch_state(0);
63 63 state->name = alloc_sname(name);
64 64 state->data = data;
65 65 return state;
66 66 }
67 67
68 68 struct smatch_state *merge_tag_info(struct smatch_state *s1, struct smatch_state *s2)
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
69 69 {
70 70 /* Basically ignore undefined states */
71 71 if (s1 == &undefined)
72 72 return s2;
73 73 if (s2 == &undefined)
74 74 return s1;
75 75
76 76 return &merged;
77 77 }
78 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 +
79 91 static void match_assign(struct expression *expr)
80 92 {
81 93 struct expression *left;
82 94 struct symbol *right_sym;
83 95 char *name;
84 96 mtag_t tag;
85 97 int offset;
86 98 int param;
87 99
88 100 if (expr->op != '=')
89 101 return;
90 102 left = strip_expr(expr->left);
103 + if (is_local_var(left))
104 + return;
91 105 right_sym = expr_to_sym(expr->right);
92 106 if (!right_sym)
93 107 return;
94 108
95 109 param = get_param_num_from_sym(right_sym);
96 110 if (param < 0)
97 111 return;
98 112 // FIXME: modify param_has_filter_data() to take a name/sym
99 113 if (!expr_to_mtag_offset(left, &tag, &offset))
100 114 return;
101 115 name = expr_to_str(left);
102 116 if (!name)
103 117 return;
104 118 set_state_expr(my_id, expr->right, alloc_tag_data_state(tag, name, offset));
105 119 free_string(name);
106 120 }
107 121
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 122 static void propogate_assignment(struct expression *expr, mtag_t tag, int offset, int param, char *key)
131 123 {
132 124 struct expression *arg;
133 125 int orig_param;
134 126 char buf[32];
135 127 char *name;
136 128 struct symbol *sym;
137 129
138 130 arg = get_argument_from_call_expr(expr->args, param);
139 131 if (!arg)
140 132 return;
141 133 name = get_variable_from_key(arg, key, &sym);
142 134 if (!name || !sym)
143 135 goto free;
144 136
145 137 orig_param = get_param_num_from_sym(sym);
146 138 if (orig_param < 0)
147 139 goto free;
148 140
149 141 snprintf(buf, sizeof(buf), "$->[%d]", offset);
150 142 set_state(my_id, name, sym, alloc_tag_data_state(tag, buf, offset));
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
151 143 free:
152 144 free_string(name);
153 145 }
154 146
155 147 static void assign_to_alias(struct expression *expr, int param, mtag_t tag, int offset, char *key)
156 148 {
157 149 struct expression *arg, *gen_expr;
158 150 struct range_list *rl;
159 151 mtag_t arg_tag;
160 152 mtag_t alias;
153 + int arg_offset;
161 154
162 155 arg = get_argument_from_call_expr(expr->args, param);
163 156 if (!arg)
164 157 return;
165 158
166 159 gen_expr = gen_expression_from_key(arg, key);
167 160 if (!gen_expr)
168 161 return;
169 162
170 163 get_absolute_rl(gen_expr, &rl);
171 164
172 165 if (!create_mtag_alias(tag, expr, &alias))
173 166 return;
174 167
175 168 // insert_mtag_data(alias, offset, rl);
176 169
177 - if (get_mtag(gen_expr, &arg_tag))
170 + // FIXME: is arg_offset handled correctly?
171 + if (expr_to_mtag_offset(gen_expr, &arg_tag, &arg_offset) && arg_offset == 0)
178 172 sql_insert_mtag_map(arg_tag, -offset, alias);
179 173 }
180 174
181 175 static void call_does_mtag_assign(struct expression *expr, int param, char *key, char *value)
182 176 {
183 177 char *p;
184 178 mtag_t tag;
185 179 int offset;
186 180
187 181 while (expr->type == EXPR_ASSIGNMENT)
188 182 expr = strip_expr(expr->right);
189 183 if (expr->type != EXPR_CALL)
190 184 return;
191 185
192 186 tag = strtoul(value, NULL, 10);
193 187 p = strchr(value, '+');
194 188 if (!p)
195 189 return;
196 190 offset = atoi(p + 1);
197 191
198 192 // save_mtag_to_map(expr, tag, offset, param, key, value);
199 193 propogate_assignment(expr, tag, offset, param, key);
200 194 assign_to_alias(expr, param, tag, offset, key);
201 195 }
202 196
203 197 static void print_stored_to_mtag(int return_id, char *return_ranges, struct expression *expr)
204 198 {
205 199 struct sm_state *sm;
206 200 struct tag_assign_info *data;
207 201 char buf[256];
208 202 const char *param_name;
209 203 int param;
210 204
211 205 FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
212 206 if (!sm->state->data)
213 207 continue;
214 208
215 209 param = get_param_num_from_sym(sm->sym);
216 210 if (param < 0)
217 211 continue;
218 212 param_name = get_param_name(sm);
219 213 if (!param_name)
220 214 continue;
221 215
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
222 216 data = sm->state->data;
223 217 snprintf(buf, sizeof(buf), "%lld+%d", data->tag, data->offset);
224 218 sql_insert_return_states(return_id, return_ranges, MTAG_ASSIGN, param, param_name, buf);
225 219 } END_FOR_EACH_SM(sm);
226 220 }
227 221
228 222 void register_param_to_mtag_data(int id)
229 223 {
230 224 my_id = id;
231 225
226 + set_dynamic_states(my_id);
232 227 add_hook(&match_assign, ASSIGNMENT_HOOK);
233 228 select_return_states_hook(MTAG_ASSIGN, &call_does_mtag_assign);
234 229 add_merge_hook(my_id, &merge_tag_info);
235 230 add_split_return_callback(&print_stored_to_mtag);
236 231 }
237 232
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX