11f5207b7SJohn Levon /*
21f5207b7SJohn Levon  * Copyright (C) 2009 Dan Carpenter.
31f5207b7SJohn Levon  *
41f5207b7SJohn Levon  * This program is free software; you can redistribute it and/or
51f5207b7SJohn Levon  * modify it under the terms of the GNU General Public License
61f5207b7SJohn Levon  * as published by the Free Software Foundation; either version 2
71f5207b7SJohn Levon  * of the License, or (at your option) any later version.
81f5207b7SJohn Levon  *
91f5207b7SJohn Levon  * This program is distributed in the hope that it will be useful,
101f5207b7SJohn Levon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
111f5207b7SJohn Levon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121f5207b7SJohn Levon  * GNU General Public License for more details.
131f5207b7SJohn Levon  *
141f5207b7SJohn Levon  * You should have received a copy of the GNU General Public License
151f5207b7SJohn Levon  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
161f5207b7SJohn Levon  */
171f5207b7SJohn Levon 
185a0e240fSJohn Levon #include <string.h>
195a0e240fSJohn Levon 
201f5207b7SJohn Levon #include "smatch.h"
211f5207b7SJohn Levon #include "smatch_slist.h"
221f5207b7SJohn Levon #include "smatch_extra.h"
231f5207b7SJohn Levon 
24efe51d0cSJohn Levon void show_sname_alloc(void);
25efe51d0cSJohn Levon void show_data_range_alloc(void);
26efe51d0cSJohn Levon void show_ptrlist_alloc(void);
27c85f09ccSJohn Levon void show_rl_ptrlist_alloc(void);
28efe51d0cSJohn Levon void show_sm_state_alloc(void);
29efe51d0cSJohn Levon 
301f5207b7SJohn Levon int local_debug;
311f5207b7SJohn Levon static int my_id;
321f5207b7SJohn Levon char *trace_variable;
331f5207b7SJohn Levon 
match_all_values(const char * fn,struct expression * expr,void * info)341f5207b7SJohn Levon static void match_all_values(const char *fn, struct expression *expr, void *info)
351f5207b7SJohn Levon {
361f5207b7SJohn Levon 	struct stree *stree;
371f5207b7SJohn Levon 
381f5207b7SJohn Levon 	stree = get_all_states_stree(SMATCH_EXTRA);
391f5207b7SJohn Levon 	__print_stree(stree);
401f5207b7SJohn Levon 	free_stree(&stree);
411f5207b7SJohn Levon }
421f5207b7SJohn Levon 
match_cur_stree(const char * fn,struct expression * expr,void * info)431f5207b7SJohn Levon static void match_cur_stree(const char *fn, struct expression *expr, void *info)
441f5207b7SJohn Levon {
451f5207b7SJohn Levon 	__print_cur_stree();
461f5207b7SJohn Levon }
471f5207b7SJohn Levon 
match_state(const char * fn,struct expression * expr,void * info)481f5207b7SJohn Levon static void match_state(const char *fn, struct expression *expr, void *info)
491f5207b7SJohn Levon {
501f5207b7SJohn Levon 	struct expression *check_arg, *state_arg;
511f5207b7SJohn Levon 	struct sm_state *sm;
521f5207b7SJohn Levon 	int found = 0;
531f5207b7SJohn Levon 
541f5207b7SJohn Levon 	check_arg = get_argument_from_call_expr(expr->args, 0);
551f5207b7SJohn Levon 	if (check_arg->type != EXPR_STRING) {
561f5207b7SJohn Levon 		sm_error("the check_name argument to %s is supposed to be a string literal", fn);
571f5207b7SJohn Levon 		return;
581f5207b7SJohn Levon 	}
591f5207b7SJohn Levon 	state_arg = get_argument_from_call_expr(expr->args, 1);
601f5207b7SJohn Levon 	if (!state_arg || state_arg->type != EXPR_STRING) {
611f5207b7SJohn Levon 		sm_error("the state_name argument to %s is supposed to be a string literal", fn);
621f5207b7SJohn Levon 		return;
631f5207b7SJohn Levon 	}
641f5207b7SJohn Levon 
651f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
661f5207b7SJohn Levon 		if (strcmp(check_name(sm->owner), check_arg->string->data) != 0)
671f5207b7SJohn Levon 			continue;
681f5207b7SJohn Levon 		if (strcmp(sm->name, state_arg->string->data) != 0)
691f5207b7SJohn Levon 			continue;
701f5207b7SJohn Levon 		sm_msg("'%s' = '%s'", sm->name, sm->state->name);
711f5207b7SJohn Levon 		found = 1;
721f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
731f5207b7SJohn Levon 
741f5207b7SJohn Levon 	if (!found)
751f5207b7SJohn Levon 		sm_msg("%s '%s' not found", check_arg->string->data, state_arg->string->data);
761f5207b7SJohn Levon }
771f5207b7SJohn Levon 
match_states(const char * fn,struct expression * expr,void * info)781f5207b7SJohn Levon static void match_states(const char *fn, struct expression *expr, void *info)
791f5207b7SJohn Levon {
801f5207b7SJohn Levon 	struct expression *check_arg;
811f5207b7SJohn Levon 
821f5207b7SJohn Levon 	check_arg = get_argument_from_call_expr(expr->args, 0);
831f5207b7SJohn Levon 	if (check_arg->type != EXPR_STRING) {
841f5207b7SJohn Levon 		sm_error("the check_name argument to %s is supposed to be a string literal", fn);
851f5207b7SJohn Levon 		return;
861f5207b7SJohn Levon 	}
871f5207b7SJohn Levon 
88*6523a3aaSJohn Levon 	if (__print_states(check_arg->string->data))
891f5207b7SJohn Levon 		return;
901f5207b7SJohn Levon 
911f5207b7SJohn Levon 	if (!id_from_name(check_arg->string->data))
921f5207b7SJohn Levon 		sm_msg("invalid check name '%s'", check_arg->string->data);
931f5207b7SJohn Levon 	else
941f5207b7SJohn Levon 		sm_msg("%s: no states", check_arg->string->data);
951f5207b7SJohn Levon }
961f5207b7SJohn Levon 
match_print_value(const char * fn,struct expression * expr,void * info)971f5207b7SJohn Levon static void match_print_value(const char *fn, struct expression *expr, void *info)
981f5207b7SJohn Levon {
991f5207b7SJohn Levon 	struct stree *stree;
1001f5207b7SJohn Levon 	struct sm_state *tmp;
1011f5207b7SJohn Levon 	struct expression *arg_expr;
1021f5207b7SJohn Levon 
1031f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
1041f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
1051f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
1061f5207b7SJohn Levon 		return;
1071f5207b7SJohn Levon 	}
1081f5207b7SJohn Levon 
1091f5207b7SJohn Levon 	stree = __get_cur_stree();
1101f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
1111f5207b7SJohn Levon 		if (!strcmp(tmp->name, arg_expr->string->data))
1121f5207b7SJohn Levon 			sm_msg("%s = %s", tmp->name, tmp->state->name);
1131f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
1141f5207b7SJohn Levon }
1151f5207b7SJohn Levon 
match_print_known(const char * fn,struct expression * expr,void * info)1161f5207b7SJohn Levon static void match_print_known(const char *fn, struct expression *expr, void *info)
1171f5207b7SJohn Levon {
1181f5207b7SJohn Levon 	struct expression *arg;
1191f5207b7SJohn Levon 	struct range_list *rl = NULL;
1201f5207b7SJohn Levon 	char *name;
1211f5207b7SJohn Levon 	int known = 0;
1221f5207b7SJohn Levon 	sval_t sval;
1231f5207b7SJohn Levon 
1241f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
1251f5207b7SJohn Levon 	if (get_value(arg, &sval))
1261f5207b7SJohn Levon 		known = 1;
1271f5207b7SJohn Levon 
1281f5207b7SJohn Levon 	get_implied_rl(arg, &rl);
1291f5207b7SJohn Levon 
1301f5207b7SJohn Levon 	name = expr_to_str(arg);
1311f5207b7SJohn Levon 	sm_msg("known: '%s' = '%s'.  implied = '%s'", name, known ? sval_to_str(sval) : "<unknown>", show_rl(rl));
1321f5207b7SJohn Levon 	free_string(name);
1331f5207b7SJohn Levon }
1341f5207b7SJohn Levon 
match_print_implied(const char * fn,struct expression * expr,void * info)1351f5207b7SJohn Levon static void match_print_implied(const char *fn, struct expression *expr, void *info)
1361f5207b7SJohn Levon {
1371f5207b7SJohn Levon 	struct expression *arg;
1381f5207b7SJohn Levon 	struct range_list *rl = NULL;
1391f5207b7SJohn Levon 	char *name;
1401f5207b7SJohn Levon 
1411f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
1421f5207b7SJohn Levon 	get_implied_rl(arg, &rl);
1431f5207b7SJohn Levon 
1441f5207b7SJohn Levon 	name = expr_to_str(arg);
1451f5207b7SJohn Levon 	sm_msg("implied: %s = '%s'", name, show_rl(rl));
1461f5207b7SJohn Levon 	free_string(name);
1471f5207b7SJohn Levon }
1481f5207b7SJohn Levon 
match_real_absolute(const char * fn,struct expression * expr,void * info)1491f5207b7SJohn Levon static void match_real_absolute(const char *fn, struct expression *expr, void *info)
1501f5207b7SJohn Levon {
1511f5207b7SJohn Levon 	struct expression *arg;
1521f5207b7SJohn Levon 	struct range_list *rl = NULL;
1531f5207b7SJohn Levon 	char *name;
1541f5207b7SJohn Levon 
1551f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
1561f5207b7SJohn Levon 	get_real_absolute_rl(arg, &rl);
1571f5207b7SJohn Levon 
1581f5207b7SJohn Levon 	name = expr_to_str(arg);
1591f5207b7SJohn Levon 	sm_msg("real absolute: %s = '%s'", name, show_rl(rl));
1601f5207b7SJohn Levon 	free_string(name);
1611f5207b7SJohn Levon }
1621f5207b7SJohn Levon 
match_print_implied_min(const char * fn,struct expression * expr,void * info)1631f5207b7SJohn Levon static void match_print_implied_min(const char *fn, struct expression *expr, void *info)
1641f5207b7SJohn Levon {
1651f5207b7SJohn Levon 	struct expression *arg;
1661f5207b7SJohn Levon 	sval_t sval;
1671f5207b7SJohn Levon 	char *name;
1681f5207b7SJohn Levon 
1691f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
1701f5207b7SJohn Levon 	name = expr_to_str(arg);
1711f5207b7SJohn Levon 
1721f5207b7SJohn Levon 	if (get_implied_min(arg, &sval))
1731f5207b7SJohn Levon 		sm_msg("implied min: %s = %s", name, sval_to_str(sval));
1741f5207b7SJohn Levon 	else
1751f5207b7SJohn Levon 		sm_msg("implied min: %s = <unknown>", name);
1761f5207b7SJohn Levon 
1771f5207b7SJohn Levon 	free_string(name);
1781f5207b7SJohn Levon }
1791f5207b7SJohn Levon 
match_print_implied_max(const char * fn,struct expression * expr,void * info)1801f5207b7SJohn Levon static void match_print_implied_max(const char *fn, struct expression *expr, void *info)
1811f5207b7SJohn Levon {
1821f5207b7SJohn Levon 	struct expression *arg;
1831f5207b7SJohn Levon 	sval_t sval;
1841f5207b7SJohn Levon 	char *name;
1851f5207b7SJohn Levon 
1861f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
1871f5207b7SJohn Levon 	name = expr_to_str(arg);
1881f5207b7SJohn Levon 
1891f5207b7SJohn Levon 	if (get_implied_max(arg, &sval))
1901f5207b7SJohn Levon 		sm_msg("implied max: %s = %s", name, sval_to_str(sval));
1911f5207b7SJohn Levon 	else
1921f5207b7SJohn Levon 		sm_msg("implied max: %s = <unknown>", name);
1931f5207b7SJohn Levon 
1941f5207b7SJohn Levon 	free_string(name);
1951f5207b7SJohn Levon }
1961f5207b7SJohn Levon 
match_user_rl(const char * fn,struct expression * expr,void * info)1971f5207b7SJohn Levon static void match_user_rl(const char *fn, struct expression *expr, void *info)
1981f5207b7SJohn Levon {
1991f5207b7SJohn Levon 	struct expression *arg;
200efe51d0cSJohn Levon 	struct range_list *rl = NULL;
201c85f09ccSJohn Levon 	bool capped = false;
2021f5207b7SJohn Levon 	char *name;
2031f5207b7SJohn Levon 
204*6523a3aaSJohn Levon 	if (option_project != PROJ_KERNEL)
205*6523a3aaSJohn Levon 		sm_msg("no user data for project = '%s'", option_project_str);
206*6523a3aaSJohn Levon 
2071f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2081f5207b7SJohn Levon 	name = expr_to_str(arg);
2091f5207b7SJohn Levon 
2101f5207b7SJohn Levon 	get_user_rl(arg, &rl);
211c85f09ccSJohn Levon 	if (rl)
212c85f09ccSJohn Levon 		capped = user_rl_capped(arg);
213c85f09ccSJohn Levon 	sm_msg("user rl: '%s' = '%s'%s", name, show_rl(rl), capped ? " (capped)" : "");
2141f5207b7SJohn Levon 
2151f5207b7SJohn Levon 	free_string(name);
2161f5207b7SJohn Levon }
2171f5207b7SJohn Levon 
match_capped(const char * fn,struct expression * expr,void * info)2181f5207b7SJohn Levon static void match_capped(const char *fn, struct expression *expr, void *info)
2191f5207b7SJohn Levon {
2201f5207b7SJohn Levon 	struct expression *arg;
2211f5207b7SJohn Levon 	char *name;
2221f5207b7SJohn Levon 
2231f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2241f5207b7SJohn Levon 	name = expr_to_str(arg);
2251f5207b7SJohn Levon 	sm_msg("'%s' = '%s'", name, is_capped(arg) ? "capped" : "not capped");
2261f5207b7SJohn Levon 	free_string(name);
2271f5207b7SJohn Levon }
2281f5207b7SJohn Levon 
match_print_hard_max(const char * fn,struct expression * expr,void * info)2291f5207b7SJohn Levon static void match_print_hard_max(const char *fn, struct expression *expr, void *info)
2301f5207b7SJohn Levon {
2311f5207b7SJohn Levon 	struct expression *arg;
2321f5207b7SJohn Levon 	sval_t sval;
2331f5207b7SJohn Levon 	char *name;
2341f5207b7SJohn Levon 
2351f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2361f5207b7SJohn Levon 	name = expr_to_str(arg);
2371f5207b7SJohn Levon 
2381f5207b7SJohn Levon 	if (get_hard_max(arg, &sval))
2391f5207b7SJohn Levon 		sm_msg("hard max: %s = %s", name, sval_to_str(sval));
2401f5207b7SJohn Levon 	else
2411f5207b7SJohn Levon 		sm_msg("hard max: %s = <unknown>", name);
2421f5207b7SJohn Levon 
2431f5207b7SJohn Levon 	free_string(name);
2441f5207b7SJohn Levon }
2451f5207b7SJohn Levon 
match_print_fuzzy_max(const char * fn,struct expression * expr,void * info)2461f5207b7SJohn Levon static void match_print_fuzzy_max(const char *fn, struct expression *expr, void *info)
2471f5207b7SJohn Levon {
2481f5207b7SJohn Levon 	struct expression *arg;
2491f5207b7SJohn Levon 	sval_t sval;
2501f5207b7SJohn Levon 	char *name;
2511f5207b7SJohn Levon 
2521f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2531f5207b7SJohn Levon 	name = expr_to_str(arg);
2541f5207b7SJohn Levon 
2551f5207b7SJohn Levon 	if (get_fuzzy_max(arg, &sval))
2561f5207b7SJohn Levon 		sm_msg("fuzzy max: %s = %s", name, sval_to_str(sval));
2571f5207b7SJohn Levon 	else
2581f5207b7SJohn Levon 		sm_msg("fuzzy max: %s = <unknown>", name);
2591f5207b7SJohn Levon 
2601f5207b7SJohn Levon 	free_string(name);
2611f5207b7SJohn Levon }
2621f5207b7SJohn Levon 
match_print_absolute(const char * fn,struct expression * expr,void * info)2631f5207b7SJohn Levon static void match_print_absolute(const char *fn, struct expression *expr, void *info)
2641f5207b7SJohn Levon {
2651f5207b7SJohn Levon 	struct expression *arg;
2661f5207b7SJohn Levon 	struct range_list *rl;
2671f5207b7SJohn Levon 	char *name;
2681f5207b7SJohn Levon 
2691f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2701f5207b7SJohn Levon 	name = expr_to_str(arg);
2711f5207b7SJohn Levon 
2721f5207b7SJohn Levon 	get_absolute_rl(arg, &rl);
2731f5207b7SJohn Levon 	sm_msg("absolute: %s = %s", name, show_rl(rl));
2741f5207b7SJohn Levon 
2751f5207b7SJohn Levon 	free_string(name);
2761f5207b7SJohn Levon }
2771f5207b7SJohn Levon 
match_print_absolute_min(const char * fn,struct expression * expr,void * info)2781f5207b7SJohn Levon static void match_print_absolute_min(const char *fn, struct expression *expr, void *info)
2791f5207b7SJohn Levon {
2801f5207b7SJohn Levon 	struct expression *arg;
2811f5207b7SJohn Levon 	sval_t sval;
2821f5207b7SJohn Levon 	char *name;
2831f5207b7SJohn Levon 
2841f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
2851f5207b7SJohn Levon 	name = expr_to_str(arg);
2861f5207b7SJohn Levon 
2871f5207b7SJohn Levon 	if (get_absolute_min(arg, &sval))
2881f5207b7SJohn Levon 		sm_msg("absolute min: %s = %s", name, sval_to_str(sval));
2891f5207b7SJohn Levon 	else
2901f5207b7SJohn Levon 		sm_msg("absolute min: %s = <unknown>", name);
2911f5207b7SJohn Levon 
2921f5207b7SJohn Levon 	free_string(name);
2931f5207b7SJohn Levon }
2941f5207b7SJohn Levon 
match_print_absolute_max(const char * fn,struct expression * expr,void * info)2951f5207b7SJohn Levon static void match_print_absolute_max(const char *fn, struct expression *expr, void *info)
2961f5207b7SJohn Levon {
2971f5207b7SJohn Levon 	struct expression *arg;
2981f5207b7SJohn Levon 	sval_t sval;
2991f5207b7SJohn Levon 	char *name;
3001f5207b7SJohn Levon 
3011f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
3021f5207b7SJohn Levon 	get_absolute_max(arg, &sval);
3031f5207b7SJohn Levon 
3041f5207b7SJohn Levon 	name = expr_to_str(arg);
3051f5207b7SJohn Levon 	sm_msg("absolute max: %s = %s", name, sval_to_str(sval));
3061f5207b7SJohn Levon 	free_string(name);
3071f5207b7SJohn Levon }
3081f5207b7SJohn Levon 
match_sval_info(const char * fn,struct expression * expr,void * info)3091f5207b7SJohn Levon static void match_sval_info(const char *fn, struct expression *expr, void *info)
3101f5207b7SJohn Levon {
3111f5207b7SJohn Levon 	struct expression *arg;
3121f5207b7SJohn Levon 	sval_t sval;
3131f5207b7SJohn Levon 	char *name;
3141f5207b7SJohn Levon 
3151f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
3161f5207b7SJohn Levon 	name = expr_to_str(arg);
3171f5207b7SJohn Levon 
3181f5207b7SJohn Levon 	if (!get_implied_value(arg, &sval)) {
3191f5207b7SJohn Levon 		sm_msg("no sval for '%s'", name);
3201f5207b7SJohn Levon 		goto free;
3211f5207b7SJohn Levon 	}
3221f5207b7SJohn Levon 
3231f5207b7SJohn Levon 	sm_msg("implied: %s %c%d ->value = %llx", name, sval_unsigned(sval) ? 'u' : 's', sval_bits(sval), sval.value);
3241f5207b7SJohn Levon free:
3251f5207b7SJohn Levon 	free_string(name);
3261f5207b7SJohn Levon }
3271f5207b7SJohn Levon 
match_member_name(const char * fn,struct expression * expr,void * info)3281f5207b7SJohn Levon static void match_member_name(const char *fn, struct expression *expr, void *info)
3291f5207b7SJohn Levon {
3301f5207b7SJohn Levon 	struct expression *arg;
3311f5207b7SJohn Levon 	char *name, *member_name;
3321f5207b7SJohn Levon 
3331f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
3341f5207b7SJohn Levon 	name = expr_to_str(arg);
3351f5207b7SJohn Levon 	member_name = get_member_name(arg);
3361f5207b7SJohn Levon 	sm_msg("member name: '%s => %s'", name, member_name);
3371f5207b7SJohn Levon 	free_string(member_name);
3381f5207b7SJohn Levon 	free_string(name);
3391f5207b7SJohn Levon }
3401f5207b7SJohn Levon 
print_possible(struct sm_state * sm)3411f5207b7SJohn Levon static void print_possible(struct sm_state *sm)
3421f5207b7SJohn Levon {
3431f5207b7SJohn Levon 	struct sm_state *tmp;
3441f5207b7SJohn Levon 
3451f5207b7SJohn Levon 	sm_msg("Possible values for %s", sm->name);
3461f5207b7SJohn Levon 	FOR_EACH_PTR(sm->possible, tmp) {
3471f5207b7SJohn Levon 		printf("%s\n", tmp->state->name);
3481f5207b7SJohn Levon 	} END_FOR_EACH_PTR(tmp);
3491f5207b7SJohn Levon 	sm_msg("===");
3501f5207b7SJohn Levon }
3511f5207b7SJohn Levon 
match_possible(const char * fn,struct expression * expr,void * info)3521f5207b7SJohn Levon static void match_possible(const char *fn, struct expression *expr, void *info)
3531f5207b7SJohn Levon {
3541f5207b7SJohn Levon 	struct stree *stree;
3551f5207b7SJohn Levon 	struct sm_state *tmp;
3561f5207b7SJohn Levon 	struct expression *arg_expr;
3571f5207b7SJohn Levon 
3581f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
3591f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
3601f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
3611f5207b7SJohn Levon 		return;
3621f5207b7SJohn Levon 	}
3631f5207b7SJohn Levon 
3641f5207b7SJohn Levon 	stree = __get_cur_stree();
3651f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
3661f5207b7SJohn Levon 		if (!strcmp(tmp->name, arg_expr->string->data))
3671f5207b7SJohn Levon 			print_possible(tmp);
3681f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
3691f5207b7SJohn Levon }
3701f5207b7SJohn Levon 
match_strlen(const char * fn,struct expression * expr,void * info)3711f5207b7SJohn Levon static void match_strlen(const char *fn, struct expression *expr, void *info)
3721f5207b7SJohn Levon {
3731f5207b7SJohn Levon 	struct expression *arg;
3741f5207b7SJohn Levon 	struct range_list *rl;
3751f5207b7SJohn Levon 	char *name;
3761f5207b7SJohn Levon 
3771f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
3781f5207b7SJohn Levon 	get_implied_strlen(arg, &rl);
3791f5207b7SJohn Levon 
3801f5207b7SJohn Levon 	name = expr_to_str(arg);
3811f5207b7SJohn Levon 	sm_msg("strlen: '%s' %s characters", name, show_rl(rl));
3821f5207b7SJohn Levon 	free_string(name);
3831f5207b7SJohn Levon }
3841f5207b7SJohn Levon 
match_buf_size(const char * fn,struct expression * expr,void * info)3851f5207b7SJohn Levon static void match_buf_size(const char *fn, struct expression *expr, void *info)
3861f5207b7SJohn Levon {
3871f5207b7SJohn Levon 	struct expression *arg, *comp;
3881f5207b7SJohn Levon 	struct range_list *rl;
3891f5207b7SJohn Levon 	int elements, bytes;
3901f5207b7SJohn Levon 	char *name;
3911f5207b7SJohn Levon 	char buf[256] = "";
392efe51d0cSJohn Levon 	int limit_type;
3931f5207b7SJohn Levon 	int n;
3941f5207b7SJohn Levon 	sval_t sval;
3951f5207b7SJohn Levon 
3961f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
3971f5207b7SJohn Levon 
3981f5207b7SJohn Levon 	elements = get_array_size(arg);
3991f5207b7SJohn Levon 	bytes = get_array_size_bytes_max(arg);
4001f5207b7SJohn Levon 	rl = get_array_size_bytes_rl(arg);
401efe51d0cSJohn Levon 	comp = get_size_variable(arg, &limit_type);
4021f5207b7SJohn Levon 
4031f5207b7SJohn Levon 	name = expr_to_str(arg);
4041f5207b7SJohn Levon 	n = snprintf(buf, sizeof(buf), "buf size: '%s' %d elements, %d bytes", name, elements, bytes);
4051f5207b7SJohn Levon 	free_string(name);
4061f5207b7SJohn Levon 
4071f5207b7SJohn Levon 	if (!rl_to_sval(rl, &sval))
4081f5207b7SJohn Levon 		n += snprintf(buf + n, sizeof(buf) - n, " (rl = %s)", show_rl(rl));
4091f5207b7SJohn Levon 
4101f5207b7SJohn Levon 	if (comp) {
4111f5207b7SJohn Levon 		name = expr_to_str(comp);
412efe51d0cSJohn Levon 		snprintf(buf + n, sizeof(buf) - n, "[size_var=%s %s]", limit_type_str(limit_type), name);
4131f5207b7SJohn Levon 		free_string(name);
4141f5207b7SJohn Levon 	}
4151f5207b7SJohn Levon 	sm_msg("%s", buf);
4161f5207b7SJohn Levon }
4171f5207b7SJohn Levon 
match_note(const char * fn,struct expression * expr,void * info)4181f5207b7SJohn Levon static void match_note(const char *fn, struct expression *expr, void *info)
4191f5207b7SJohn Levon {
4201f5207b7SJohn Levon 	struct expression *arg_expr;
4211f5207b7SJohn Levon 
4221f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
4231f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
4241f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
4251f5207b7SJohn Levon 		return;
4261f5207b7SJohn Levon 	}
4271f5207b7SJohn Levon 	sm_msg("%s", arg_expr->string->data);
4281f5207b7SJohn Levon }
4291f5207b7SJohn Levon 
print_related(struct sm_state * sm)4301f5207b7SJohn Levon static void print_related(struct sm_state *sm)
4311f5207b7SJohn Levon {
4321f5207b7SJohn Levon 	struct relation *rel;
4331f5207b7SJohn Levon 
4341f5207b7SJohn Levon 	if (!estate_related(sm->state))
4351f5207b7SJohn Levon 		return;
4361f5207b7SJohn Levon 
4371f5207b7SJohn Levon 	sm_prefix();
4381f5207b7SJohn Levon 	sm_printf("%s: ", sm->name);
4391f5207b7SJohn Levon 	FOR_EACH_PTR(estate_related(sm->state), rel) {
4401f5207b7SJohn Levon 		sm_printf("%s ", rel->name);
4411f5207b7SJohn Levon 	} END_FOR_EACH_PTR(rel);
4421f5207b7SJohn Levon 	sm_printf("\n");
4431f5207b7SJohn Levon }
4441f5207b7SJohn Levon 
match_dump_related(const char * fn,struct expression * expr,void * info)4451f5207b7SJohn Levon static void match_dump_related(const char *fn, struct expression *expr, void *info)
4461f5207b7SJohn Levon {
4471f5207b7SJohn Levon 	struct stree *stree;
4481f5207b7SJohn Levon 	struct sm_state *tmp;
4491f5207b7SJohn Levon 
4501f5207b7SJohn Levon 	stree = __get_cur_stree();
4511f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
4521f5207b7SJohn Levon 		print_related(tmp);
4531f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
4541f5207b7SJohn Levon }
4551f5207b7SJohn Levon 
match_compare(const char * fn,struct expression * expr,void * info)4561f5207b7SJohn Levon static void match_compare(const char *fn, struct expression *expr, void *info)
4571f5207b7SJohn Levon {
4581f5207b7SJohn Levon 	struct expression *one, *two;
4591f5207b7SJohn Levon 	char *one_name, *two_name;
4601f5207b7SJohn Levon 	int comparison;
4611f5207b7SJohn Levon 	char buf[16];
4621f5207b7SJohn Levon 
4631f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
4641f5207b7SJohn Levon 	two = get_argument_from_call_expr(expr->args, 1);
4651f5207b7SJohn Levon 
4661f5207b7SJohn Levon 	comparison = get_comparison(one, two);
4671f5207b7SJohn Levon 	if (!comparison)
4681f5207b7SJohn Levon 		snprintf(buf, sizeof(buf), "<none>");
4691f5207b7SJohn Levon 	else
4701f5207b7SJohn Levon 		snprintf(buf, sizeof(buf), "%s", show_special(comparison));
4711f5207b7SJohn Levon 
4721f5207b7SJohn Levon 	one_name = expr_to_str(one);
4731f5207b7SJohn Levon 	two_name = expr_to_str(two);
4741f5207b7SJohn Levon 
4751f5207b7SJohn Levon 	sm_msg("%s %s %s", one_name, buf, two_name);
4761f5207b7SJohn Levon 
4771f5207b7SJohn Levon 	free_string(one_name);
4781f5207b7SJohn Levon 	free_string(two_name);
4791f5207b7SJohn Levon }
4801f5207b7SJohn Levon 
match_debug_on(const char * fn,struct expression * expr,void * info)4811f5207b7SJohn Levon static void match_debug_on(const char *fn, struct expression *expr, void *info)
4821f5207b7SJohn Levon {
4831f5207b7SJohn Levon 	option_debug = 1;
4841f5207b7SJohn Levon }
4851f5207b7SJohn Levon 
match_debug_check(const char * fn,struct expression * expr,void * info)4861f5207b7SJohn Levon static void match_debug_check(const char *fn, struct expression *expr, void *info)
4871f5207b7SJohn Levon {
4881f5207b7SJohn Levon 	struct expression *arg;
4891f5207b7SJohn Levon 
4901f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
4911f5207b7SJohn Levon 	if (!arg || arg->type != EXPR_STRING)
4921f5207b7SJohn Levon 		return;
4931f5207b7SJohn Levon 	option_debug_check = arg->string->data;
4941f5207b7SJohn Levon 	sm_msg("arg = '%s'", option_debug_check);
4951f5207b7SJohn Levon }
4961f5207b7SJohn Levon 
match_debug_off(const char * fn,struct expression * expr,void * info)4971f5207b7SJohn Levon static void match_debug_off(const char *fn, struct expression *expr, void *info)
4981f5207b7SJohn Levon {
4991f5207b7SJohn Levon 	option_debug_check = (char *)"";
5001f5207b7SJohn Levon 	option_debug = 0;
5011f5207b7SJohn Levon }
5021f5207b7SJohn Levon 
match_local_debug_on(const char * fn,struct expression * expr,void * info)5031f5207b7SJohn Levon static void match_local_debug_on(const char *fn, struct expression *expr, void *info)
5041f5207b7SJohn Levon {
5051f5207b7SJohn Levon 	local_debug = 1;
5061f5207b7SJohn Levon }
5071f5207b7SJohn Levon 
match_local_debug_off(const char * fn,struct expression * expr,void * info)5081f5207b7SJohn Levon static void match_local_debug_off(const char *fn, struct expression *expr, void *info)
5091f5207b7SJohn Levon {
5101f5207b7SJohn Levon 	local_debug = 0;
5111f5207b7SJohn Levon }
5121f5207b7SJohn Levon 
match_debug_db_on(const char * fn,struct expression * expr,void * info)5135a0e240fSJohn Levon static void match_debug_db_on(const char *fn, struct expression *expr, void *info)
5145a0e240fSJohn Levon {
5155a0e240fSJohn Levon 	debug_db = 1;
5165a0e240fSJohn Levon }
5175a0e240fSJohn Levon 
match_debug_db_off(const char * fn,struct expression * expr,void * info)5185a0e240fSJohn Levon static void match_debug_db_off(const char *fn, struct expression *expr, void *info)
5195a0e240fSJohn Levon {
5205a0e240fSJohn Levon 	debug_db = 0;
5215a0e240fSJohn Levon }
5225a0e240fSJohn Levon 
mtag_info(struct expression * expr)523*6523a3aaSJohn Levon static void mtag_info(struct expression *expr)
524*6523a3aaSJohn Levon {
525*6523a3aaSJohn Levon 	mtag_t tag = 0;
526*6523a3aaSJohn Levon 	int offset = 0;
527*6523a3aaSJohn Levon 	struct range_list *rl = NULL;
528*6523a3aaSJohn Levon 
529*6523a3aaSJohn Levon 	expr_to_mtag_offset(expr, &tag, &offset);
530*6523a3aaSJohn Levon 	get_mtag_rl(expr, &rl);
531*6523a3aaSJohn Levon 	sm_msg("mtag = %llu offset = %d rl = '%s'", tag, offset, show_rl(rl));
532*6523a3aaSJohn Levon }
533*6523a3aaSJohn Levon 
match_about(const char * fn,struct expression * expr,void * info)5341f5207b7SJohn Levon static void match_about(const char *fn, struct expression *expr, void *info)
5351f5207b7SJohn Levon {
5361f5207b7SJohn Levon 	struct expression *arg;
5371f5207b7SJohn Levon 	struct sm_state *sm;
5381f5207b7SJohn Levon 	char *name;
5391f5207b7SJohn Levon 
5401f5207b7SJohn Levon 	sm_msg("---- about ----");
5411f5207b7SJohn Levon 	match_print_implied(fn, expr, NULL);
5421f5207b7SJohn Levon 	match_buf_size(fn, expr, NULL);
5431f5207b7SJohn Levon 	match_strlen(fn, expr, NULL);
5441f5207b7SJohn Levon 	match_real_absolute(fn, expr, NULL);
545*6523a3aaSJohn Levon 	mtag_info(expr);
5461f5207b7SJohn Levon 
5471f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
5481f5207b7SJohn Levon 	name = expr_to_str(arg);
5491f5207b7SJohn Levon 	if (!name) {
5501f5207b7SJohn Levon 		sm_msg("info: not a straight forward variable.");
5511f5207b7SJohn Levon 		return;
5521f5207b7SJohn Levon 	}
5531f5207b7SJohn Levon 
5541f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
5551f5207b7SJohn Levon 		if (strcmp(sm->name, name) != 0)
5561f5207b7SJohn Levon 			continue;
5571f5207b7SJohn Levon 		sm_msg("%s", show_sm(sm));
5581f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
5591f5207b7SJohn Levon }
5601f5207b7SJohn Levon 
match_intersection(const char * fn,struct expression * expr,void * info)5611f5207b7SJohn Levon static void match_intersection(const char *fn, struct expression *expr, void *info)
5621f5207b7SJohn Levon {
5631f5207b7SJohn Levon 	struct expression *one, *two;
5641f5207b7SJohn Levon 	struct range_list *one_rl, *two_rl;
5651f5207b7SJohn Levon 	struct range_list *res;
5661f5207b7SJohn Levon 
5671f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
5681f5207b7SJohn Levon 	two = get_argument_from_call_expr(expr->args, 1);
5691f5207b7SJohn Levon 
5701f5207b7SJohn Levon 	get_absolute_rl(one, &one_rl);
5711f5207b7SJohn Levon 	get_absolute_rl(two, &two_rl);
5721f5207b7SJohn Levon 
5731f5207b7SJohn Levon 	res = rl_intersection(one_rl, two_rl);
5741f5207b7SJohn Levon 	sm_msg("'%s' intersect '%s' is '%s'", show_rl(one_rl), show_rl(two_rl), show_rl(res));
5751f5207b7SJohn Levon }
5761f5207b7SJohn Levon 
match_type(const char * fn,struct expression * expr,void * info)5771f5207b7SJohn Levon static void match_type(const char *fn, struct expression *expr, void *info)
5781f5207b7SJohn Levon {
5791f5207b7SJohn Levon 	struct expression *one;
5801f5207b7SJohn Levon 	struct symbol *type;
5811f5207b7SJohn Levon 	char *name;
5821f5207b7SJohn Levon 
5831f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
5841f5207b7SJohn Levon 	type = get_type(one);
5851f5207b7SJohn Levon 	name = expr_to_str(one);
5861f5207b7SJohn Levon 	sm_msg("type of '%s' is: '%s'", name, type_to_str(type));
5871f5207b7SJohn Levon 	free_string(name);
5881f5207b7SJohn Levon }
5891f5207b7SJohn Levon 
match_type_rl_return(struct expression * call,void * unused,struct range_list ** rl)5901f5207b7SJohn Levon static int match_type_rl_return(struct expression *call, void *unused, struct range_list **rl)
5911f5207b7SJohn Levon {
5921f5207b7SJohn Levon 	struct expression *one, *two;
5931f5207b7SJohn Levon 	struct symbol *type;
5941f5207b7SJohn Levon 
5951f5207b7SJohn Levon 	one = get_argument_from_call_expr(call->args, 0);
5961f5207b7SJohn Levon 	type = get_type(one);
5971f5207b7SJohn Levon 
5981f5207b7SJohn Levon 	two = get_argument_from_call_expr(call->args, 1);
5991f5207b7SJohn Levon 	if (!two || two->type != EXPR_STRING) {
6001f5207b7SJohn Levon 		sm_msg("expected: __smatch_type_rl(type, \"string\")");
6011f5207b7SJohn Levon 		return 0;
6021f5207b7SJohn Levon 	}
6031f5207b7SJohn Levon 	call_results_to_rl(call, type, two->string->data, rl);
6041f5207b7SJohn Levon 	return 1;
6051f5207b7SJohn Levon }
6061f5207b7SJohn Levon 
print_left_right(struct sm_state * sm)6071f5207b7SJohn Levon static void print_left_right(struct sm_state *sm)
6081f5207b7SJohn Levon {
6091f5207b7SJohn Levon 	if (!sm)
6101f5207b7SJohn Levon 		return;
6111f5207b7SJohn Levon 	if (!sm->left && !sm->right)
6121f5207b7SJohn Levon 		return;
6131f5207b7SJohn Levon 
6141f5207b7SJohn Levon 	sm_printf("[ ");
6151f5207b7SJohn Levon 	if (sm->left)
6161f5207b7SJohn Levon 		sm_printf("(%d: %s->'%s')", get_stree_id(sm->left->pool),  sm->left->name, sm->left->state->name);
6171f5207b7SJohn Levon 	else
6181f5207b7SJohn Levon 		sm_printf(" - ");
6191f5207b7SJohn Levon 
6201f5207b7SJohn Levon 
6211f5207b7SJohn Levon 	print_left_right(sm->left);
6221f5207b7SJohn Levon 
6231f5207b7SJohn Levon 	if (sm->right)
6241f5207b7SJohn Levon 		sm_printf("(%d: %s->'%s')", get_stree_id(sm->right->pool),  sm->right->name, sm->right->state->name);
6251f5207b7SJohn Levon 	else
6261f5207b7SJohn Levon 		sm_printf(" - ");
6271f5207b7SJohn Levon 
6281f5207b7SJohn Levon 	print_left_right(sm->right);
6291f5207b7SJohn Levon }
6301f5207b7SJohn Levon 
match_print_merge_tree(const char * fn,struct expression * expr,void * info)6311f5207b7SJohn Levon static void match_print_merge_tree(const char *fn, struct expression *expr, void *info)
6321f5207b7SJohn Levon {
6331f5207b7SJohn Levon 	struct sm_state *sm;
6341f5207b7SJohn Levon 	struct expression *arg;
6351f5207b7SJohn Levon 	char *name;
6361f5207b7SJohn Levon 
6371f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
6381f5207b7SJohn Levon 	name = expr_to_str(arg);
6391f5207b7SJohn Levon 
6401f5207b7SJohn Levon 	sm = get_sm_state_expr(SMATCH_EXTRA, arg);
6411f5207b7SJohn Levon 	if (!sm) {
6421f5207b7SJohn Levon 		sm_msg("no sm state for '%s'", name);
6431f5207b7SJohn Levon 		goto free;
6441f5207b7SJohn Levon 	}
6451f5207b7SJohn Levon 
6461f5207b7SJohn Levon 	sm_prefix();
6471f5207b7SJohn Levon 	sm_printf("merge tree: %s -> %s", name, sm->state->name);
6481f5207b7SJohn Levon 	print_left_right(sm);
6491f5207b7SJohn Levon 	sm_printf("\n");
6501f5207b7SJohn Levon 
6511f5207b7SJohn Levon free:
6521f5207b7SJohn Levon 	free_string(name);
6531f5207b7SJohn Levon }
6541f5207b7SJohn Levon 
match_print_stree_id(const char * fn,struct expression * expr,void * info)6551f5207b7SJohn Levon static void match_print_stree_id(const char *fn, struct expression *expr, void *info)
6561f5207b7SJohn Levon {
6571f5207b7SJohn Levon 	sm_msg("stree_id %d", __stree_id);
6581f5207b7SJohn Levon }
6591f5207b7SJohn Levon 
match_bits(const char * fn,struct expression * expr,void * _unused)660*6523a3aaSJohn Levon static void match_bits(const char *fn, struct expression *expr, void *_unused)
661*6523a3aaSJohn Levon {
662*6523a3aaSJohn Levon 	struct expression *arg;
663*6523a3aaSJohn Levon 	struct bit_info *info;
664*6523a3aaSJohn Levon 	char *name;
665*6523a3aaSJohn Levon 
666*6523a3aaSJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
667*6523a3aaSJohn Levon 	name = expr_to_str(arg);
668*6523a3aaSJohn Levon 
669*6523a3aaSJohn Levon 	info = get_bit_info(arg);
670*6523a3aaSJohn Levon 
671*6523a3aaSJohn Levon 	sm_msg("bit info '%s': definitely set 0x%llx.  possibly set 0x%llx.",
672*6523a3aaSJohn Levon 	       name, info->set, info->possible);
673*6523a3aaSJohn Levon }
674*6523a3aaSJohn Levon 
match_mtag(const char * fn,struct expression * expr,void * info)6751f5207b7SJohn Levon static void match_mtag(const char *fn, struct expression *expr, void *info)
6761f5207b7SJohn Levon {
6771f5207b7SJohn Levon 	struct expression *arg;
6781f5207b7SJohn Levon 	char *name;
6791f5207b7SJohn Levon 	mtag_t tag = 0;
680efe51d0cSJohn Levon 	int offset = 0;
6811f5207b7SJohn Levon 
6821f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
6831f5207b7SJohn Levon 	name = expr_to_str(arg);
684efe51d0cSJohn Levon 	expr_to_mtag_offset(arg, &tag, &offset);
685efe51d0cSJohn Levon 	sm_msg("mtag: '%s' => tag: %llu %d", name, tag, offset);
6861f5207b7SJohn Levon 	free_string(name);
6871f5207b7SJohn Levon }
6881f5207b7SJohn Levon 
match_mtag_data_offset(const char * fn,struct expression * expr,void * info)6891f5207b7SJohn Levon static void match_mtag_data_offset(const char *fn, struct expression *expr, void *info)
6901f5207b7SJohn Levon {
6911f5207b7SJohn Levon 	struct expression *arg;
6921f5207b7SJohn Levon 	char *name;
6931f5207b7SJohn Levon 	mtag_t tag = 0;
6941f5207b7SJohn Levon 	int offset = -1;
6951f5207b7SJohn Levon 
6961f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
6971f5207b7SJohn Levon 	name = expr_to_str(arg);
6981f5207b7SJohn Levon 	expr_to_mtag_offset(arg, &tag, &offset);
6991f5207b7SJohn Levon 	sm_msg("mtag: '%s' => tag: %lld, offset: %d", name, tag, offset);
7001f5207b7SJohn Levon 	free_string(name);
7011f5207b7SJohn Levon }
7021f5207b7SJohn Levon 
match_container(const char * fn,struct expression * expr,void * info)703efe51d0cSJohn Levon static void match_container(const char *fn, struct expression *expr, void *info)
704efe51d0cSJohn Levon {
705efe51d0cSJohn Levon 	struct expression *container, *x;
706efe51d0cSJohn Levon 	char *cont, *name, *str;
707efe51d0cSJohn Levon 
708efe51d0cSJohn Levon 	container = get_argument_from_call_expr(expr->args, 0);
709efe51d0cSJohn Levon 	x = get_argument_from_call_expr(expr->args, 1);
710efe51d0cSJohn Levon 
711efe51d0cSJohn Levon 	str = get_container_name(container, x);
712efe51d0cSJohn Levon 	cont = expr_to_str(container);
713efe51d0cSJohn Levon 	name = expr_to_str(x);
714efe51d0cSJohn Levon 	sm_msg("container: '%s' vs '%s' --> '%s'", cont, name, str);
715efe51d0cSJohn Levon 	free_string(cont);
716efe51d0cSJohn Levon 	free_string(name);
717efe51d0cSJohn Levon }
718efe51d0cSJohn Levon 
match_expr(const char * fn,struct expression * expr,void * info)719*6523a3aaSJohn Levon static void match_expr(const char *fn, struct expression *expr, void *info)
720*6523a3aaSJohn Levon {
721*6523a3aaSJohn Levon 	struct expression *arg, *str, *new;
722*6523a3aaSJohn Levon 	char *name, *new_name;
723*6523a3aaSJohn Levon 
724*6523a3aaSJohn Levon 	str = get_argument_from_call_expr(expr->args, 0);
725*6523a3aaSJohn Levon 	arg = get_argument_from_call_expr(expr->args, 1);
726*6523a3aaSJohn Levon 	if (!arg || !str)
727*6523a3aaSJohn Levon 		return;
728*6523a3aaSJohn Levon 
729*6523a3aaSJohn Levon 	if (str->type != EXPR_STRING)
730*6523a3aaSJohn Levon 		return;
731*6523a3aaSJohn Levon 
732*6523a3aaSJohn Levon 	new = gen_expression_from_key(arg, str->string->data);
733*6523a3aaSJohn Levon 	name = expr_to_str(arg);
734*6523a3aaSJohn Levon 	new_name = expr_to_str(new);
735*6523a3aaSJohn Levon 
736*6523a3aaSJohn Levon 	sm_msg("str = '%s', arg = '%s' expr = '%s'", str->string->data, name, new_name);
737*6523a3aaSJohn Levon 
738*6523a3aaSJohn Levon 	free_string(new_name);
739*6523a3aaSJohn Levon 	free_string(name);
740*6523a3aaSJohn Levon }
match_state_count(const char * fn,struct expression * expr,void * info)7411f5207b7SJohn Levon static void match_state_count(const char *fn, struct expression *expr, void *info)
7421f5207b7SJohn Levon {
7431f5207b7SJohn Levon 	sm_msg("state_count = %d\n", sm_state_counter);
7441f5207b7SJohn Levon }
7451f5207b7SJohn Levon 
match_mem(const char * fn,struct expression * expr,void * info)7461f5207b7SJohn Levon static void match_mem(const char *fn, struct expression *expr, void *info)
7471f5207b7SJohn Levon {
7481f5207b7SJohn Levon 	show_sname_alloc();
749c85f09ccSJohn Levon 	show_data_range_alloc();
750c85f09ccSJohn Levon 	show_rl_ptrlist_alloc();
7511f5207b7SJohn Levon 	show_ptrlist_alloc();
7521f5207b7SJohn Levon 	sm_msg("%lu pools", get_pool_count());
7531f5207b7SJohn Levon 	sm_msg("%d strees", unfree_stree);
7541f5207b7SJohn Levon 	show_smatch_state_alloc();
7551f5207b7SJohn Levon 	show_sm_state_alloc();
7561f5207b7SJohn Levon }
7571f5207b7SJohn Levon 
match_exit(const char * fn,struct expression * expr,void * info)7581f5207b7SJohn Levon static void match_exit(const char *fn, struct expression *expr, void *info)
7591f5207b7SJohn Levon {
7601f5207b7SJohn Levon 	exit(0);
7611f5207b7SJohn Levon }
7621f5207b7SJohn Levon 
7631f5207b7SJohn Levon static struct stree *old_stree;
trace_var(struct statement * stmt)7641f5207b7SJohn Levon static void trace_var(struct statement *stmt)
7651f5207b7SJohn Levon {
7661f5207b7SJohn Levon 	struct sm_state *sm, *old;
7671f5207b7SJohn Levon 	int printed = 0;
7681f5207b7SJohn Levon 
7691f5207b7SJohn Levon 	if (!trace_variable)
7701f5207b7SJohn Levon 		return;
7711f5207b7SJohn Levon 	if (__inline_fn)
7721f5207b7SJohn Levon 		return;
7731f5207b7SJohn Levon 
7741f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
7751f5207b7SJohn Levon 		if (strcmp(sm->name, trace_variable) != 0)
7761f5207b7SJohn Levon 			continue;
7771f5207b7SJohn Levon 		old = get_sm_state_stree(old_stree, sm->owner, sm->name, sm->sym);
7781f5207b7SJohn Levon 		if (old && old->state == sm->state)
7791f5207b7SJohn Levon 			continue;
7801f5207b7SJohn Levon 		sm_msg("[%d] %s '%s': '%s' => '%s'", stmt->type,
7811f5207b7SJohn Levon 		       check_name(sm->owner),
7821f5207b7SJohn Levon 		       sm->name, old ? old->state->name : "<none>", sm->state->name);
7831f5207b7SJohn Levon 		printed = 1;
7841f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
7851f5207b7SJohn Levon 
7861f5207b7SJohn Levon 	if (printed) {
7871f5207b7SJohn Levon 		free_stree(&old_stree);
7881f5207b7SJohn Levon 		old_stree = clone_stree(__get_cur_stree());
7891f5207b7SJohn Levon 	}
7901f5207b7SJohn Levon }
7911f5207b7SJohn Levon 
free_old_stree(struct symbol * sym)7921f5207b7SJohn Levon static void free_old_stree(struct symbol *sym)
7931f5207b7SJohn Levon {
7941f5207b7SJohn Levon 	free_stree(&old_stree);
7951f5207b7SJohn Levon }
7961f5207b7SJohn Levon 
check_debug(int id)7971f5207b7SJohn Levon void check_debug(int id)
7981f5207b7SJohn Levon {
7991f5207b7SJohn Levon 	my_id = id;
8001f5207b7SJohn Levon 	add_function_hook("__smatch_about", &match_about, NULL);
8011f5207b7SJohn Levon 	add_function_hook("__smatch_all_values", &match_all_values, NULL);
8021f5207b7SJohn Levon 	add_function_hook("__smatch_state", &match_state, NULL);
8031f5207b7SJohn Levon 	add_function_hook("__smatch_states", &match_states, NULL);
8041f5207b7SJohn Levon 	add_function_hook("__smatch_value", &match_print_value, NULL);
8051f5207b7SJohn Levon 	add_function_hook("__smatch_known", &match_print_known, NULL);
8061f5207b7SJohn Levon 	add_function_hook("__smatch_implied", &match_print_implied, NULL);
8071f5207b7SJohn Levon 	add_function_hook("__smatch_implied_min", &match_print_implied_min, NULL);
8081f5207b7SJohn Levon 	add_function_hook("__smatch_implied_max", &match_print_implied_max, NULL);
8091f5207b7SJohn Levon 	add_function_hook("__smatch_user_rl", &match_user_rl, NULL);
8101f5207b7SJohn Levon 	add_function_hook("__smatch_capped", &match_capped, NULL);
8111f5207b7SJohn Levon 	add_function_hook("__smatch_hard_max", &match_print_hard_max, NULL);
8121f5207b7SJohn Levon 	add_function_hook("__smatch_fuzzy_max", &match_print_fuzzy_max, NULL);
8131f5207b7SJohn Levon 	add_function_hook("__smatch_absolute", &match_print_absolute, NULL);
8141f5207b7SJohn Levon 	add_function_hook("__smatch_absolute_min", &match_print_absolute_min, NULL);
8151f5207b7SJohn Levon 	add_function_hook("__smatch_absolute_max", &match_print_absolute_max, NULL);
8161f5207b7SJohn Levon 	add_function_hook("__smatch_real_absolute", &match_real_absolute, NULL);
8171f5207b7SJohn Levon 	add_function_hook("__smatch_sval_info", &match_sval_info, NULL);
8181f5207b7SJohn Levon 	add_function_hook("__smatch_member_name", &match_member_name, NULL);
8191f5207b7SJohn Levon 	add_function_hook("__smatch_possible", &match_possible, NULL);
8201f5207b7SJohn Levon 	add_function_hook("__smatch_cur_stree", &match_cur_stree, NULL);
8211f5207b7SJohn Levon 	add_function_hook("__smatch_strlen", &match_strlen, NULL);
8221f5207b7SJohn Levon 	add_function_hook("__smatch_buf_size", &match_buf_size, NULL);
8231f5207b7SJohn Levon 	add_function_hook("__smatch_note", &match_note, NULL);
8241f5207b7SJohn Levon 	add_function_hook("__smatch_dump_related", &match_dump_related, NULL);
8251f5207b7SJohn Levon 	add_function_hook("__smatch_compare", &match_compare, NULL);
8261f5207b7SJohn Levon 	add_function_hook("__smatch_debug_on", &match_debug_on, NULL);
8271f5207b7SJohn Levon 	add_function_hook("__smatch_debug_check", &match_debug_check, NULL);
8281f5207b7SJohn Levon 	add_function_hook("__smatch_debug_off", &match_debug_off, NULL);
8291f5207b7SJohn Levon 	add_function_hook("__smatch_local_debug_on", &match_local_debug_on, NULL);
8301f5207b7SJohn Levon 	add_function_hook("__smatch_local_debug_off", &match_local_debug_off, NULL);
8315a0e240fSJohn Levon 	add_function_hook("__smatch_debug_db_on", &match_debug_db_on, NULL);
8325a0e240fSJohn Levon 	add_function_hook("__smatch_debug_db_off", &match_debug_db_off, NULL);
8331f5207b7SJohn Levon 	add_function_hook("__smatch_intersection", &match_intersection, NULL);
8341f5207b7SJohn Levon 	add_function_hook("__smatch_type", &match_type, NULL);
8351f5207b7SJohn Levon 	add_implied_return_hook("__smatch_type_rl_helper", &match_type_rl_return, NULL);
8361f5207b7SJohn Levon 	add_function_hook("__smatch_merge_tree", &match_print_merge_tree, NULL);
8371f5207b7SJohn Levon 	add_function_hook("__smatch_stree_id", &match_print_stree_id, NULL);
838*6523a3aaSJohn Levon 	add_function_hook("__smatch_bits", &match_bits, NULL);
8391f5207b7SJohn Levon 	add_function_hook("__smatch_mtag", &match_mtag, NULL);
8401f5207b7SJohn Levon 	add_function_hook("__smatch_mtag_data", &match_mtag_data_offset, NULL);
841*6523a3aaSJohn Levon 	add_function_hook("__smatch_expr", &match_expr, NULL);
8421f5207b7SJohn Levon 	add_function_hook("__smatch_state_count", &match_state_count, NULL);
8431f5207b7SJohn Levon 	add_function_hook("__smatch_mem", &match_mem, NULL);
8441f5207b7SJohn Levon 	add_function_hook("__smatch_exit", &match_exit, NULL);
845efe51d0cSJohn Levon 	add_function_hook("__smatch_container", &match_container, NULL);
8461f5207b7SJohn Levon 
8471f5207b7SJohn Levon 	add_hook(free_old_stree, AFTER_FUNC_HOOK);
8481f5207b7SJohn Levon 	add_hook(trace_var, STMT_HOOK_AFTER);
8491f5207b7SJohn Levon }
850