xref: /illumos-gate/usr/src/tools/smatch/src/smatch_db.c (revision 5bb525f494c825f138113d51f2ba7acf185093f3)
1 /*
2  * Copyright (C) 2010 Dan Carpenter.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16  */
17 
18 #include <string.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <ctype.h>
22 #include "smatch.h"
23 #include "smatch_slist.h"
24 #include "smatch_extra.h"
25 
26 struct sqlite3 *smatch_db;
27 struct sqlite3 *mem_db;
28 struct sqlite3 *cache_db;
29 
30 static int return_id;
31 
32 #define SQLITE_CACHE_PAGES 1000
33 
34 struct def_callback {
35 	int hook_type;
36 	void (*callback)(const char *name, struct symbol *sym, char *key, char *value);
37 };
38 ALLOCATOR(def_callback, "definition db hook callbacks");
39 DECLARE_PTR_LIST(callback_list, struct def_callback);
40 static struct callback_list *select_caller_info_callbacks;
41 
42 struct member_info_callback {
43 	int owner;
44 	void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm);
45 };
46 ALLOCATOR(member_info_callback, "caller_info callbacks");
47 DECLARE_PTR_LIST(member_info_cb_list, struct member_info_callback);
48 static struct member_info_cb_list *member_callbacks;
49 
50 struct returned_state_callback {
51 	void (*callback)(int return_id, char *return_ranges, struct expression *return_expr);
52 };
53 ALLOCATOR(returned_state_callback, "returned state callbacks");
54 DECLARE_PTR_LIST(returned_state_cb_list, struct returned_state_callback);
55 static struct returned_state_cb_list *returned_state_callbacks;
56 
57 struct returned_member_callback {
58 	int owner;
59 	void (*callback)(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state);
60 };
61 ALLOCATOR(returned_member_callback, "returned member callbacks");
62 DECLARE_PTR_LIST(returned_member_cb_list, struct returned_member_callback);
63 static struct returned_member_cb_list *returned_member_callbacks;
64 
65 struct db_implies_callback {
66 	int type;
67 	void (*callback)(struct expression *call, struct expression *arg, char *key, char *value);
68 };
69 ALLOCATOR(db_implies_callback, "return_implies callbacks");
70 DECLARE_PTR_LIST(db_implies_cb_list, struct db_implies_callback);
71 static struct db_implies_cb_list *return_implies_cb_list;
72 static struct db_implies_cb_list *call_implies_cb_list;
73 
74 /* silently truncates if needed. */
75 char *escape_newlines(const char *str)
76 {
77 	char buf[1024] = "";
78 	bool found = false;
79 	int i, j;
80 
81 	for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
82 		if (str[i] != '\n') {
83 			buf[j] = str[i];
84 			continue;
85 		}
86 
87 		found = true;
88 		buf[j++] = '\\';
89 		if (j == sizeof(buf))
90 			 break;
91 		buf[j] = 'n';
92 	}
93 
94 	if (!found)
95 		return alloc_sname(str);
96 
97 	if (j == sizeof(buf))
98 		buf[j - 1] = '\0';
99 	return alloc_sname(buf);
100 }
101 
102 static int print_sql_output(void *unused, int argc, char **argv, char **azColName)
103 {
104 	int i;
105 
106 	for (i = 0; i < argc; i++) {
107 		if (i != 0)
108 			printf(", ");
109 		sm_printf("%s", argv[i]);
110 	}
111 	sm_printf("\n");
112 	return 0;
113 }
114 
115 void sql_exec(struct sqlite3 *db, int (*callback)(void*, int, char**, char**), void *data, const char *sql)
116 {
117 	char *err = NULL;
118 	int rc;
119 
120 	if (!db)
121 		return;
122 
123 	if (option_debug) {
124 		sm_msg("%s", sql);
125 		if (strncasecmp(sql, "select", strlen("select")) == 0)
126 			sqlite3_exec(db, sql, print_sql_output, NULL, NULL);
127 	}
128 
129 	rc = sqlite3_exec(db, sql, callback, data, &err);
130 	if (rc != SQLITE_OK && !parse_error) {
131 		sm_ierror("%s:%d SQL error #2: %s\n", get_filename(), get_lineno(), err);
132 		sm_ierror("%s:%d SQL: '%s'\n", get_filename(), get_lineno(), sql);
133 		parse_error = 1;
134 	}
135 }
136 
137 static int replace_count;
138 static char **replace_table;
139 static const char *replace_return_ranges(const char *return_ranges)
140 {
141 	int i;
142 
143 	if (!get_function()) {
144 		/* I have no idea why EXPORT_SYMBOL() is here */
145 		return return_ranges;
146 	}
147 	for (i = 0; i < replace_count; i += 3) {
148 		if (strcmp(replace_table[i + 0], get_function()) == 0) {
149 			if (strcmp(replace_table[i + 1], return_ranges) == 0)
150 				return replace_table[i + 2];
151 		}
152 	}
153 	return return_ranges;
154 }
155 
156 
157 static char *use_states;
158 static int get_db_state_count(void)
159 {
160 	struct sm_state *sm;
161 	int count = 0;
162 
163 	FOR_EACH_SM(__get_cur_stree(), sm) {
164 		if (sm->owner == USHRT_MAX)
165 			continue;
166 		if (use_states[sm->owner])
167 			count++;
168 	} END_FOR_EACH_SM(sm);
169 	return count;
170 }
171 
172 void db_ignore_states(int id)
173 {
174 	use_states[id] = 0;
175 }
176 
177 void sql_insert_return_states(int return_id, const char *return_ranges,
178 		int type, int param, const char *key, const char *value)
179 {
180 	if (key && strlen(key) >= 80)
181 		return;
182 	return_ranges = replace_return_ranges(return_ranges);
183 	sql_insert(return_states, "'%s', '%s', %lu, %d, '%s', %d, %d, %d, '%s', '%s'",
184 		   get_base_file(), get_function(), (unsigned long)__inline_fn,
185 		   return_id, return_ranges, fn_static(), type, param, key, value);
186 }
187 
188 static struct string_list *common_funcs;
189 static int is_common_function(const char *fn)
190 {
191 	char *tmp;
192 
193 	if (!fn)
194 		return 0;
195 
196 	if (strncmp(fn, "__builtin_", 10) == 0)
197 		return 1;
198 
199 	FOR_EACH_PTR(common_funcs, tmp) {
200 		if (strcmp(tmp, fn) == 0)
201 			return 1;
202 	} END_FOR_EACH_PTR(tmp);
203 
204 	return 0;
205 }
206 
207 static char *function_signature(void)
208 {
209 	return type_to_str(get_real_base_type(cur_func_sym));
210 }
211 
212 void sql_insert_caller_info(struct expression *call, int type,
213 		int param, const char *key, const char *value)
214 {
215 	FILE *tmp_fd = sm_outfd;
216 	char *fn;
217 
218 	if (!option_info && !__inline_call)
219 		return;
220 
221 	if (key && strlen(key) >= 80)
222 		return;
223 
224 	fn = get_fnptr_name(call->fn);
225 	if (!fn)
226 		return;
227 
228 	if (__inline_call) {
229 		mem_sql(NULL, NULL,
230 			"insert into caller_info values ('%s', '%s', '%s', %lu, %d, %d, %d, '%s', '%s');",
231 			get_base_file(), get_function(), fn, (unsigned long)call,
232 			is_static(call->fn), type, param, key, value);
233 	}
234 
235 	if (!option_info)
236 		return;
237 
238 	if (strncmp(fn, "__builtin_", 10) == 0)
239 		return;
240 	if (type != INTERNAL && is_common_function(fn))
241 		return;
242 
243 	sm_outfd = caller_info_fd;
244 	sm_msg("SQL_caller_info: insert into caller_info values ("
245 	       "'%s', '%s', '%s', %%CALL_ID%%, %d, %d, %d, '%s', '%s');",
246 	       get_base_file(), get_function(), fn, is_static(call->fn),
247 	       type, param, key, value);
248 	sm_outfd = tmp_fd;
249 
250 	free_string(fn);
251 }
252 
253 void sql_insert_function_ptr(const char *fn, const char *struct_name)
254 {
255 	sql_insert(function_ptr, "'%s', '%s', '%s', 0", get_base_file(), fn,
256 		   struct_name);
257 }
258 
259 void sql_insert_return_implies(int type, int param, const char *key, const char *value)
260 {
261 	sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
262 		get_base_file(), get_function(), (unsigned long)__inline_fn,
263 		fn_static(), type, param, key, value);
264 }
265 
266 void sql_insert_call_implies(int type, int param, const char *key, const char *value)
267 {
268 	sql_insert_or_ignore(call_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
269 		get_base_file(), get_function(), (unsigned long)__inline_fn,
270 		fn_static(), type, param, key, value);
271 }
272 
273 void sql_insert_function_type_size(const char *member, const char *ranges)
274 {
275 	sql_insert(function_type_size, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), member, ranges);
276 }
277 
278 void sql_insert_function_type_info(int type, const char *struct_type, const char *member, const char *value)
279 {
280 	sql_insert(function_type_info, "'%s', '%s', %d, '%s', '%s', '%s'", get_base_file(), get_function(), type, struct_type, member, value);
281 }
282 
283 void sql_insert_type_info(int type, const char *member, const char *value)
284 {
285 	sql_insert_cache(type_info, "'%s', %d, '%s', '%s'", get_base_file(), type, member, value);
286 }
287 
288 void sql_insert_local_values(const char *name, const char *value)
289 {
290 	sql_insert(local_values, "'%s', '%s', '%s'", get_base_file(), name, value);
291 }
292 
293 void sql_insert_function_type_value(const char *type, const char *value)
294 {
295 	sql_insert(function_type_value, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), type, value);
296 }
297 
298 void sql_insert_function_type(int param, const char *value)
299 {
300 	sql_insert(function_type, "'%s', '%s', %d, %d, '%s'",
301 		   get_base_file(), get_function(), fn_static(), param, value);
302 }
303 
304 void sql_insert_parameter_name(int param, const char *value)
305 {
306 	sql_insert(parameter_name, "'%s', '%s', %d, %d, '%s'",
307 		   get_base_file(), get_function(), fn_static(), param, value);
308 }
309 
310 void sql_insert_data_info(struct expression *data, int type, const char *value)
311 {
312 	char *data_name;
313 
314 	data_name = get_data_info_name(data);
315 	if (!data_name)
316 		return;
317 	sql_insert(data_info, "'%s', '%s', %d, '%s'",
318 		   is_static(data) ? get_base_file() : "extern",
319 		   data_name, type, value);
320 }
321 
322 void sql_insert_data_info_var_sym(const char *var, struct symbol *sym, int type, const char *value)
323 {
324 	sql_insert(data_info, "'%s', '%s', %d, '%s'",
325 		   (sym->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
326 		   var, type, value);
327 }
328 
329 void sql_save_constraint(const char *con)
330 {
331 	if (!option_info)
332 		return;
333 
334         sm_msg("SQL: insert or ignore into constraints (str) values('%s');", con);
335 }
336 
337 void sql_save_constraint_required(const char *data, int op, const char *limit)
338 {
339 	sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
340 }
341 
342 void sql_copy_constraint_required(const char *new_limit, const char *old_limit)
343 {
344 	if (!option_info)
345 		return;
346 
347 	sm_msg("SQL_late: insert or ignore into constraints_required (data, op, bound) "
348 		"select constraints_required.data, constraints_required.op, '%s' from "
349 		"constraints_required where bound = '%s';", new_limit, old_limit);
350 }
351 
352 void sql_insert_fn_ptr_data_link(const char *ptr, const char *data)
353 {
354 	sql_insert_or_ignore(fn_ptr_data_link, "'%s', '%s'", ptr, data);
355 }
356 
357 void sql_insert_fn_data_link(struct expression *fn, int type, int param, const char *key, const char *value)
358 {
359 	if (fn->type != EXPR_SYMBOL || !fn->symbol->ident)
360 		return;
361 
362 	sql_insert(fn_data_link, "'%s', '%s', %d, %d, %d, '%s', '%s'",
363 		   (fn->symbol->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
364 		   fn->symbol->ident->name,
365 		   !!(fn->symbol->ctype.modifiers & MOD_STATIC),
366 		   type, param, key, value);
367 }
368 
369 void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
370 {
371 	sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
372 		   tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
373 }
374 
375 void sql_insert_mtag_data(mtag_t tag, const char *var, int offset, int type, const char *value)
376 {
377 	sql_insert(mtag_data, "%lld, '%s', %d, %d, '%s'", tag, var, offset, type, value);
378 }
379 
380 void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
381 {
382 	sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
383 }
384 
385 void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
386 {
387 	sql_insert(mtag_alias, "%lld, %lld", orig, alias);
388 }
389 
390 static int save_mtag(void *_tag, int argc, char **argv, char **azColName)
391 {
392 	mtag_t *saved_tag = _tag;
393 	mtag_t new_tag;
394 
395 	new_tag = strtoll(argv[0], NULL, 10);
396 
397 	if (!*saved_tag)
398 		*saved_tag = new_tag;
399 	else if (*saved_tag != new_tag)
400 		*saved_tag = -1ULL;
401 
402 	return 0;
403 }
404 
405 int mtag_map_select_container(mtag_t tag, int offset, mtag_t *container)
406 {
407 	mtag_t tmp = 0;
408 
409 	run_sql(save_mtag, &tmp,
410 		"select container from mtag_map where tag = %lld and offset = %d;",
411 		tag, offset);
412 
413 	if (tmp == 0 || tmp == -1ULL)
414 		return 0;
415 	*container = tmp;
416 	return 1;
417 }
418 
419 int mtag_map_select_tag(mtag_t container, int offset, mtag_t *tag)
420 {
421 	mtag_t tmp = 0;
422 
423 	run_sql(save_mtag, &tmp,
424 		"select tag from mtag_map where container = %lld and offset = %d;",
425 		container, offset);
426 
427 	if (tmp == 0 || tmp == -1ULL)
428 		return 0;
429 	*tag = tmp;
430 	return 1;
431 }
432 
433 char *get_static_filter(struct symbol *sym)
434 {
435 	static char sql_filter[1024];
436 
437 	/* This can only happen on buggy code.  Return invalid SQL. */
438 	if (!sym) {
439 		sql_filter[0] = '\0';
440 		return sql_filter;
441 	}
442 
443 	if (sym->ctype.modifiers & MOD_STATIC) {
444 		snprintf(sql_filter, sizeof(sql_filter),
445 			 "file = '%s' and function = '%s' and static = '1'",
446 			 get_base_file(), sym->ident->name);
447 	} else {
448 		snprintf(sql_filter, sizeof(sql_filter),
449 			 "function = '%s' and static = '0'", sym->ident->name);
450 	}
451 
452 	return sql_filter;
453 }
454 
455 static int get_row_count(void *_row_count, int argc, char **argv, char **azColName)
456 {
457 	int *row_count = _row_count;
458 
459 	*row_count = 0;
460 	if (argc != 1)
461 		return 0;
462 	*row_count = atoi(argv[0]);
463 	return 0;
464 }
465 
466 static void mark_call_params_untracked(struct expression *call)
467 {
468 	struct expression *arg;
469 	int i = 0;
470 
471 	FOR_EACH_PTR(call->args, arg) {
472 		mark_untracked(call, i++, "$", NULL);
473 	} END_FOR_EACH_PTR(arg);
474 }
475 
476 static void sql_select_return_states_pointer(const char *cols,
477 	struct expression *call, int (*callback)(void*, int, char**, char**), void *info)
478 {
479 	char *ptr;
480 	int return_count = 0;
481 
482 	ptr = get_fnptr_name(call->fn);
483 	if (!ptr)
484 		return;
485 
486 	run_sql(get_row_count, &return_count,
487 		"select count(*) from return_states join function_ptr "
488 		"where return_states.function == function_ptr.function and "
489 		"ptr = '%s' and searchable = 1 and type = %d;", ptr, INTERNAL);
490 	/* The magic number 100 is just from testing on the kernel. */
491 	if (return_count > 100) {
492 		mark_call_params_untracked(call);
493 		return;
494 	}
495 
496 	run_sql(callback, info,
497 		"select %s from return_states join function_ptr where "
498 		"return_states.function == function_ptr.function and ptr = '%s' "
499 		"and searchable = 1 "
500 		"order by function_ptr.file, return_states.file, return_id, type;",
501 		cols, ptr);
502 }
503 
504 static int is_local_symbol(struct expression *expr)
505 {
506 	if (expr->type != EXPR_SYMBOL)
507 		return 0;
508 	if (expr->symbol->ctype.modifiers & (MOD_NONLOCAL | MOD_STATIC | MOD_ADDRESSABLE))
509 		return 0;
510 	return 1;
511 }
512 
513 void sql_select_return_states(const char *cols, struct expression *call,
514 	int (*callback)(void*, int, char**, char**), void *info)
515 {
516 	int row_count = 0;
517 
518 	if (is_fake_call(call))
519 		return;
520 
521 	if (call->fn->type != EXPR_SYMBOL || !call->fn->symbol || is_local_symbol(call->fn)) {
522 		sql_select_return_states_pointer(cols, call, callback, info);
523 		return;
524 	}
525 
526 	if (inlinable(call->fn)) {
527 		mem_sql(callback, info,
528 			"select %s from return_states where call_id = '%lu' order by return_id, type;",
529 			cols, (unsigned long)call);
530 		return;
531 	}
532 
533 	run_sql(get_row_count, &row_count, "select count(*) from return_states where %s;",
534 		get_static_filter(call->fn->symbol));
535 	if (row_count > 3000)
536 		return;
537 
538 	run_sql(callback, info, "select %s from return_states where %s order by file, return_id, type;",
539 		cols, get_static_filter(call->fn->symbol));
540 }
541 
542 #define CALL_IMPLIES 0
543 #define RETURN_IMPLIES 1
544 
545 struct implies_info {
546 	int type;
547 	struct db_implies_cb_list *cb_list;
548 	struct expression *expr;
549 	struct symbol *sym;
550 };
551 
552 void sql_select_implies(const char *cols, struct implies_info *info,
553 	int (*callback)(void*, int, char**, char**))
554 {
555 	if (info->type == RETURN_IMPLIES && inlinable(info->expr->fn)) {
556 		mem_sql(callback, info,
557 			"select %s from return_implies where call_id = '%lu';",
558 			cols, (unsigned long)info->expr);
559 		return;
560 	}
561 
562 	run_sql(callback, info, "select %s from %s_implies where %s;",
563 		cols,
564 		info->type == CALL_IMPLIES ? "call" : "return",
565 		get_static_filter(info->sym));
566 }
567 
568 struct select_caller_info_data {
569 	struct stree *final_states;
570 	struct timeval start_time;
571 	int prev_func_id;
572 	int ignore;
573 	int results;
574 };
575 
576 static int caller_info_callback(void *_data, int argc, char **argv, char **azColName);
577 
578 static void sql_select_caller_info(struct select_caller_info_data *data,
579 	const char *cols, struct symbol *sym)
580 {
581 	if (__inline_fn) {
582 		mem_sql(caller_info_callback, data,
583 			"select %s from caller_info where call_id = %lu;",
584 			cols, (unsigned long)__inline_fn);
585 		return;
586 	}
587 
588 	if (sym->ident->name && is_common_function(sym->ident->name))
589 		return;
590 	run_sql(caller_info_callback, data,
591 		"select %s from common_caller_info where %s order by call_id;",
592 		cols, get_static_filter(sym));
593 	if (data->results)
594 		return;
595 
596 	run_sql(caller_info_callback, data,
597 		"select %s from caller_info where %s order by call_id;",
598 		cols, get_static_filter(sym));
599 }
600 
601 void select_caller_info_hook(void (*callback)(const char *name, struct symbol *sym, char *key, char *value), int type)
602 {
603 	struct def_callback *def_callback = __alloc_def_callback(0);
604 
605 	def_callback->hook_type = type;
606 	def_callback->callback = callback;
607 	add_ptr_list(&select_caller_info_callbacks, def_callback);
608 }
609 
610 /*
611  * These call backs are used when the --info option is turned on to print struct
612  * member information.  For example foo->bar could have a state in
613  * smatch_extra.c and also check_user.c.
614  */
615 void add_member_info_callback(int owner, void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
616 {
617 	struct member_info_callback *member_callback = __alloc_member_info_callback(0);
618 
619 	member_callback->owner = owner;
620 	member_callback->callback = callback;
621 	add_ptr_list(&member_callbacks, member_callback);
622 }
623 
624 void add_split_return_callback(void (*fn)(int return_id, char *return_ranges, struct expression *returned_expr))
625 {
626 	struct returned_state_callback *callback = __alloc_returned_state_callback(0);
627 
628 	callback->callback = fn;
629 	add_ptr_list(&returned_state_callbacks, callback);
630 }
631 
632 void add_returned_member_callback(int owner, void (*callback)(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state))
633 {
634 	struct returned_member_callback *member_callback = __alloc_returned_member_callback(0);
635 
636 	member_callback->owner = owner;
637 	member_callback->callback = callback;
638 	add_ptr_list(&returned_member_callbacks, member_callback);
639 }
640 
641 void select_call_implies_hook(int type, void (*callback)(struct expression *call, struct expression *arg, char *key, char *value))
642 {
643 	struct db_implies_callback *cb = __alloc_db_implies_callback(0);
644 
645 	cb->type = type;
646 	cb->callback = callback;
647 	add_ptr_list(&call_implies_cb_list, cb);
648 }
649 
650 void select_return_implies_hook(int type, void (*callback)(struct expression *call, struct expression *arg, char *key, char *value))
651 {
652 	struct db_implies_callback *cb = __alloc_db_implies_callback(0);
653 
654 	cb->type = type;
655 	cb->callback = callback;
656 	add_ptr_list(&return_implies_cb_list, cb);
657 }
658 
659 struct return_info {
660 	struct expression *static_returns_call;
661 	struct symbol *return_type;
662 	struct range_list *return_range_list;
663 };
664 
665 static int db_return_callback(void *_ret_info, int argc, char **argv, char **azColName)
666 {
667 	struct return_info *ret_info = _ret_info;
668 	struct range_list *rl;
669 	struct expression *call_expr = ret_info->static_returns_call;
670 
671 	if (argc != 1)
672 		return 0;
673 	call_results_to_rl(call_expr, ret_info->return_type, argv[0], &rl);
674 	ret_info->return_range_list = rl_union(ret_info->return_range_list, rl);
675 	return 0;
676 }
677 
678 struct range_list *db_return_vals(struct expression *expr)
679 {
680 	struct return_info ret_info = {};
681 	char buf[64];
682 	struct sm_state *sm;
683 
684 	if (is_fake_call(expr))
685 		return NULL;
686 
687 	snprintf(buf, sizeof(buf), "return %p", expr);
688 	sm = get_sm_state(SMATCH_EXTRA, buf, NULL);
689 	if (sm)
690 		return clone_rl(estate_rl(sm->state));
691 	ret_info.static_returns_call = expr;
692 	ret_info.return_type = get_type(expr);
693 	if (!ret_info.return_type)
694 		return NULL;
695 
696 	if (expr->fn->type != EXPR_SYMBOL || !expr->fn->symbol)
697 		return NULL;
698 
699 	ret_info.return_range_list = NULL;
700 	if (inlinable(expr->fn)) {
701 		mem_sql(db_return_callback, &ret_info,
702 			"select distinct return from return_states where call_id = '%lu';",
703 			(unsigned long)expr);
704 	} else {
705 		run_sql(db_return_callback, &ret_info,
706 			"select distinct return from return_states where %s;",
707 			get_static_filter(expr->fn->symbol));
708 	}
709 	return ret_info.return_range_list;
710 }
711 
712 struct range_list *db_return_vals_from_str(const char *fn_name)
713 {
714 	struct return_info ret_info;
715 
716 	ret_info.static_returns_call = NULL;
717 	ret_info.return_type = &llong_ctype;
718 	ret_info.return_range_list = NULL;
719 
720 	run_sql(db_return_callback, &ret_info,
721 		"select distinct return from return_states where function = '%s';",
722 		fn_name);
723 	return ret_info.return_range_list;
724 }
725 
726 static void match_call_marker(struct expression *expr)
727 {
728 	struct symbol *type;
729 
730 	type = get_type(expr->fn);
731 	if (type && type->type == SYM_PTR)
732 		type = get_real_base_type(type);
733 
734 	/*
735 	 * we just want to record something in the database so that if we have
736 	 * two calls like:  frob(4); frob(some_unkown); then on the receiving
737 	 * side we know that sometimes frob is called with unknown parameters.
738 	 */
739 
740 	sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
741 }
742 
743 static char *show_offset(int offset)
744 {
745 	static char buf[64];
746 
747 	buf[0] = '\0';
748 	if (offset != -1)
749 		snprintf(buf, sizeof(buf), "(-%d)", offset);
750 	return buf;
751 }
752 
753 static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
754 	void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
755 {
756 	struct sm_state *sm;
757 	char *name;
758 	struct symbol *sym;
759 	int len;
760 	char printed_name[256];
761 	int is_address = 0;
762 	struct symbol *type;
763 
764 	expr = strip_expr(expr);
765 	if (!expr)
766 		return;
767 	if (expr->type == EXPR_PREOP && expr->op == '&') {
768 		expr = strip_expr(expr->unop);
769 		is_address = 1;
770 	}
771 
772 	type = get_type(expr);
773 	if (type && type_bits(type) < type_bits(&ulong_ctype))
774 		return;
775 
776 	name = expr_to_var_sym(expr, &sym);
777 	if (!name || !sym)
778 		goto free;
779 
780 	len = strlen(name);
781 	FOR_EACH_SM(stree, sm) {
782 		if (sm->sym != sym)
783 			continue;
784 		if (strcmp(name, sm->name) == 0) {
785 			if (is_address)
786 				snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
787 			else /* these are already handled. fixme: handle them here */
788 				continue;
789 		} else if (sm->name[0] == '*' && strcmp(name, sm->name + 1) == 0) {
790 			snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
791 		} else if (strncmp(name, sm->name, len) == 0) {
792 			if (isalnum(sm->name[len]))
793 				continue;
794 			if (is_address)
795 				snprintf(printed_name, sizeof(printed_name), "$%s->%s", show_offset(offset), sm->name + len + 1);
796 			else
797 				snprintf(printed_name, sizeof(printed_name), "$%s%s", show_offset(offset), sm->name + len);
798 		} else {
799 			continue;
800 		}
801 		callback(call, param, printed_name, sm);
802 	} END_FOR_EACH_SM(sm);
803 free:
804 	free_string(name);
805 }
806 
807 static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
808 {
809 	char **container = _container;
810 	static char buf[256];
811 
812 	snprintf(buf, sizeof(buf), "%s", argv[0]);
813 	*container = buf;
814 	return 0;
815 }
816 
817 static void print_container_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
818 	void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
819 {
820 	struct expression *tmp;
821 	char *container = NULL;
822 	int offset;
823 	int holder_offset;
824 	char *p;
825 
826 	if (!call->fn || call->fn->type != EXPR_SYMBOL || !call->fn->symbol)
827 		return;
828 
829 	/*
830 	 * We can't use the in-mem DB because we have to parse the function
831 	 * first, then we know if it takes a container, then we know to pass it
832 	 * the container data.
833 	 *
834 	 */
835 	run_sql(&param_used_callback, &container,
836 		"select key from return_implies where %s and type = %d and key like '%%$(%%' and parameter = %d limit 1;",
837 		get_static_filter(call->fn->symbol), CONTAINER, param);
838 	if (!container)
839 		return;
840 
841 	p = strchr(container, '-');
842 	if (!p)
843 		return;
844 	offset = atoi(p);
845 	p = strchr(p, ')');
846 	if (!p)
847 		return;
848 	p++;
849 
850 	tmp = get_assigned_expr(expr);
851 	if (tmp)
852 		expr = tmp;
853 
854 	if (expr->type != EXPR_PREOP || expr->op != '&')
855 		return;
856 	expr = strip_expr(expr->unop);
857 	holder_offset = get_member_offset_from_deref(expr);
858 	if (-holder_offset != offset)
859 		return;
860 
861 	expr = strip_expr(expr->deref);
862 	if (expr->type == EXPR_PREOP && expr->op == '*')
863 		expr = strip_expr(expr->unop);
864 
865 	print_struct_members(call, expr, param, holder_offset, stree, callback);
866 }
867 
868 static void match_call_info(struct expression *call)
869 {
870 	struct member_info_callback *cb;
871 	struct expression *arg;
872 	struct stree *stree;
873 	char *name;
874 	int i;
875 
876 	name = get_fnptr_name(call->fn);
877 	if (!name)
878 		return;
879 
880 	FOR_EACH_PTR(member_callbacks, cb) {
881 		stree = get_all_states_stree(cb->owner);
882 		i = 0;
883 		FOR_EACH_PTR(call->args, arg) {
884 			print_struct_members(call, arg, i, -1, stree, cb->callback);
885 			print_container_struct_members(call, arg, i, stree, cb->callback);
886 			i++;
887 		} END_FOR_EACH_PTR(arg);
888 		free_stree(&stree);
889 	} END_FOR_EACH_PTR(cb);
890 
891 	free_string(name);
892 }
893 
894 static int get_param(int param, char **name, struct symbol **sym)
895 {
896 	struct symbol *arg;
897 	int i;
898 
899 	i = 0;
900 	FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
901 		/*
902 		 * this is a temporary hack to work around a bug (I think in sparse?)
903 		 * 2.6.37-rc1:fs/reiserfs/journal.o
904 		 * If there is a function definition without parameter name found
905 		 * after a function implementation then it causes a crash.
906 		 * int foo() {}
907 		 * int bar(char *);
908 		 */
909 		if (arg->ident->name < (char *)100)
910 			continue;
911 		if (i == param) {
912 			*name = arg->ident->name;
913 			*sym = arg;
914 			return TRUE;
915 		}
916 		i++;
917 	} END_FOR_EACH_PTR(arg);
918 
919 	return FALSE;
920 }
921 
922 static int function_signature_matches(const char *sig)
923 {
924 	char *my_sig;
925 
926 	my_sig = function_signature();
927 	if (!sig || !my_sig)
928 		return 1;  /* default to matching */
929 	if (strcmp(my_sig, sig) == 0)
930 		  return 1;
931 	return 0;
932 }
933 
934 static int caller_info_callback(void *_data, int argc, char **argv, char **azColName)
935 {
936 	struct select_caller_info_data *data = _data;
937 	int func_id;
938 	long type;
939 	long param;
940 	char *key;
941 	char *value;
942 	char *name = NULL;
943 	struct symbol *sym = NULL;
944 	struct def_callback *def_callback;
945 	struct stree *stree;
946 	struct timeval cur_time;
947 
948 	data->results = 1;
949 
950 	if (argc != 5)
951 		return 0;
952 
953 	gettimeofday(&cur_time, NULL);
954 	if (cur_time.tv_sec - data->start_time.tv_sec > 10)
955 		return 0;
956 
957 	func_id = atoi(argv[0]);
958 	errno = 0;
959 	type = strtol(argv[1], NULL, 10);
960 	param = strtol(argv[2], NULL, 10);
961 	if (errno)
962 		return 0;
963 	key = argv[3];
964 	value = argv[4];
965 
966 	if (data->prev_func_id == -1)
967 		data->prev_func_id = func_id;
968 	if (func_id != data->prev_func_id) {
969 		stree = __pop_fake_cur_stree();
970 		if (!data->ignore)
971 			merge_stree(&data->final_states, stree);
972 		free_stree(&stree);
973 		__push_fake_cur_stree();
974 		__unnullify_path();
975 		data->prev_func_id = func_id;
976 		data->ignore = 0;
977 	}
978 
979 	if (data->ignore)
980 		return 0;
981 	if (type == INTERNAL &&
982 	    !function_signature_matches(value)) {
983 		data->ignore = 1;
984 		return 0;
985 	}
986 
987 	if (param >= 0 && !get_param(param, &name, &sym))
988 		return 0;
989 
990 	FOR_EACH_PTR(select_caller_info_callbacks, def_callback) {
991 		if (def_callback->hook_type == type)
992 			def_callback->callback(name, sym, key, value);
993 	} END_FOR_EACH_PTR(def_callback);
994 
995 	return 0;
996 }
997 
998 static struct string_list *ptr_names_done;
999 static struct string_list *ptr_names;
1000 
1001 static int get_ptr_name(void *unused, int argc, char **argv, char **azColName)
1002 {
1003 	insert_string(&ptr_names, alloc_string(argv[0]));
1004 	return 0;
1005 }
1006 
1007 static char *get_next_ptr_name(void)
1008 {
1009 	char *ptr;
1010 
1011 	FOR_EACH_PTR(ptr_names, ptr) {
1012 		if (list_has_string(ptr_names_done, ptr))
1013 			continue;
1014 		insert_string(&ptr_names_done, ptr);
1015 		return ptr;
1016 	} END_FOR_EACH_PTR(ptr);
1017 	return NULL;
1018 }
1019 
1020 static void get_ptr_names(const char *file, const char *name)
1021 {
1022 	char sql_filter[1024];
1023 	int before, after;
1024 
1025 	if (file) {
1026 		snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
1027 			 file, name);
1028 	} else {
1029 		snprintf(sql_filter, 1024, "function = '%s';", name);
1030 	}
1031 
1032 	before = ptr_list_size((struct ptr_list *)ptr_names);
1033 
1034 	run_sql(get_ptr_name, NULL,
1035 		"select distinct ptr from function_ptr where %s",
1036 		sql_filter);
1037 
1038 	after = ptr_list_size((struct ptr_list *)ptr_names);
1039 	if (before == after)
1040 		return;
1041 
1042 	while ((name = get_next_ptr_name()))
1043 		get_ptr_names(NULL, name);
1044 }
1045 
1046 static void match_data_from_db(struct symbol *sym)
1047 {
1048 	struct select_caller_info_data data = { .prev_func_id = -1 };
1049 	struct sm_state *sm;
1050 	struct stree *stree;
1051 	struct timeval end_time;
1052 
1053 	if (!sym || !sym->ident)
1054 		return;
1055 
1056 	gettimeofday(&data.start_time, NULL);
1057 
1058 	__push_fake_cur_stree();
1059 	__unnullify_path();
1060 
1061 	if (!__inline_fn) {
1062 		char *ptr;
1063 
1064 		if (sym->ctype.modifiers & MOD_STATIC)
1065 			get_ptr_names(get_base_file(), sym->ident->name);
1066 		else
1067 			get_ptr_names(NULL, sym->ident->name);
1068 
1069 		if (ptr_list_size((struct ptr_list *)ptr_names) > 20) {
1070 			__free_ptr_list((struct ptr_list **)&ptr_names);
1071 			__free_ptr_list((struct ptr_list **)&ptr_names_done);
1072 			stree = __pop_fake_cur_stree();
1073 			free_stree(&stree);
1074 			return;
1075 		}
1076 
1077 		sql_select_caller_info(&data,
1078 				       "call_id, type, parameter, key, value",
1079 				       sym);
1080 
1081 
1082 		stree = __pop_fake_cur_stree();
1083 		if (!data.ignore)
1084 			merge_stree(&data.final_states, stree);
1085 		free_stree(&stree);
1086 		__push_fake_cur_stree();
1087 		__unnullify_path();
1088 		data.prev_func_id = -1;
1089 		data.ignore = 0;
1090 
1091 		FOR_EACH_PTR(ptr_names, ptr) {
1092 			run_sql(caller_info_callback, &data,
1093 				"select call_id, type, parameter, key, value"
1094 				" from common_caller_info where function = '%s' order by call_id",
1095 				ptr);
1096 		} END_FOR_EACH_PTR(ptr);
1097 
1098 		if (data.results) {
1099 			FOR_EACH_PTR(ptr_names, ptr) {
1100 				free_string(ptr);
1101 			} END_FOR_EACH_PTR(ptr);
1102 			goto free_ptr_names;
1103 		}
1104 
1105 		FOR_EACH_PTR(ptr_names, ptr) {
1106 			run_sql(caller_info_callback, &data,
1107 				"select call_id, type, parameter, key, value"
1108 				" from caller_info where function = '%s' order by call_id",
1109 				ptr);
1110 			free_string(ptr);
1111 		} END_FOR_EACH_PTR(ptr);
1112 
1113 free_ptr_names:
1114 		__free_ptr_list((struct ptr_list **)&ptr_names);
1115 		__free_ptr_list((struct ptr_list **)&ptr_names_done);
1116 	} else {
1117 		sql_select_caller_info(&data,
1118 				       "call_id, type, parameter, key, value",
1119 				       sym);
1120 	}
1121 
1122 	stree = __pop_fake_cur_stree();
1123 	if (!data.ignore)
1124 		merge_stree(&data.final_states, stree);
1125 	free_stree(&stree);
1126 
1127 	gettimeofday(&end_time, NULL);
1128 	if (end_time.tv_sec - data.start_time.tv_sec <= 10) {
1129 		FOR_EACH_SM(data.final_states, sm) {
1130 			__set_sm(sm);
1131 		} END_FOR_EACH_SM(sm);
1132 	}
1133 
1134 	free_stree(&data.final_states);
1135 }
1136 
1137 static int return_implies_callbacks(void *_info, int argc, char **argv, char **azColName)
1138 {
1139 	struct implies_info *info = _info;
1140 	struct db_implies_callback *cb;
1141 	struct expression *arg = NULL;
1142 	int type;
1143 	int param;
1144 
1145 	if (argc != 5)
1146 		return 0;
1147 
1148 	type = atoi(argv[1]);
1149 	param = atoi(argv[2]);
1150 
1151 	FOR_EACH_PTR(info->cb_list, cb) {
1152 		if (cb->type != type)
1153 			continue;
1154 		if (param != -1) {
1155 			arg = get_argument_from_call_expr(info->expr->args, param);
1156 			if (!arg)
1157 				continue;
1158 		}
1159 		cb->callback(info->expr, arg, argv[3], argv[4]);
1160 	} END_FOR_EACH_PTR(cb);
1161 
1162 	return 0;
1163 }
1164 
1165 static int call_implies_callbacks(void *_info, int argc, char **argv, char **azColName)
1166 {
1167 	struct implies_info *info = _info;
1168 	struct db_implies_callback *cb;
1169 	struct expression *arg;
1170 	struct symbol *sym;
1171 	char *name;
1172 	int type;
1173 	int param;
1174 
1175 	if (argc != 5)
1176 		return 0;
1177 
1178 	type = atoi(argv[1]);
1179 	param = atoi(argv[2]);
1180 
1181 	if (!get_param(param, &name, &sym))
1182 		return 0;
1183 	arg = symbol_expression(sym);
1184 	if (!arg)
1185 		return 0;
1186 
1187 	FOR_EACH_PTR(info->cb_list, cb) {
1188 		if (cb->type != type)
1189 			continue;
1190 		cb->callback(info->expr, arg, argv[3], argv[4]);
1191 	} END_FOR_EACH_PTR(cb);
1192 
1193 	return 0;
1194 }
1195 
1196 static void match_return_implies(struct expression *expr)
1197 {
1198 	struct implies_info info = {
1199 		.type = RETURN_IMPLIES,
1200 		.cb_list = return_implies_cb_list,
1201 	};
1202 
1203 	if (expr->fn->type != EXPR_SYMBOL ||
1204 	    !expr->fn->symbol)
1205 		return;
1206 	info.expr = expr;
1207 	info.sym = expr->fn->symbol;
1208 	sql_select_implies("function, type, parameter, key, value", &info,
1209 			   return_implies_callbacks);
1210 }
1211 
1212 static void match_call_implies(struct symbol *sym)
1213 {
1214 	struct implies_info info = {
1215 		.type = CALL_IMPLIES,
1216 		.cb_list = call_implies_cb_list,
1217 	};
1218 
1219 	if (!sym || !sym->ident)
1220 		return;
1221 
1222 	info.sym = sym;
1223 	sql_select_implies("function, type, parameter, key, value", &info,
1224 			   call_implies_callbacks);
1225 }
1226 
1227 static void print_initializer_list(struct expression_list *expr_list,
1228 		struct symbol *struct_type)
1229 {
1230 	struct expression *expr;
1231 	struct symbol *base_type;
1232 	char struct_name[256];
1233 
1234 	FOR_EACH_PTR(expr_list, expr) {
1235 		if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
1236 			print_initializer_list(expr->idx_expression->expr_list, struct_type);
1237 			continue;
1238 		}
1239 		if (expr->type != EXPR_IDENTIFIER)
1240 			continue;
1241 		if (!expr->expr_ident)
1242 			continue;
1243 		if (!expr->ident_expression || !expr->ident_expression->symbol_name)
1244 			continue;
1245 		base_type = get_type(expr->ident_expression);
1246 		if (!base_type || base_type->type != SYM_FN)
1247 			continue;
1248 		snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
1249 			 struct_type->ident->name, expr->expr_ident->name);
1250 		sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
1251 				        struct_name);
1252 	} END_FOR_EACH_PTR(expr);
1253 }
1254 
1255 static void global_variable(struct symbol *sym)
1256 {
1257 	struct symbol *struct_type;
1258 
1259 	if (!sym->ident)
1260 		return;
1261 	if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
1262 		return;
1263 	struct_type = get_base_type(sym);
1264 	if (!struct_type)
1265 		return;
1266 	if (struct_type->type == SYM_ARRAY) {
1267 		struct_type = get_base_type(struct_type);
1268 		if (!struct_type)
1269 			return;
1270 	}
1271 	if (struct_type->type != SYM_STRUCT || !struct_type->ident)
1272 		return;
1273 	print_initializer_list(sym->initializer->expr_list, struct_type);
1274 }
1275 
1276 static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1277 {
1278 	sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1279 }
1280 
1281 static void call_return_state_hooks_conditional(struct expression *expr)
1282 {
1283 	struct returned_state_callback *cb;
1284 	struct range_list *rl;
1285 	char *return_ranges;
1286 	int final_pass_orig = final_pass;
1287 
1288 	__push_fake_cur_stree();
1289 
1290 	final_pass = 0;
1291 	__split_whole_condition(expr->conditional);
1292 	final_pass = final_pass_orig;
1293 
1294 	if (get_implied_rl(expr->cond_true, &rl))
1295 		rl = cast_rl(cur_func_return_type(), rl);
1296 	else
1297 		rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_true)));
1298 	return_ranges = show_rl(rl);
1299 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1300 
1301 	return_id++;
1302 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1303 		cb->callback(return_id, return_ranges, expr->cond_true);
1304 	} END_FOR_EACH_PTR(cb);
1305 
1306 	__push_true_states();
1307 	__use_false_states();
1308 
1309 	if (get_implied_rl(expr->cond_false, &rl))
1310 		rl = cast_rl(cur_func_return_type(), rl);
1311 	else
1312 		rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_false)));
1313 	return_ranges = show_rl(rl);
1314 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1315 
1316 	return_id++;
1317 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1318 		cb->callback(return_id, return_ranges, expr->cond_false);
1319 	} END_FOR_EACH_PTR(cb);
1320 
1321 	__merge_true_states();
1322 	__free_fake_cur_stree();
1323 }
1324 
1325 static void call_return_state_hooks_compare(struct expression *expr)
1326 {
1327 	struct returned_state_callback *cb;
1328 	char *return_ranges;
1329 	int final_pass_orig = final_pass;
1330 	sval_t sval = { .type = &int_ctype };
1331 	sval_t ret;
1332 
1333 	if (!get_implied_value(expr, &ret))
1334 		ret.value = -1;
1335 
1336 	__push_fake_cur_stree();
1337 
1338 	final_pass = 0;
1339 	__split_whole_condition(expr);
1340 	final_pass = final_pass_orig;
1341 
1342 	if (ret.value != 0) {
1343 		return_ranges = alloc_sname("1");
1344 		sval.value = 1;
1345 		set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_sval(sval));
1346 
1347 		return_id++;
1348 		FOR_EACH_PTR(returned_state_callbacks, cb) {
1349 			cb->callback(return_id, return_ranges, expr);
1350 		} END_FOR_EACH_PTR(cb);
1351 	}
1352 
1353 	__push_true_states();
1354 	__use_false_states();
1355 
1356 	if (ret.value != 1) {
1357 		return_ranges = alloc_sname("0");
1358 		sval.value = 0;
1359 		set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_sval(sval));
1360 
1361 		return_id++;
1362 		FOR_EACH_PTR(returned_state_callbacks, cb) {
1363 			cb->callback(return_id, return_ranges, expr);
1364 		} END_FOR_EACH_PTR(cb);
1365 	}
1366 
1367 	__merge_true_states();
1368 	__free_fake_cur_stree();
1369 }
1370 
1371 static int ptr_in_list(struct sm_state *sm, struct state_list *slist)
1372 {
1373 	struct sm_state *tmp;
1374 
1375 	FOR_EACH_PTR(slist, tmp) {
1376 		if (strcmp(tmp->state->name, sm->state->name) == 0)
1377 			return 1;
1378 	} END_FOR_EACH_PTR(tmp);
1379 
1380 	return 0;
1381 }
1382 
1383 static char *get_return_compare_str(struct expression *expr)
1384 {
1385 	char *compare_str;
1386 	char *var;
1387 	char buf[256];
1388 	int comparison;
1389 	int param;
1390 
1391 	compare_str = expr_lte_to_param(expr, -1);
1392 	if (compare_str)
1393 		return compare_str;
1394 	param = get_param_num(expr);
1395 	if (param < 0)
1396 		return NULL;
1397 
1398 	var = expr_to_var(expr);
1399 	if (!var)
1400 		return NULL;
1401 	snprintf(buf, sizeof(buf), "%s orig", var);
1402 	comparison = get_comparison_strings(var, buf);
1403 	free_string(var);
1404 
1405 	if (!comparison)
1406 		return NULL;
1407 
1408 	snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
1409 	return alloc_sname(buf);
1410 }
1411 
1412 static int split_possible_helper(struct sm_state *sm, struct expression *expr)
1413 {
1414 	struct returned_state_callback *cb;
1415 	struct range_list *rl;
1416 	char *return_ranges;
1417 	struct sm_state *tmp;
1418 	int ret = 0;
1419 	int nr_possible, nr_states;
1420 	char *compare_str = NULL;
1421 	char buf[128];
1422 	struct state_list *already_handled = NULL;
1423 
1424 	if (!sm || !sm->merged)
1425 		return 0;
1426 
1427 	if (too_many_possible(sm))
1428 		return 0;
1429 
1430 	/* bail if it gets too complicated */
1431 	nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
1432 	nr_states = get_db_state_count();
1433 	if (nr_states * nr_possible >= 2000)
1434 		return 0;
1435 
1436 	FOR_EACH_PTR(sm->possible, tmp) {
1437 		if (tmp->merged)
1438 			continue;
1439 		if (ptr_in_list(tmp, already_handled))
1440 			continue;
1441 		add_ptr_list(&already_handled, tmp);
1442 
1443 		ret = 1;
1444 		__push_fake_cur_stree();
1445 
1446 		overwrite_states_using_pool(sm, tmp);
1447 
1448 		rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
1449 		return_ranges = show_rl(rl);
1450 		set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));
1451 		compare_str = get_return_compare_str(expr);
1452 		if (compare_str) {
1453 			snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1454 			return_ranges = alloc_sname(buf);
1455 		}
1456 
1457 		return_id++;
1458 		FOR_EACH_PTR(returned_state_callbacks, cb) {
1459 			cb->callback(return_id, return_ranges, expr);
1460 		} END_FOR_EACH_PTR(cb);
1461 
1462 		__free_fake_cur_stree();
1463 	} END_FOR_EACH_PTR(tmp);
1464 
1465 	free_slist(&already_handled);
1466 
1467 	return ret;
1468 }
1469 
1470 static int call_return_state_hooks_split_possible(struct expression *expr)
1471 {
1472 	struct sm_state *sm;
1473 
1474 	if (!expr || expr_equal_to_param(expr, -1))
1475 		return 0;
1476 
1477 	sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1478 	return split_possible_helper(sm, expr);
1479 }
1480 
1481 static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
1482 {
1483 	struct range_list *rl;
1484 	char *return_ranges;
1485 	sval_t sval;
1486 	char *compare_str;
1487 	char *math_str;
1488 	char buf[128];
1489 
1490 	*rl_p = NULL;
1491 
1492 	if (!expr)
1493 		return alloc_sname("");
1494 
1495 	if (get_implied_value(expr, &sval)) {
1496 		sval = sval_cast(cur_func_return_type(), sval);
1497 		*rl_p = alloc_rl(sval, sval);
1498 		return sval_to_str(sval);
1499 	}
1500 
1501 	compare_str = expr_equal_to_param(expr, -1);
1502 	math_str = get_value_in_terms_of_parameter_math(expr);
1503 
1504 	if (get_implied_rl(expr, &rl)) {
1505 		rl = cast_rl(cur_func_return_type(), rl);
1506 		return_ranges = show_rl(rl);
1507 	} else if (get_imaginary_absolute(expr, &rl)){
1508 		rl = cast_rl(cur_func_return_type(), rl);
1509 		return alloc_sname(show_rl(rl));
1510 	} else {
1511 		rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr)));
1512 		return_ranges = show_rl(rl);
1513 	}
1514 	*rl_p = rl;
1515 
1516 	if (compare_str) {
1517 		snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1518 		return alloc_sname(buf);
1519 	}
1520 	if (math_str) {
1521 		snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
1522 		return alloc_sname(buf);
1523 	}
1524 	compare_str = get_return_compare_str(expr);
1525 	if (compare_str) {
1526 		snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1527 		return alloc_sname(buf);
1528 	}
1529 
1530 	return return_ranges;
1531 }
1532 
1533 static bool has_possible_negative(struct sm_state *sm)
1534 {
1535 	struct sm_state *tmp;
1536 
1537 	FOR_EACH_PTR(sm->possible, tmp) {
1538 		if (!estate_rl(tmp->state))
1539 			continue;
1540 		if (sval_is_negative(estate_min(tmp->state)) &&
1541 		    sval_is_negative(estate_max(tmp->state)))
1542 			return true;
1543 	} END_FOR_EACH_PTR(tmp);
1544 
1545 	return false;
1546 }
1547 
1548 static bool has_possible_zero_null(struct sm_state *sm)
1549 {
1550 	struct sm_state *tmp;
1551 	sval_t sval;
1552 
1553 	FOR_EACH_PTR(sm->possible, tmp) {
1554 		if (!estate_get_single_value(tmp->state, &sval))
1555 			continue;
1556 		if (sval.value == 0)
1557 			return true;
1558 	} END_FOR_EACH_PTR(tmp);
1559 
1560 	return false;
1561 }
1562 
1563 static int split_positive_from_negative(struct expression *expr)
1564 {
1565 	struct sm_state *sm;
1566 	struct returned_state_callback *cb;
1567 	struct range_list *rl;
1568 	const char *return_ranges;
1569 	struct range_list *ret_rl;
1570 	int undo;
1571 
1572 	/* We're going to print the states 3 times */
1573 	if (get_db_state_count() > 10000 / 3)
1574 		return 0;
1575 
1576 	if (!get_implied_rl(expr, &rl) || !rl)
1577 		return 0;
1578 	if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1579 		return 0;
1580 	/* Forget about INT_MAX and larger */
1581 	if (rl_max(rl).value <= 0)
1582 		return 0;
1583 	if (!sval_is_negative(rl_min(rl)))
1584 		return 0;
1585 
1586 	sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1587 	if (!sm)
1588 		return 0;
1589 	if (!has_possible_negative(sm))
1590 		return 0;
1591 
1592 	if (!assume(compare_expression(expr, '>', zero_expr())))
1593 		return 0;
1594 
1595 	return_id++;
1596 	return_ranges = get_return_ranges_str(expr, &ret_rl);
1597 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1598 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1599 		cb->callback(return_id, (char *)return_ranges, expr);
1600 	} END_FOR_EACH_PTR(cb);
1601 
1602 	end_assume();
1603 
1604 	if (rl_has_sval(rl, sval_type_val(rl_type(rl), 0))) {
1605 		undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1606 
1607 		return_id++;
1608 		return_ranges = get_return_ranges_str(expr, &ret_rl);
1609 		set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1610 		FOR_EACH_PTR(returned_state_callbacks, cb) {
1611 			cb->callback(return_id, (char *)return_ranges, expr);
1612 		} END_FOR_EACH_PTR(cb);
1613 
1614 		if (undo)
1615 			end_assume();
1616 	}
1617 
1618 	undo = assume(compare_expression(expr, '<', zero_expr()));
1619 
1620 	return_id++;
1621 	return_ranges = get_return_ranges_str(expr, &ret_rl);
1622 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1623 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1624 		cb->callback(return_id, (char *)return_ranges, expr);
1625 	} END_FOR_EACH_PTR(cb);
1626 
1627 	if (undo)
1628 		end_assume();
1629 
1630 	return 1;
1631 }
1632 
1633 static int call_return_state_hooks_split_null_non_null(struct expression *expr)
1634 {
1635 	struct returned_state_callback *cb;
1636 	struct range_list *rl;
1637 	struct range_list *nonnull_rl;
1638 	sval_t null_sval;
1639 	struct range_list *null_rl = NULL;
1640 	char *return_ranges;
1641 	struct sm_state *sm;
1642 	struct smatch_state *state;
1643 	int nr_states;
1644 	int final_pass_orig = final_pass;
1645 
1646 	if (!expr || expr_equal_to_param(expr, -1))
1647 		return 0;
1648 	if (expr->type == EXPR_CALL)
1649 		return 0;
1650 	if (!is_pointer(expr))
1651 		return 0;
1652 
1653 	sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1654 	if (!sm)
1655 		return 0;
1656 	if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1657 		return 0;
1658 	state = sm->state;
1659 	if (!estate_rl(state))
1660 		return 0;
1661 	if (estate_min(state).value == 0 && estate_max(state).value == 0)
1662 		return 0;
1663 	if (!has_possible_zero_null(sm))
1664 		return 0;
1665 
1666 	nr_states = get_db_state_count();
1667 	if (option_info && nr_states >= 1500)
1668 		return 0;
1669 
1670 	rl = estate_rl(state);
1671 
1672 	__push_fake_cur_stree();
1673 
1674 	final_pass = 0;
1675 	__split_whole_condition(expr);
1676 	final_pass = final_pass_orig;
1677 
1678 	nonnull_rl = rl_filter(rl, rl_zero());
1679 	return_ranges = show_rl(nonnull_rl);
1680 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(nonnull_rl));
1681 
1682 	return_id++;
1683 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1684 		cb->callback(return_id, return_ranges, expr);
1685 	} END_FOR_EACH_PTR(cb);
1686 
1687 	__push_true_states();
1688 	__use_false_states();
1689 
1690 	return_ranges = alloc_sname("0");
1691 	null_sval = sval_type_val(rl_type(rl), 0);
1692 	add_range(&null_rl, null_sval, null_sval);
1693 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(null_rl));
1694 	return_id++;
1695 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1696 		cb->callback(return_id, return_ranges, expr);
1697 	} END_FOR_EACH_PTR(cb);
1698 
1699 	__merge_true_states();
1700 	__free_fake_cur_stree();
1701 
1702 	return 1;
1703 }
1704 
1705 static int call_return_state_hooks_split_success_fail(struct expression *expr)
1706 {
1707 	struct sm_state *sm;
1708 	struct range_list *rl;
1709 	struct range_list *nonzero_rl;
1710 	sval_t zero_sval;
1711 	struct range_list *zero_rl = NULL;
1712 	int nr_states;
1713 	struct returned_state_callback *cb;
1714 	char *return_ranges;
1715 	int final_pass_orig = final_pass;
1716 
1717 	if (option_project != PROJ_KERNEL)
1718 		return 0;
1719 
1720 	nr_states = get_db_state_count();
1721 	if (nr_states > 1500)
1722 		return 0;
1723 
1724 	sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1725 	if (!sm)
1726 		return 0;
1727 	if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1728 		return 0;
1729 
1730 	rl = estate_rl(sm->state);
1731 	if (!rl)
1732 		return 0;
1733 
1734 	if (rl_min(rl).value < -4095 || rl_min(rl).value >= 0)
1735 		return 0;
1736 	if (rl_max(rl).value != 0)
1737 		return 0;
1738 	if (!has_possible_zero_null(sm))
1739 		return 0;
1740 
1741 	__push_fake_cur_stree();
1742 
1743 	final_pass = 0;
1744 	__split_whole_condition(expr);
1745 	final_pass = final_pass_orig;
1746 
1747 	nonzero_rl = rl_filter(rl, rl_zero());
1748 	nonzero_rl = cast_rl(cur_func_return_type(), nonzero_rl);
1749 	return_ranges = show_rl(nonzero_rl);
1750 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(nonzero_rl));
1751 
1752 	return_id++;
1753 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1754 		cb->callback(return_id, return_ranges, expr);
1755 	} END_FOR_EACH_PTR(cb);
1756 
1757 	__push_true_states();
1758 	__use_false_states();
1759 
1760 	return_ranges = alloc_sname("0");
1761 	zero_sval = sval_type_val(rl_type(rl), 0);
1762 	add_range(&zero_rl, zero_sval, zero_sval);
1763 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(zero_rl));
1764 	return_id++;
1765 	FOR_EACH_PTR(returned_state_callbacks, cb) {
1766 		cb->callback(return_id, return_ranges, expr);
1767 	} END_FOR_EACH_PTR(cb);
1768 
1769 	__merge_true_states();
1770 	__free_fake_cur_stree();
1771 
1772 	return 1;
1773 }
1774 
1775 static int is_boolean(struct expression *expr)
1776 {
1777 	struct range_list *rl;
1778 
1779 	if (!get_implied_rl(expr, &rl))
1780 		return 0;
1781 	if (rl_min(rl).value == 0 && rl_max(rl).value == 1)
1782 		return 1;
1783 	return 0;
1784 }
1785 
1786 static int is_conditional(struct expression *expr)
1787 {
1788 	if (!expr)
1789 		return 0;
1790 	if (expr->type == EXPR_CONDITIONAL || expr->type == EXPR_SELECT)
1791 		return 1;
1792 	return 0;
1793 }
1794 
1795 static int splitable_function_call(struct expression *expr)
1796 {
1797 	struct sm_state *sm;
1798 	char buf[64];
1799 
1800 	if (!expr || expr->type != EXPR_CALL)
1801 		return 0;
1802 	snprintf(buf, sizeof(buf), "return %p", expr);
1803 	sm = get_sm_state(SMATCH_EXTRA, buf, NULL);
1804 	return split_possible_helper(sm, expr);
1805 }
1806 
1807 static struct sm_state *find_bool_param(void)
1808 {
1809 	struct stree *start_states;
1810 	struct symbol *arg;
1811 	struct sm_state *sm, *tmp;
1812 	sval_t sval;
1813 
1814 	start_states = get_start_states();
1815 
1816 	FOR_EACH_PTR_REVERSE(cur_func_sym->ctype.base_type->arguments, arg) {
1817 		if (!arg->ident)
1818 			continue;
1819 		sm = get_sm_state_stree(start_states, SMATCH_EXTRA, arg->ident->name, arg);
1820 		if (!sm)
1821 			continue;
1822 		if (rl_min(estate_rl(sm->state)).value != 0 ||
1823 		    rl_max(estate_rl(sm->state)).value != 1)
1824 			continue;
1825 		goto found;
1826 	} END_FOR_EACH_PTR_REVERSE(arg);
1827 
1828 	return NULL;
1829 
1830 found:
1831 	/*
1832 	 * Check if it's splitable.  If not, then splitting it up is likely not
1833 	 * useful for the callers.
1834 	 */
1835 	FOR_EACH_PTR(sm->possible, tmp) {
1836 		if (is_merged(tmp))
1837 			continue;
1838 		if (!estate_get_single_value(tmp->state, &sval))
1839 			return NULL;
1840 	} END_FOR_EACH_PTR(tmp);
1841 
1842 	return sm;
1843 }
1844 
1845 static int split_on_bool_sm(struct sm_state *sm, struct expression *expr)
1846 {
1847 	struct returned_state_callback *cb;
1848 	struct range_list *ret_rl;
1849 	const char *return_ranges;
1850 	struct sm_state *tmp;
1851 	int ret = 0;
1852 	int nr_possible, nr_states;
1853 	char *compare_str = NULL;
1854 	char buf[128];
1855 	struct state_list *already_handled = NULL;
1856 
1857 	if (!sm || !sm->merged)
1858 		return 0;
1859 
1860 	if (too_many_possible(sm))
1861 		return 0;
1862 
1863 	/* bail if it gets too complicated */
1864 	nr_possible = ptr_list_size((struct ptr_list *)sm->possible);
1865 	nr_states = get_db_state_count();
1866 	if (nr_states * nr_possible >= 2000)
1867 		return 0;
1868 
1869 	FOR_EACH_PTR(sm->possible, tmp) {
1870 		if (tmp->merged)
1871 			continue;
1872 		if (ptr_in_list(tmp, already_handled))
1873 			continue;
1874 		add_ptr_list(&already_handled, tmp);
1875 
1876 		ret = 1;
1877 		__push_fake_cur_stree();
1878 
1879 		overwrite_states_using_pool(sm, tmp);
1880 
1881 		return_ranges = get_return_ranges_str(expr, &ret_rl);
1882 		set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1883 		compare_str = get_return_compare_str(expr);
1884 		if (compare_str) {
1885 			snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1886 			return_ranges = alloc_sname(buf);
1887 		}
1888 
1889 		return_id++;
1890 		FOR_EACH_PTR(returned_state_callbacks, cb) {
1891 			cb->callback(return_id, (char *)return_ranges, expr);
1892 		} END_FOR_EACH_PTR(cb);
1893 
1894 		__free_fake_cur_stree();
1895 	} END_FOR_EACH_PTR(tmp);
1896 
1897 	free_slist(&already_handled);
1898 
1899 	return ret;
1900 }
1901 
1902 static int split_by_bool_param(struct expression *expr)
1903 {
1904 	struct sm_state *start_sm, *sm;
1905 	sval_t sval;
1906 
1907 	start_sm = find_bool_param();
1908 	if (!start_sm)
1909 		return 0;
1910 	sm = get_sm_state(SMATCH_EXTRA, start_sm->name, start_sm->sym);
1911 	if (!sm || estate_get_single_value(sm->state, &sval))
1912 		return 0;
1913 	return split_on_bool_sm(sm, expr);
1914 }
1915 
1916 static int split_by_null_nonnull_param(struct expression *expr)
1917 {
1918 	struct symbol *arg;
1919 	struct sm_state *sm;
1920 	sval_t zero = {
1921 		.type = &ulong_ctype,
1922 	};
1923 
1924 	/* function must only take one pointer */
1925 	if (ptr_list_size((struct ptr_list *)cur_func_sym->ctype.base_type->arguments) != 1)
1926 		return 0;
1927 	arg = first_ptr_list((struct ptr_list *)cur_func_sym->ctype.base_type->arguments);
1928 	if (!arg->ident)
1929 		return 0;
1930 	if (get_real_base_type(arg)->type != SYM_PTR)
1931 		return 0;
1932 
1933 	if (param_was_set_var_sym(arg->ident->name, arg))
1934 		return 0;
1935 	sm = get_sm_state(SMATCH_EXTRA, arg->ident->name, arg);
1936 	if (!sm)
1937 		return 0;
1938 
1939 	if (!rl_has_sval(estate_rl(sm->state), zero))
1940 		return 0;
1941 
1942 	return split_on_bool_sm(sm, expr);
1943 }
1944 
1945 struct expression *strip_expr_statement(struct expression *expr)
1946 {
1947 	struct expression *orig = expr;
1948 	struct statement *stmt, *last_stmt;
1949 
1950 	if (!expr)
1951 		return NULL;
1952 	if (expr->type == EXPR_PREOP && expr->op == '(')
1953 		expr = expr->unop;
1954 	if (expr->type != EXPR_STATEMENT)
1955 		return orig;
1956 	stmt = expr->statement;
1957 	if (!stmt || stmt->type != STMT_COMPOUND)
1958 		return orig;
1959 
1960 	last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1961 	if (!last_stmt || last_stmt->type == STMT_LABEL)
1962 		last_stmt = last_stmt->label_statement;
1963 	if (!last_stmt || last_stmt->type != STMT_EXPRESSION)
1964 		return orig;
1965 	return strip_expr(last_stmt->expression);
1966 }
1967 
1968 static void call_return_state_hooks(struct expression *expr)
1969 {
1970 	struct returned_state_callback *cb;
1971 	struct range_list *ret_rl;
1972 	const char *return_ranges;
1973 	int nr_states;
1974 	sval_t sval;
1975 
1976 	if (__path_is_null())
1977 		return;
1978 
1979 	expr = strip_expr(expr);
1980 	expr = strip_expr_statement(expr);
1981 
1982 	if (is_impossible_path())
1983 		goto vanilla;
1984 
1985 	if (expr && (expr->type == EXPR_COMPARE ||
1986 		     !get_implied_value(expr, &sval)) &&
1987 	    (is_condition(expr) || is_boolean(expr))) {
1988 		call_return_state_hooks_compare(expr);
1989 		return;
1990 	} else if (is_conditional(expr)) {
1991 		call_return_state_hooks_conditional(expr);
1992 		return;
1993 	} else if (call_return_state_hooks_split_possible(expr)) {
1994 		return;
1995 	} else if (call_return_state_hooks_split_null_non_null(expr)) {
1996 		return;
1997 	} else if (call_return_state_hooks_split_success_fail(expr)) {
1998 		return;
1999 	} else if (splitable_function_call(expr)) {
2000 		return;
2001 	} else if (split_positive_from_negative(expr)) {
2002 		return;
2003 	} else if (split_by_bool_param(expr)) {
2004 	} else if (split_by_null_nonnull_param(expr)) {
2005 		return;
2006 	}
2007 
2008 vanilla:
2009 	return_ranges = get_return_ranges_str(expr, &ret_rl);
2010 	set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
2011 
2012 	return_id++;
2013 	nr_states = get_db_state_count();
2014 	if (nr_states >= 10000) {
2015 		match_return_info(return_id, (char *)return_ranges, expr);
2016 		mark_all_params_untracked(return_id, (char *)return_ranges, expr);
2017 		return;
2018 	}
2019 	FOR_EACH_PTR(returned_state_callbacks, cb) {
2020 		cb->callback(return_id, (char *)return_ranges, expr);
2021 	} END_FOR_EACH_PTR(cb);
2022 }
2023 
2024 static void print_returned_struct_members(int return_id, char *return_ranges, struct expression *expr)
2025 {
2026 	struct returned_member_callback *cb;
2027 	struct stree *stree;
2028 	struct sm_state *sm;
2029 	struct symbol *type;
2030 	char *name;
2031 	char member_name[256];
2032 	int len;
2033 
2034 	type = get_type(expr);
2035 	if (!type || type->type != SYM_PTR)
2036 		return;
2037 	name = expr_to_var(expr);
2038 	if (!name)
2039 		return;
2040 
2041 	member_name[sizeof(member_name) - 1] = '\0';
2042 	strcpy(member_name, "$");
2043 
2044 	len = strlen(name);
2045 	FOR_EACH_PTR(returned_member_callbacks, cb) {
2046 		stree = __get_cur_stree();
2047 		FOR_EACH_MY_SM(cb->owner, stree, sm) {
2048 			if (sm->name[0] == '*' && strcmp(sm->name + 1, name) == 0) {
2049 				strcpy(member_name, "*$");
2050 				cb->callback(return_id, return_ranges, expr, member_name, sm->state);
2051 				continue;
2052 			}
2053 			if (strncmp(sm->name, name, len) != 0)
2054 				continue;
2055 			if (strncmp(sm->name + len, "->", 2) != 0)
2056 				continue;
2057 			snprintf(member_name, sizeof(member_name), "$%s", sm->name + len);
2058 			cb->callback(return_id, return_ranges, expr, member_name, sm->state);
2059 		} END_FOR_EACH_SM(sm);
2060 	} END_FOR_EACH_PTR(cb);
2061 
2062 	free_string(name);
2063 }
2064 
2065 static void reset_memdb(struct symbol *sym)
2066 {
2067 	mem_sql(NULL, NULL, "delete from caller_info;");
2068 	mem_sql(NULL, NULL, "delete from return_states;");
2069 	mem_sql(NULL, NULL, "delete from call_implies;");
2070 	mem_sql(NULL, NULL, "delete from return_implies;");
2071 }
2072 
2073 static void match_end_func_info(struct symbol *sym)
2074 {
2075 	if (__path_is_null())
2076 		return;
2077 	call_return_state_hooks(NULL);
2078 }
2079 
2080 static void match_after_func(struct symbol *sym)
2081 {
2082 	if (!__inline_fn)
2083 		reset_memdb(sym);
2084 }
2085 
2086 static void init_memdb(void)
2087 {
2088 	char *err = NULL;
2089 	int rc;
2090 	const char *schema_files[] = {
2091 		"db/db.schema",
2092 		"db/caller_info.schema",
2093 		"db/common_caller_info.schema",
2094 		"db/return_states.schema",
2095 		"db/function_type_size.schema",
2096 		"db/type_size.schema",
2097 		"db/function_type_info.schema",
2098 		"db/type_info.schema",
2099 		"db/call_implies.schema",
2100 		"db/return_implies.schema",
2101 		"db/function_ptr.schema",
2102 		"db/local_values.schema",
2103 		"db/function_type_value.schema",
2104 		"db/type_value.schema",
2105 		"db/function_type.schema",
2106 		"db/data_info.schema",
2107 		"db/parameter_name.schema",
2108 		"db/constraints.schema",
2109 		"db/constraints_required.schema",
2110 		"db/fn_ptr_data_link.schema",
2111 		"db/fn_data_link.schema",
2112 		"db/mtag_about.schema",
2113 		"db/mtag_map.schema",
2114 		"db/mtag_data.schema",
2115 		"db/mtag_alias.schema",
2116 	};
2117 	static char buf[4096];
2118 	int fd;
2119 	int ret;
2120 	int i;
2121 
2122 	rc = sqlite3_open(":memory:", &mem_db);
2123 	if (rc != SQLITE_OK) {
2124 		sm_ierror("starting In-Memory database.");
2125 		return;
2126 	}
2127 
2128 	for (i = 0; i < ARRAY_SIZE(schema_files); i++) {
2129 		fd = open_schema_file(schema_files[i]);
2130 		if (fd < 0)
2131 			continue;
2132 		ret = read(fd, buf, sizeof(buf));
2133 		if (ret < 0) {
2134 			sm_ierror("failed to read: %s", schema_files[i]);
2135 			continue;
2136 		}
2137 		close(fd);
2138 		if (ret == sizeof(buf)) {
2139 			sm_ierror("Schema file too large:  %s (limit %zd bytes)",
2140 			       schema_files[i], sizeof(buf));
2141 			continue;
2142 		}
2143 		buf[ret] = '\0';
2144 		rc = sqlite3_exec(mem_db, buf, NULL, NULL, &err);
2145 		if (rc != SQLITE_OK) {
2146 			sm_ierror("SQL error #2: %s", err);
2147 			sm_ierror("%s", buf);
2148 		}
2149 	}
2150 }
2151 
2152 static void init_cachedb(void)
2153 {
2154 	char *err = NULL;
2155 	int rc;
2156 	const char *schema_files[] = {
2157 		"db/call_implies.schema",
2158 		"db/return_implies.schema",
2159 		"db/type_info.schema",
2160 		"db/mtag_data.schema",
2161 		"db/sink_info.schema",
2162 	};
2163 	static char buf[4096];
2164 	int fd;
2165 	int ret;
2166 	int i;
2167 
2168 	rc = sqlite3_open(":memory:", &cache_db);
2169 	if (rc != SQLITE_OK) {
2170 		sm_ierror("starting In-Memory database.");
2171 		return;
2172 	}
2173 
2174 	for (i = 0; i < ARRAY_SIZE(schema_files); i++) {
2175 		fd = open_schema_file(schema_files[i]);
2176 		if (fd < 0)
2177 			continue;
2178 		ret = read(fd, buf, sizeof(buf));
2179 		if (ret < 0) {
2180 			sm_ierror("failed to read: %s", schema_files[i]);
2181 			continue;
2182 		}
2183 		close(fd);
2184 		if (ret == sizeof(buf)) {
2185 			sm_ierror("Schema file too large:  %s (limit %zd bytes)",
2186 			       schema_files[i], sizeof(buf));
2187 			continue;
2188 		}
2189 		buf[ret] = '\0';
2190 		rc = sqlite3_exec(cache_db, buf, NULL, NULL, &err);
2191 		if (rc != SQLITE_OK) {
2192 			sm_ierror("SQL error #2: %s", err);
2193 			sm_ierror("%s", buf);
2194 		}
2195 	}
2196 }
2197 
2198 static int save_cache_data(void *_table, int argc, char **argv, char **azColName)
2199 {
2200 	static char buf[4096];
2201 	char tmp[256];
2202 	char *p = buf;
2203 	char *table = _table;
2204 	int i;
2205 
2206 
2207 	p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
2208 	for (i = 0; i < argc; i++) {
2209 		if (i)
2210 			p += snprintf(p, 4096 - (p - buf), ", ");
2211 		sqlite3_snprintf(sizeof(tmp), tmp, "%q", argv[i]);
2212 		p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
2213 
2214 	}
2215 	p += snprintf(p, 4096 - (p - buf), ");");
2216 	if (p - buf > 4096)
2217 		return 0;
2218 
2219 	sm_msg("SQL: %s", buf);
2220 	return 0;
2221 }
2222 
2223 static void dump_cache(struct symbol_list *sym_list)
2224 {
2225 	if (!option_info)
2226 		return;
2227 	cache_sql(&save_cache_data, (char *)"type_info", "select * from type_info;");
2228 	cache_sql(&save_cache_data, (char *)"return_implies", "select * from return_implies;");
2229 	cache_sql(&save_cache_data, (char *)"call_implies", "select * from call_implies;");
2230 	cache_sql(&save_cache_data, (char *)"mtag_data", "select * from mtag_data;");
2231 	cache_sql(&save_cache_data, (char *)"sink_info", "select * from sink_info;");
2232 }
2233 
2234 void open_smatch_db(char *db_file)
2235 {
2236 	int rc;
2237 
2238 	if (option_no_db)
2239 		return;
2240 
2241 	use_states = malloc(num_checks + 1);
2242 	memset(use_states, 0xff, num_checks + 1);
2243 
2244 	init_memdb();
2245 	init_cachedb();
2246 
2247 	rc = sqlite3_open_v2(db_file, &smatch_db, SQLITE_OPEN_READONLY, NULL);
2248 	if (rc != SQLITE_OK) {
2249 		option_no_db = 1;
2250 		return;
2251 	}
2252 	run_sql(NULL, NULL,
2253 		"PRAGMA cache_size = %d;", SQLITE_CACHE_PAGES);
2254 	return;
2255 }
2256 
2257 static void register_common_funcs(void)
2258 {
2259 	struct token *token;
2260 	char *func;
2261 	char filename[256];
2262 
2263 	if (option_project == PROJ_NONE)
2264 		strcpy(filename, "common_functions");
2265 	else
2266 		snprintf(filename, 256, "%s.common_functions", option_project_str);
2267 
2268 	token = get_tokens_file(filename);
2269 	if (!token)
2270 		return;
2271 	if (token_type(token) != TOKEN_STREAMBEGIN)
2272 		return;
2273 	token = token->next;
2274 	while (token_type(token) != TOKEN_STREAMEND) {
2275 		if (token_type(token) != TOKEN_IDENT)
2276 			return;
2277 		func = alloc_string(show_ident(token->ident));
2278 		add_ptr_list(&common_funcs, func);
2279 		token = token->next;
2280 	}
2281 	clear_token_alloc();
2282 }
2283 
2284 static char *get_next_string(char **str)
2285 {
2286 	static char string[256];
2287 	char *start;
2288 	char *p = *str;
2289 	int len;
2290 
2291 	if (*p == '\0')
2292 		return NULL;
2293 	start = p;
2294 
2295 	while (*p != '\0' && *p != ' ' && *p != '\n')
2296 		p++;
2297 
2298 	len = p - start;
2299 	if (len > 256) {
2300 		memcpy(string, start, 255);
2301 		string[255] = '\0';
2302 		sm_ierror("return_fix: '%s' too long", string);
2303 		**str = '\0';
2304 		return NULL;
2305 	}
2306 	memcpy(string, start, len);
2307 	string[len] = '\0';
2308 	if (*p != '\0')
2309 		p++;
2310 	*str = p;
2311 	return string;
2312 }
2313 
2314 static void register_return_replacements(void)
2315 {
2316 	char *func, *orig, *new;
2317 	char filename[256];
2318 	char buf[4096];
2319 	int fd, ret, i;
2320 	char *p;
2321 
2322 	snprintf(filename, 256, "db/%s.return_fixes", option_project_str);
2323 	fd = open_schema_file(filename);
2324 	if (fd < 0)
2325 		return;
2326 	ret = read(fd, buf, sizeof(buf));
2327 	close(fd);
2328 	if (ret < 0)
2329 		return;
2330 	if (ret == sizeof(buf)) {
2331 		sm_ierror("file too large:  %s (limit %zd bytes)",
2332 		       filename, sizeof(buf));
2333 		return;
2334 	}
2335 	buf[ret] = '\0';
2336 
2337 	p = buf;
2338 	while (*p) {
2339 		get_next_string(&p);
2340 		replace_count++;
2341 	}
2342 	if (replace_count == 0 || replace_count % 3 != 0) {
2343 		replace_count = 0;
2344 		return;
2345 	}
2346 	replace_table = malloc(replace_count * sizeof(char *));
2347 
2348 	p = buf;
2349 	i = 0;
2350 	while (*p) {
2351 		func = alloc_string(get_next_string(&p));
2352 		orig = alloc_string(get_next_string(&p));
2353 		new  = alloc_string(get_next_string(&p));
2354 
2355 		replace_table[i++] = func;
2356 		replace_table[i++] = orig;
2357 		replace_table[i++] = new;
2358 	}
2359 }
2360 
2361 void register_definition_db_callbacks(int id)
2362 {
2363 	add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2364 	add_hook(&global_variable, BASE_HOOK);
2365 	add_hook(&global_variable, DECLARATION_HOOK);
2366 	add_split_return_callback(match_return_info);
2367 	add_split_return_callback(print_returned_struct_members);
2368 	add_hook(&call_return_state_hooks, RETURN_HOOK);
2369 	add_hook(&match_end_func_info, END_FUNC_HOOK);
2370 	add_hook(&match_after_func, AFTER_FUNC_HOOK);
2371 
2372 	add_hook(&match_data_from_db, FUNC_DEF_HOOK);
2373 	add_hook(&match_call_implies, FUNC_DEF_HOOK);
2374 	add_hook(&match_return_implies, CALL_HOOK_AFTER_INLINE);
2375 
2376 	register_common_funcs();
2377 	register_return_replacements();
2378 
2379 	add_hook(&dump_cache, END_FILE_HOOK);
2380 }
2381 
2382 void register_db_call_marker(int id)
2383 {
2384 	add_hook(&match_call_marker, FUNCTION_CALL_HOOK);
2385 }
2386 
2387 char *return_state_to_var_sym(struct expression *expr, int param, const char *key, struct symbol **sym)
2388 {
2389 	struct expression *arg;
2390 	char *name = NULL;
2391 	char member_name[256];
2392 
2393 	*sym = NULL;
2394 
2395 	if (param == -1) {
2396 		const char *star = "";
2397 
2398 		if (expr->type != EXPR_ASSIGNMENT)
2399 			return NULL;
2400 		name = expr_to_var_sym(expr->left, sym);
2401 		if (!name)
2402 			return NULL;
2403 		if (key[0] == '*') {
2404 			star = "*";
2405 			key++;
2406 		}
2407 		if (strncmp(key, "$", 1) != 0)
2408 			return name;
2409 		snprintf(member_name, sizeof(member_name), "%s%s%s", star, name, key + 1);
2410 		free_string(name);
2411 		return alloc_string(member_name);
2412 	}
2413 
2414 	while (expr->type == EXPR_ASSIGNMENT)
2415 		expr = strip_expr(expr->right);
2416 	if (expr->type != EXPR_CALL)
2417 		return NULL;
2418 
2419 	arg = get_argument_from_call_expr(expr->args, param);
2420 	if (!arg)
2421 		return NULL;
2422 
2423 	return get_variable_from_key(arg, key, sym);
2424 }
2425 
2426 char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2427 {
2428 	char buf[256];
2429 	char *tmp;
2430 
2431 	if (!arg)
2432 		return NULL;
2433 
2434 	arg = strip_expr(arg);
2435 
2436 	if (strcmp(key, "$") == 0)
2437 		return expr_to_var_sym(arg, sym);
2438 
2439 	if (strcmp(key, "*$") == 0) {
2440 		if (arg->type == EXPR_PREOP && arg->op == '&') {
2441 			arg = strip_expr(arg->unop);
2442 			return expr_to_var_sym(arg, sym);
2443 		} else {
2444 			tmp = expr_to_var_sym(arg, sym);
2445 			if (!tmp)
2446 				return NULL;
2447 			snprintf(buf, sizeof(buf), "*%s", tmp);
2448 			free_string(tmp);
2449 			return alloc_string(buf);
2450 		}
2451 	}
2452 
2453 	if (arg->type == EXPR_PREOP && arg->op == '&') {
2454 		arg = strip_expr(arg->unop);
2455 		tmp = expr_to_var_sym(arg, sym);
2456 		if (!tmp)
2457 			return NULL;
2458 		snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 3);
2459 		return alloc_string(buf);
2460 	}
2461 
2462 	tmp = expr_to_var_sym(arg, sym);
2463 	if (!tmp)
2464 		return NULL;
2465 	snprintf(buf, sizeof(buf), "%s%s", tmp, key + 1);
2466 	free_string(tmp);
2467 	return alloc_string(buf);
2468 }
2469 
2470 char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2471 {
2472 	*vsl = NULL;
2473 
2474 	if (strcmp("$", key) == 0)
2475 		return expr_to_chunk_sym_vsl(arg, sym, vsl);
2476 	return get_variable_from_key(arg, key, sym);
2477 }
2478 
2479 const char *state_name_to_param_name(const char *state_name, const char *param_name)
2480 {
2481 	int name_len;
2482 	static char buf[256];
2483 
2484 	name_len = strlen(param_name);
2485 
2486 	if (strcmp(state_name, param_name) == 0) {
2487 		return "$";
2488 	} else if (state_name[name_len] == '-' && /* check for '-' from "->" */
2489 	    strncmp(state_name, param_name, name_len) == 0) {
2490 		snprintf(buf, sizeof(buf), "$%s", state_name + name_len);
2491 		return buf;
2492 	} else if (state_name[0] == '*' && strcmp(state_name + 1, param_name) == 0) {
2493 		return "*$";
2494 	}
2495 	return NULL;
2496 }
2497 
2498 const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2499 {
2500 	if (!sym || !sym->ident)
2501 		return NULL;
2502 
2503 	return state_name_to_param_name(name, sym->ident->name);
2504 }
2505 
2506 const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym)
2507 {
2508 	struct symbol *type;
2509 	const char *sym_name;
2510 	int name_len;
2511 	static char buf[256];
2512 
2513 	/*
2514 	 * mtag_name is different from param_name because mtags can be a struct
2515 	 * instead of a struct pointer.  But we want to treat it like a pointer
2516 	 * because really an mtag is a pointer.  Or in other words, if you pass
2517 	 * a struct foo then you want to talk about foo.bar but with an mtag
2518 	 * you want to refer to it as foo->bar.
2519 	 *
2520 	 */
2521 
2522 	if (!sym || !sym->ident)
2523 		return NULL;
2524 
2525 	type = get_real_base_type(sym);
2526 	if (type && type->type == SYM_BASETYPE)
2527 		return "*$";
2528 
2529 	sym_name = sym->ident->name;
2530 	name_len = strlen(sym_name);
2531 
2532 	if (state_name[name_len] == '.' && /* check for '-' from "->" */
2533 	    strncmp(state_name, sym_name, name_len) == 0) {
2534 		snprintf(buf, sizeof(buf), "$->%s", state_name + name_len + 1);
2535 		return buf;
2536 	}
2537 
2538 	return state_name_to_param_name(state_name, sym_name);
2539 }
2540 
2541 const char *get_mtag_name_expr(struct expression *expr)
2542 {
2543 	char *name;
2544 	struct symbol *sym;
2545 	const char *ret = NULL;
2546 
2547 	name = expr_to_var_sym(expr, &sym);
2548 	if (!name || !sym)
2549 		goto free;
2550 
2551 	ret = get_mtag_name_var_sym(name, sym);
2552 free:
2553 	free_string(name);
2554 	return ret;
2555 }
2556 
2557 const char *get_param_name(struct sm_state *sm)
2558 {
2559 	return get_param_name_var_sym(sm->name, sm->sym);
2560 }
2561 
2562 char *get_data_info_name(struct expression *expr)
2563 {
2564 	struct symbol *sym;
2565 	char *name;
2566 	char buf[256];
2567 	char *ret = NULL;
2568 
2569 	expr = strip_expr(expr);
2570 	name = get_member_name(expr);
2571 	if (name)
2572 		return name;
2573 	name = expr_to_var_sym(expr, &sym);
2574 	if (!name || !sym)
2575 		goto free;
2576 	if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
2577 		goto free;
2578 	if (sym->ctype.modifiers & MOD_STATIC)
2579 		snprintf(buf, sizeof(buf), "static %s", name);
2580 	else
2581 		snprintf(buf, sizeof(buf), "global %s", name);
2582 	ret = alloc_sname(buf);
2583 free:
2584 	free_string(name);
2585 	return ret;
2586 }
2587