1*1f5207b7SJohn Levon /*
2*1f5207b7SJohn Levon  * Copyright (C) 2009 Dan Carpenter.
3*1f5207b7SJohn Levon  *
4*1f5207b7SJohn Levon  * This program is free software; you can redistribute it and/or
5*1f5207b7SJohn Levon  * modify it under the terms of the GNU General Public License
6*1f5207b7SJohn Levon  * as published by the Free Software Foundation; either version 2
7*1f5207b7SJohn Levon  * of the License, or (at your option) any later version.
8*1f5207b7SJohn Levon  *
9*1f5207b7SJohn Levon  * This program is distributed in the hope that it will be useful,
10*1f5207b7SJohn Levon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*1f5207b7SJohn Levon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*1f5207b7SJohn Levon  * GNU General Public License for more details.
13*1f5207b7SJohn Levon  *
14*1f5207b7SJohn Levon  * You should have received a copy of the GNU General Public License
15*1f5207b7SJohn Levon  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16*1f5207b7SJohn Levon  */
17*1f5207b7SJohn Levon 
18*1f5207b7SJohn Levon #include "smatch.h"
19*1f5207b7SJohn Levon #include "smatch_slist.h"
20*1f5207b7SJohn Levon #include "smatch_extra.h"
21*1f5207b7SJohn Levon 
22*1f5207b7SJohn Levon int local_debug;
23*1f5207b7SJohn Levon static int my_id;
24*1f5207b7SJohn Levon char *trace_variable;
25*1f5207b7SJohn Levon 
26*1f5207b7SJohn Levon static void match_all_values(const char *fn, struct expression *expr, void *info)
27*1f5207b7SJohn Levon {
28*1f5207b7SJohn Levon 	struct stree *stree;
29*1f5207b7SJohn Levon 
30*1f5207b7SJohn Levon 	stree = get_all_states_stree(SMATCH_EXTRA);
31*1f5207b7SJohn Levon 	__print_stree(stree);
32*1f5207b7SJohn Levon 	free_stree(&stree);
33*1f5207b7SJohn Levon }
34*1f5207b7SJohn Levon 
35*1f5207b7SJohn Levon static void match_cur_stree(const char *fn, struct expression *expr, void *info)
36*1f5207b7SJohn Levon {
37*1f5207b7SJohn Levon 	__print_cur_stree();
38*1f5207b7SJohn Levon }
39*1f5207b7SJohn Levon 
40*1f5207b7SJohn Levon static void match_state(const char *fn, struct expression *expr, void *info)
41*1f5207b7SJohn Levon {
42*1f5207b7SJohn Levon 	struct expression *check_arg, *state_arg;
43*1f5207b7SJohn Levon 	struct sm_state *sm;
44*1f5207b7SJohn Levon 	int found = 0;
45*1f5207b7SJohn Levon 
46*1f5207b7SJohn Levon 	check_arg = get_argument_from_call_expr(expr->args, 0);
47*1f5207b7SJohn Levon 	if (check_arg->type != EXPR_STRING) {
48*1f5207b7SJohn Levon 		sm_error("the check_name argument to %s is supposed to be a string literal", fn);
49*1f5207b7SJohn Levon 		return;
50*1f5207b7SJohn Levon 	}
51*1f5207b7SJohn Levon 	state_arg = get_argument_from_call_expr(expr->args, 1);
52*1f5207b7SJohn Levon 	if (!state_arg || state_arg->type != EXPR_STRING) {
53*1f5207b7SJohn Levon 		sm_error("the state_name argument to %s is supposed to be a string literal", fn);
54*1f5207b7SJohn Levon 		return;
55*1f5207b7SJohn Levon 	}
56*1f5207b7SJohn Levon 
57*1f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
58*1f5207b7SJohn Levon 		if (strcmp(check_name(sm->owner), check_arg->string->data) != 0)
59*1f5207b7SJohn Levon 			continue;
60*1f5207b7SJohn Levon 		if (strcmp(sm->name, state_arg->string->data) != 0)
61*1f5207b7SJohn Levon 			continue;
62*1f5207b7SJohn Levon 		sm_msg("'%s' = '%s'", sm->name, sm->state->name);
63*1f5207b7SJohn Levon 		found = 1;
64*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
65*1f5207b7SJohn Levon 
66*1f5207b7SJohn Levon 	if (!found)
67*1f5207b7SJohn Levon 		sm_msg("%s '%s' not found", check_arg->string->data, state_arg->string->data);
68*1f5207b7SJohn Levon }
69*1f5207b7SJohn Levon 
70*1f5207b7SJohn Levon static void match_states(const char *fn, struct expression *expr, void *info)
71*1f5207b7SJohn Levon {
72*1f5207b7SJohn Levon 	struct expression *check_arg;
73*1f5207b7SJohn Levon 	struct sm_state *sm;
74*1f5207b7SJohn Levon 	int found = 0;
75*1f5207b7SJohn Levon 
76*1f5207b7SJohn Levon 	check_arg = get_argument_from_call_expr(expr->args, 0);
77*1f5207b7SJohn Levon 	if (check_arg->type != EXPR_STRING) {
78*1f5207b7SJohn Levon 		sm_error("the check_name argument to %s is supposed to be a string literal", fn);
79*1f5207b7SJohn Levon 		return;
80*1f5207b7SJohn Levon 	}
81*1f5207b7SJohn Levon 
82*1f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
83*1f5207b7SJohn Levon 		if (strcmp(check_name(sm->owner), check_arg->string->data) != 0)
84*1f5207b7SJohn Levon 			continue;
85*1f5207b7SJohn Levon 		sm_msg("%s", show_sm(sm));
86*1f5207b7SJohn Levon 		found = 1;
87*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
88*1f5207b7SJohn Levon 
89*1f5207b7SJohn Levon 	if (found)
90*1f5207b7SJohn Levon 		return;
91*1f5207b7SJohn Levon 
92*1f5207b7SJohn Levon 	if (!id_from_name(check_arg->string->data))
93*1f5207b7SJohn Levon 		sm_msg("invalid check name '%s'", check_arg->string->data);
94*1f5207b7SJohn Levon 	else
95*1f5207b7SJohn Levon 		sm_msg("%s: no states", check_arg->string->data);
96*1f5207b7SJohn Levon }
97*1f5207b7SJohn Levon 
98*1f5207b7SJohn Levon static void match_print_value(const char *fn, struct expression *expr, void *info)
99*1f5207b7SJohn Levon {
100*1f5207b7SJohn Levon 	struct stree *stree;
101*1f5207b7SJohn Levon 	struct sm_state *tmp;
102*1f5207b7SJohn Levon 	struct expression *arg_expr;
103*1f5207b7SJohn Levon 
104*1f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
105*1f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
106*1f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
107*1f5207b7SJohn Levon 		return;
108*1f5207b7SJohn Levon 	}
109*1f5207b7SJohn Levon 
110*1f5207b7SJohn Levon 	stree = __get_cur_stree();
111*1f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
112*1f5207b7SJohn Levon 		if (!strcmp(tmp->name, arg_expr->string->data))
113*1f5207b7SJohn Levon 			sm_msg("%s = %s", tmp->name, tmp->state->name);
114*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
115*1f5207b7SJohn Levon }
116*1f5207b7SJohn Levon 
117*1f5207b7SJohn Levon static void match_print_known(const char *fn, struct expression *expr, void *info)
118*1f5207b7SJohn Levon {
119*1f5207b7SJohn Levon 	struct expression *arg;
120*1f5207b7SJohn Levon 	struct range_list *rl = NULL;
121*1f5207b7SJohn Levon 	char *name;
122*1f5207b7SJohn Levon 	int known = 0;
123*1f5207b7SJohn Levon 	sval_t sval;
124*1f5207b7SJohn Levon 
125*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
126*1f5207b7SJohn Levon 	if (get_value(arg, &sval))
127*1f5207b7SJohn Levon 		known = 1;
128*1f5207b7SJohn Levon 
129*1f5207b7SJohn Levon 	get_implied_rl(arg, &rl);
130*1f5207b7SJohn Levon 
131*1f5207b7SJohn Levon 	name = expr_to_str(arg);
132*1f5207b7SJohn Levon 	sm_msg("known: '%s' = '%s'.  implied = '%s'", name, known ? sval_to_str(sval) : "<unknown>", show_rl(rl));
133*1f5207b7SJohn Levon 	free_string(name);
134*1f5207b7SJohn Levon }
135*1f5207b7SJohn Levon 
136*1f5207b7SJohn Levon static void match_print_implied(const char *fn, struct expression *expr, void *info)
137*1f5207b7SJohn Levon {
138*1f5207b7SJohn Levon 	struct expression *arg;
139*1f5207b7SJohn Levon 	struct range_list *rl = NULL;
140*1f5207b7SJohn Levon 	char *name;
141*1f5207b7SJohn Levon 
142*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
143*1f5207b7SJohn Levon 	get_implied_rl(arg, &rl);
144*1f5207b7SJohn Levon 
145*1f5207b7SJohn Levon 	name = expr_to_str(arg);
146*1f5207b7SJohn Levon 	sm_msg("implied: %s = '%s'", name, show_rl(rl));
147*1f5207b7SJohn Levon 	free_string(name);
148*1f5207b7SJohn Levon }
149*1f5207b7SJohn Levon 
150*1f5207b7SJohn Levon static void match_real_absolute(const char *fn, struct expression *expr, void *info)
151*1f5207b7SJohn Levon {
152*1f5207b7SJohn Levon 	struct expression *arg;
153*1f5207b7SJohn Levon 	struct range_list *rl = NULL;
154*1f5207b7SJohn Levon 	char *name;
155*1f5207b7SJohn Levon 
156*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
157*1f5207b7SJohn Levon 	get_real_absolute_rl(arg, &rl);
158*1f5207b7SJohn Levon 
159*1f5207b7SJohn Levon 	name = expr_to_str(arg);
160*1f5207b7SJohn Levon 	sm_msg("real absolute: %s = '%s'", name, show_rl(rl));
161*1f5207b7SJohn Levon 	free_string(name);
162*1f5207b7SJohn Levon }
163*1f5207b7SJohn Levon 
164*1f5207b7SJohn Levon static void match_print_implied_min(const char *fn, struct expression *expr, void *info)
165*1f5207b7SJohn Levon {
166*1f5207b7SJohn Levon 	struct expression *arg;
167*1f5207b7SJohn Levon 	sval_t sval;
168*1f5207b7SJohn Levon 	char *name;
169*1f5207b7SJohn Levon 
170*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
171*1f5207b7SJohn Levon 	name = expr_to_str(arg);
172*1f5207b7SJohn Levon 
173*1f5207b7SJohn Levon 	if (get_implied_min(arg, &sval))
174*1f5207b7SJohn Levon 		sm_msg("implied min: %s = %s", name, sval_to_str(sval));
175*1f5207b7SJohn Levon 	else
176*1f5207b7SJohn Levon 		sm_msg("implied min: %s = <unknown>", name);
177*1f5207b7SJohn Levon 
178*1f5207b7SJohn Levon 	free_string(name);
179*1f5207b7SJohn Levon }
180*1f5207b7SJohn Levon 
181*1f5207b7SJohn Levon static void match_print_implied_max(const char *fn, struct expression *expr, void *info)
182*1f5207b7SJohn Levon {
183*1f5207b7SJohn Levon 	struct expression *arg;
184*1f5207b7SJohn Levon 	sval_t sval;
185*1f5207b7SJohn Levon 	char *name;
186*1f5207b7SJohn Levon 
187*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
188*1f5207b7SJohn Levon 	name = expr_to_str(arg);
189*1f5207b7SJohn Levon 
190*1f5207b7SJohn Levon 	if (get_implied_max(arg, &sval))
191*1f5207b7SJohn Levon 		sm_msg("implied max: %s = %s", name, sval_to_str(sval));
192*1f5207b7SJohn Levon 	else
193*1f5207b7SJohn Levon 		sm_msg("implied max: %s = <unknown>", name);
194*1f5207b7SJohn Levon 
195*1f5207b7SJohn Levon 	free_string(name);
196*1f5207b7SJohn Levon }
197*1f5207b7SJohn Levon 
198*1f5207b7SJohn Levon static void match_user_rl(const char *fn, struct expression *expr, void *info)
199*1f5207b7SJohn Levon {
200*1f5207b7SJohn Levon 	struct expression *arg;
201*1f5207b7SJohn Levon 	struct range_list *rl;
202*1f5207b7SJohn Levon 	char *name;
203*1f5207b7SJohn Levon 
204*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
205*1f5207b7SJohn Levon 	name = expr_to_str(arg);
206*1f5207b7SJohn Levon 
207*1f5207b7SJohn Levon 	get_user_rl(arg, &rl);
208*1f5207b7SJohn Levon 	sm_msg("user rl: '%s' = '%s'", name, show_rl(rl));
209*1f5207b7SJohn Levon 
210*1f5207b7SJohn Levon 	free_string(name);
211*1f5207b7SJohn Levon }
212*1f5207b7SJohn Levon 
213*1f5207b7SJohn Levon static void match_capped(const char *fn, struct expression *expr, void *info)
214*1f5207b7SJohn Levon {
215*1f5207b7SJohn Levon 	struct expression *arg;
216*1f5207b7SJohn Levon 	char *name;
217*1f5207b7SJohn Levon 
218*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
219*1f5207b7SJohn Levon 	name = expr_to_str(arg);
220*1f5207b7SJohn Levon 	sm_msg("'%s' = '%s'", name, is_capped(arg) ? "capped" : "not capped");
221*1f5207b7SJohn Levon 	free_string(name);
222*1f5207b7SJohn Levon }
223*1f5207b7SJohn Levon 
224*1f5207b7SJohn Levon static void match_print_hard_max(const char *fn, struct expression *expr, void *info)
225*1f5207b7SJohn Levon {
226*1f5207b7SJohn Levon 	struct expression *arg;
227*1f5207b7SJohn Levon 	sval_t sval;
228*1f5207b7SJohn Levon 	char *name;
229*1f5207b7SJohn Levon 
230*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
231*1f5207b7SJohn Levon 	name = expr_to_str(arg);
232*1f5207b7SJohn Levon 
233*1f5207b7SJohn Levon 	if (get_hard_max(arg, &sval))
234*1f5207b7SJohn Levon 		sm_msg("hard max: %s = %s", name, sval_to_str(sval));
235*1f5207b7SJohn Levon 	else
236*1f5207b7SJohn Levon 		sm_msg("hard max: %s = <unknown>", name);
237*1f5207b7SJohn Levon 
238*1f5207b7SJohn Levon 	free_string(name);
239*1f5207b7SJohn Levon }
240*1f5207b7SJohn Levon 
241*1f5207b7SJohn Levon static void match_print_fuzzy_max(const char *fn, struct expression *expr, void *info)
242*1f5207b7SJohn Levon {
243*1f5207b7SJohn Levon 	struct expression *arg;
244*1f5207b7SJohn Levon 	sval_t sval;
245*1f5207b7SJohn Levon 	char *name;
246*1f5207b7SJohn Levon 
247*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
248*1f5207b7SJohn Levon 	name = expr_to_str(arg);
249*1f5207b7SJohn Levon 
250*1f5207b7SJohn Levon 	if (get_fuzzy_max(arg, &sval))
251*1f5207b7SJohn Levon 		sm_msg("fuzzy max: %s = %s", name, sval_to_str(sval));
252*1f5207b7SJohn Levon 	else
253*1f5207b7SJohn Levon 		sm_msg("fuzzy max: %s = <unknown>", name);
254*1f5207b7SJohn Levon 
255*1f5207b7SJohn Levon 	free_string(name);
256*1f5207b7SJohn Levon }
257*1f5207b7SJohn Levon 
258*1f5207b7SJohn Levon static void match_print_absolute(const char *fn, struct expression *expr, void *info)
259*1f5207b7SJohn Levon {
260*1f5207b7SJohn Levon 	struct expression *arg;
261*1f5207b7SJohn Levon 	struct range_list *rl;
262*1f5207b7SJohn Levon 	char *name;
263*1f5207b7SJohn Levon 
264*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
265*1f5207b7SJohn Levon 	name = expr_to_str(arg);
266*1f5207b7SJohn Levon 
267*1f5207b7SJohn Levon 	get_absolute_rl(arg, &rl);
268*1f5207b7SJohn Levon 	sm_msg("absolute: %s = %s", name, show_rl(rl));
269*1f5207b7SJohn Levon 
270*1f5207b7SJohn Levon 	free_string(name);
271*1f5207b7SJohn Levon }
272*1f5207b7SJohn Levon 
273*1f5207b7SJohn Levon static void match_print_absolute_min(const char *fn, struct expression *expr, void *info)
274*1f5207b7SJohn Levon {
275*1f5207b7SJohn Levon 	struct expression *arg;
276*1f5207b7SJohn Levon 	sval_t sval;
277*1f5207b7SJohn Levon 	char *name;
278*1f5207b7SJohn Levon 
279*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
280*1f5207b7SJohn Levon 	name = expr_to_str(arg);
281*1f5207b7SJohn Levon 
282*1f5207b7SJohn Levon 	if (get_absolute_min(arg, &sval))
283*1f5207b7SJohn Levon 		sm_msg("absolute min: %s = %s", name, sval_to_str(sval));
284*1f5207b7SJohn Levon 	else
285*1f5207b7SJohn Levon 		sm_msg("absolute min: %s = <unknown>", name);
286*1f5207b7SJohn Levon 
287*1f5207b7SJohn Levon 	free_string(name);
288*1f5207b7SJohn Levon }
289*1f5207b7SJohn Levon 
290*1f5207b7SJohn Levon static void match_print_absolute_max(const char *fn, struct expression *expr, void *info)
291*1f5207b7SJohn Levon {
292*1f5207b7SJohn Levon 	struct expression *arg;
293*1f5207b7SJohn Levon 	sval_t sval;
294*1f5207b7SJohn Levon 	char *name;
295*1f5207b7SJohn Levon 
296*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
297*1f5207b7SJohn Levon 	get_absolute_max(arg, &sval);
298*1f5207b7SJohn Levon 
299*1f5207b7SJohn Levon 	name = expr_to_str(arg);
300*1f5207b7SJohn Levon 	sm_msg("absolute max: %s = %s", name, sval_to_str(sval));
301*1f5207b7SJohn Levon 	free_string(name);
302*1f5207b7SJohn Levon }
303*1f5207b7SJohn Levon 
304*1f5207b7SJohn Levon static void match_sval_info(const char *fn, struct expression *expr, void *info)
305*1f5207b7SJohn Levon {
306*1f5207b7SJohn Levon 	struct expression *arg;
307*1f5207b7SJohn Levon 	sval_t sval;
308*1f5207b7SJohn Levon 	char *name;
309*1f5207b7SJohn Levon 
310*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
311*1f5207b7SJohn Levon 	name = expr_to_str(arg);
312*1f5207b7SJohn Levon 
313*1f5207b7SJohn Levon 	if (!get_implied_value(arg, &sval)) {
314*1f5207b7SJohn Levon 		sm_msg("no sval for '%s'", name);
315*1f5207b7SJohn Levon 		goto free;
316*1f5207b7SJohn Levon 	}
317*1f5207b7SJohn Levon 
318*1f5207b7SJohn Levon 	sm_msg("implied: %s %c%d ->value = %llx", name, sval_unsigned(sval) ? 'u' : 's', sval_bits(sval), sval.value);
319*1f5207b7SJohn Levon free:
320*1f5207b7SJohn Levon 	free_string(name);
321*1f5207b7SJohn Levon }
322*1f5207b7SJohn Levon 
323*1f5207b7SJohn Levon static void match_member_name(const char *fn, struct expression *expr, void *info)
324*1f5207b7SJohn Levon {
325*1f5207b7SJohn Levon 	struct expression *arg;
326*1f5207b7SJohn Levon 	char *name, *member_name;
327*1f5207b7SJohn Levon 
328*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
329*1f5207b7SJohn Levon 	name = expr_to_str(arg);
330*1f5207b7SJohn Levon 	member_name = get_member_name(arg);
331*1f5207b7SJohn Levon 	sm_msg("member name: '%s => %s'", name, member_name);
332*1f5207b7SJohn Levon 	free_string(member_name);
333*1f5207b7SJohn Levon 	free_string(name);
334*1f5207b7SJohn Levon }
335*1f5207b7SJohn Levon 
336*1f5207b7SJohn Levon static void print_possible(struct sm_state *sm)
337*1f5207b7SJohn Levon {
338*1f5207b7SJohn Levon 	struct sm_state *tmp;
339*1f5207b7SJohn Levon 
340*1f5207b7SJohn Levon 	sm_msg("Possible values for %s", sm->name);
341*1f5207b7SJohn Levon 	FOR_EACH_PTR(sm->possible, tmp) {
342*1f5207b7SJohn Levon 		printf("%s\n", tmp->state->name);
343*1f5207b7SJohn Levon 	} END_FOR_EACH_PTR(tmp);
344*1f5207b7SJohn Levon 	sm_msg("===");
345*1f5207b7SJohn Levon }
346*1f5207b7SJohn Levon 
347*1f5207b7SJohn Levon static void match_possible(const char *fn, struct expression *expr, void *info)
348*1f5207b7SJohn Levon {
349*1f5207b7SJohn Levon 	struct stree *stree;
350*1f5207b7SJohn Levon 	struct sm_state *tmp;
351*1f5207b7SJohn Levon 	struct expression *arg_expr;
352*1f5207b7SJohn Levon 
353*1f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
354*1f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
355*1f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
356*1f5207b7SJohn Levon 		return;
357*1f5207b7SJohn Levon 	}
358*1f5207b7SJohn Levon 
359*1f5207b7SJohn Levon 	stree = __get_cur_stree();
360*1f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
361*1f5207b7SJohn Levon 		if (!strcmp(tmp->name, arg_expr->string->data))
362*1f5207b7SJohn Levon 			print_possible(tmp);
363*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
364*1f5207b7SJohn Levon }
365*1f5207b7SJohn Levon 
366*1f5207b7SJohn Levon static void match_strlen(const char *fn, struct expression *expr, void *info)
367*1f5207b7SJohn Levon {
368*1f5207b7SJohn Levon 	struct expression *arg;
369*1f5207b7SJohn Levon 	struct range_list *rl;
370*1f5207b7SJohn Levon 	char *name;
371*1f5207b7SJohn Levon 
372*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
373*1f5207b7SJohn Levon 	get_implied_strlen(arg, &rl);
374*1f5207b7SJohn Levon 
375*1f5207b7SJohn Levon 	name = expr_to_str(arg);
376*1f5207b7SJohn Levon 	sm_msg("strlen: '%s' %s characters", name, show_rl(rl));
377*1f5207b7SJohn Levon 	free_string(name);
378*1f5207b7SJohn Levon }
379*1f5207b7SJohn Levon 
380*1f5207b7SJohn Levon static void match_buf_size(const char *fn, struct expression *expr, void *info)
381*1f5207b7SJohn Levon {
382*1f5207b7SJohn Levon 	struct expression *arg, *comp;
383*1f5207b7SJohn Levon 	struct range_list *rl;
384*1f5207b7SJohn Levon 	int elements, bytes;
385*1f5207b7SJohn Levon 	char *name;
386*1f5207b7SJohn Levon 	char buf[256] = "";
387*1f5207b7SJohn Levon 	int n;
388*1f5207b7SJohn Levon 	sval_t sval;
389*1f5207b7SJohn Levon 
390*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
391*1f5207b7SJohn Levon 
392*1f5207b7SJohn Levon 	elements = get_array_size(arg);
393*1f5207b7SJohn Levon 	bytes = get_array_size_bytes_max(arg);
394*1f5207b7SJohn Levon 	rl = get_array_size_bytes_rl(arg);
395*1f5207b7SJohn Levon 	comp = get_size_variable(arg);
396*1f5207b7SJohn Levon 
397*1f5207b7SJohn Levon 	name = expr_to_str(arg);
398*1f5207b7SJohn Levon 	n = snprintf(buf, sizeof(buf), "buf size: '%s' %d elements, %d bytes", name, elements, bytes);
399*1f5207b7SJohn Levon 	free_string(name);
400*1f5207b7SJohn Levon 
401*1f5207b7SJohn Levon 	if (!rl_to_sval(rl, &sval))
402*1f5207b7SJohn Levon 		n += snprintf(buf + n, sizeof(buf) - n, " (rl = %s)", show_rl(rl));
403*1f5207b7SJohn Levon 
404*1f5207b7SJohn Levon 	if (comp) {
405*1f5207b7SJohn Levon 		name = expr_to_str(comp);
406*1f5207b7SJohn Levon 		snprintf(buf + n, sizeof(buf) - n, "[size_var=%s]", name);
407*1f5207b7SJohn Levon 		free_string(name);
408*1f5207b7SJohn Levon 	}
409*1f5207b7SJohn Levon 	sm_msg("%s", buf);
410*1f5207b7SJohn Levon }
411*1f5207b7SJohn Levon 
412*1f5207b7SJohn Levon static void match_note(const char *fn, struct expression *expr, void *info)
413*1f5207b7SJohn Levon {
414*1f5207b7SJohn Levon 	struct expression *arg_expr;
415*1f5207b7SJohn Levon 
416*1f5207b7SJohn Levon 	arg_expr = get_argument_from_call_expr(expr->args, 0);
417*1f5207b7SJohn Levon 	if (arg_expr->type != EXPR_STRING) {
418*1f5207b7SJohn Levon 		sm_error("the argument to %s is supposed to be a string literal", fn);
419*1f5207b7SJohn Levon 		return;
420*1f5207b7SJohn Levon 	}
421*1f5207b7SJohn Levon 	sm_msg("%s", arg_expr->string->data);
422*1f5207b7SJohn Levon }
423*1f5207b7SJohn Levon 
424*1f5207b7SJohn Levon static void print_related(struct sm_state *sm)
425*1f5207b7SJohn Levon {
426*1f5207b7SJohn Levon 	struct relation *rel;
427*1f5207b7SJohn Levon 
428*1f5207b7SJohn Levon 	if (!estate_related(sm->state))
429*1f5207b7SJohn Levon 		return;
430*1f5207b7SJohn Levon 
431*1f5207b7SJohn Levon 	sm_prefix();
432*1f5207b7SJohn Levon 	sm_printf("%s: ", sm->name);
433*1f5207b7SJohn Levon 	FOR_EACH_PTR(estate_related(sm->state), rel) {
434*1f5207b7SJohn Levon 		sm_printf("%s ", rel->name);
435*1f5207b7SJohn Levon 	} END_FOR_EACH_PTR(rel);
436*1f5207b7SJohn Levon 	sm_printf("\n");
437*1f5207b7SJohn Levon }
438*1f5207b7SJohn Levon 
439*1f5207b7SJohn Levon static void match_dump_related(const char *fn, struct expression *expr, void *info)
440*1f5207b7SJohn Levon {
441*1f5207b7SJohn Levon 	struct stree *stree;
442*1f5207b7SJohn Levon 	struct sm_state *tmp;
443*1f5207b7SJohn Levon 
444*1f5207b7SJohn Levon 	stree = __get_cur_stree();
445*1f5207b7SJohn Levon 	FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
446*1f5207b7SJohn Levon 		print_related(tmp);
447*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(tmp);
448*1f5207b7SJohn Levon }
449*1f5207b7SJohn Levon 
450*1f5207b7SJohn Levon static void match_compare(const char *fn, struct expression *expr, void *info)
451*1f5207b7SJohn Levon {
452*1f5207b7SJohn Levon 	struct expression *one, *two;
453*1f5207b7SJohn Levon 	char *one_name, *two_name;
454*1f5207b7SJohn Levon 	int comparison;
455*1f5207b7SJohn Levon 	char buf[16];
456*1f5207b7SJohn Levon 
457*1f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
458*1f5207b7SJohn Levon 	two = get_argument_from_call_expr(expr->args, 1);
459*1f5207b7SJohn Levon 
460*1f5207b7SJohn Levon 	comparison = get_comparison(one, two);
461*1f5207b7SJohn Levon 	if (!comparison)
462*1f5207b7SJohn Levon 		snprintf(buf, sizeof(buf), "<none>");
463*1f5207b7SJohn Levon 	else
464*1f5207b7SJohn Levon 		snprintf(buf, sizeof(buf), "%s", show_special(comparison));
465*1f5207b7SJohn Levon 
466*1f5207b7SJohn Levon 	one_name = expr_to_str(one);
467*1f5207b7SJohn Levon 	two_name = expr_to_str(two);
468*1f5207b7SJohn Levon 
469*1f5207b7SJohn Levon 	sm_msg("%s %s %s", one_name, buf, two_name);
470*1f5207b7SJohn Levon 
471*1f5207b7SJohn Levon 	free_string(one_name);
472*1f5207b7SJohn Levon 	free_string(two_name);
473*1f5207b7SJohn Levon }
474*1f5207b7SJohn Levon 
475*1f5207b7SJohn Levon static void match_debug_on(const char *fn, struct expression *expr, void *info)
476*1f5207b7SJohn Levon {
477*1f5207b7SJohn Levon 	option_debug = 1;
478*1f5207b7SJohn Levon }
479*1f5207b7SJohn Levon 
480*1f5207b7SJohn Levon static void match_debug_check(const char *fn, struct expression *expr, void *info)
481*1f5207b7SJohn Levon {
482*1f5207b7SJohn Levon 	struct expression *arg;
483*1f5207b7SJohn Levon 
484*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
485*1f5207b7SJohn Levon 	if (!arg || arg->type != EXPR_STRING)
486*1f5207b7SJohn Levon 		return;
487*1f5207b7SJohn Levon 	option_debug_check = arg->string->data;
488*1f5207b7SJohn Levon 	sm_msg("arg = '%s'", option_debug_check);
489*1f5207b7SJohn Levon }
490*1f5207b7SJohn Levon 
491*1f5207b7SJohn Levon static void match_debug_off(const char *fn, struct expression *expr, void *info)
492*1f5207b7SJohn Levon {
493*1f5207b7SJohn Levon 	option_debug_check = (char *)"";
494*1f5207b7SJohn Levon 	option_debug = 0;
495*1f5207b7SJohn Levon }
496*1f5207b7SJohn Levon 
497*1f5207b7SJohn Levon static void match_local_debug_on(const char *fn, struct expression *expr, void *info)
498*1f5207b7SJohn Levon {
499*1f5207b7SJohn Levon 	local_debug = 1;
500*1f5207b7SJohn Levon }
501*1f5207b7SJohn Levon 
502*1f5207b7SJohn Levon static void match_local_debug_off(const char *fn, struct expression *expr, void *info)
503*1f5207b7SJohn Levon {
504*1f5207b7SJohn Levon 	local_debug = 0;
505*1f5207b7SJohn Levon }
506*1f5207b7SJohn Levon 
507*1f5207b7SJohn Levon static void match_debug_implied_on(const char *fn, struct expression *expr, void *info)
508*1f5207b7SJohn Levon {
509*1f5207b7SJohn Levon 	option_debug_implied = 1;
510*1f5207b7SJohn Levon }
511*1f5207b7SJohn Levon 
512*1f5207b7SJohn Levon static void match_debug_implied_off(const char *fn, struct expression *expr, void *info)
513*1f5207b7SJohn Levon {
514*1f5207b7SJohn Levon 	option_debug_implied = 0;
515*1f5207b7SJohn Levon }
516*1f5207b7SJohn Levon 
517*1f5207b7SJohn Levon static void match_about(const char *fn, struct expression *expr, void *info)
518*1f5207b7SJohn Levon {
519*1f5207b7SJohn Levon 	struct expression *arg;
520*1f5207b7SJohn Levon 	struct sm_state *sm;
521*1f5207b7SJohn Levon 	char *name;
522*1f5207b7SJohn Levon 
523*1f5207b7SJohn Levon 	sm_msg("---- about ----");
524*1f5207b7SJohn Levon 	match_print_implied(fn, expr, NULL);
525*1f5207b7SJohn Levon 	match_buf_size(fn, expr, NULL);
526*1f5207b7SJohn Levon 	match_strlen(fn, expr, NULL);
527*1f5207b7SJohn Levon 	match_real_absolute(fn, expr, NULL);
528*1f5207b7SJohn Levon 
529*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
530*1f5207b7SJohn Levon 	name = expr_to_str(arg);
531*1f5207b7SJohn Levon 	if (!name) {
532*1f5207b7SJohn Levon 		sm_msg("info: not a straight forward variable.");
533*1f5207b7SJohn Levon 		return;
534*1f5207b7SJohn Levon 	}
535*1f5207b7SJohn Levon 
536*1f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
537*1f5207b7SJohn Levon 		if (strcmp(sm->name, name) != 0)
538*1f5207b7SJohn Levon 			continue;
539*1f5207b7SJohn Levon 		sm_msg("%s", show_sm(sm));
540*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
541*1f5207b7SJohn Levon }
542*1f5207b7SJohn Levon 
543*1f5207b7SJohn Levon static void match_intersection(const char *fn, struct expression *expr, void *info)
544*1f5207b7SJohn Levon {
545*1f5207b7SJohn Levon 	struct expression *one, *two;
546*1f5207b7SJohn Levon 	struct range_list *one_rl, *two_rl;
547*1f5207b7SJohn Levon 	struct range_list *res;
548*1f5207b7SJohn Levon 
549*1f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
550*1f5207b7SJohn Levon 	two = get_argument_from_call_expr(expr->args, 1);
551*1f5207b7SJohn Levon 
552*1f5207b7SJohn Levon 	get_absolute_rl(one, &one_rl);
553*1f5207b7SJohn Levon 	get_absolute_rl(two, &two_rl);
554*1f5207b7SJohn Levon 
555*1f5207b7SJohn Levon 	res = rl_intersection(one_rl, two_rl);
556*1f5207b7SJohn Levon 	sm_msg("'%s' intersect '%s' is '%s'", show_rl(one_rl), show_rl(two_rl), show_rl(res));
557*1f5207b7SJohn Levon }
558*1f5207b7SJohn Levon 
559*1f5207b7SJohn Levon static void match_type(const char *fn, struct expression *expr, void *info)
560*1f5207b7SJohn Levon {
561*1f5207b7SJohn Levon 	struct expression *one;
562*1f5207b7SJohn Levon 	struct symbol *type;
563*1f5207b7SJohn Levon 	char *name;
564*1f5207b7SJohn Levon 
565*1f5207b7SJohn Levon 	one = get_argument_from_call_expr(expr->args, 0);
566*1f5207b7SJohn Levon 	type = get_type(one);
567*1f5207b7SJohn Levon 	name = expr_to_str(one);
568*1f5207b7SJohn Levon 	sm_msg("type of '%s' is: '%s'", name, type_to_str(type));
569*1f5207b7SJohn Levon 	free_string(name);
570*1f5207b7SJohn Levon }
571*1f5207b7SJohn Levon 
572*1f5207b7SJohn Levon static int match_type_rl_return(struct expression *call, void *unused, struct range_list **rl)
573*1f5207b7SJohn Levon {
574*1f5207b7SJohn Levon 	struct expression *one, *two;
575*1f5207b7SJohn Levon 	struct symbol *type;
576*1f5207b7SJohn Levon 
577*1f5207b7SJohn Levon 	one = get_argument_from_call_expr(call->args, 0);
578*1f5207b7SJohn Levon 	type = get_type(one);
579*1f5207b7SJohn Levon 
580*1f5207b7SJohn Levon 	two = get_argument_from_call_expr(call->args, 1);
581*1f5207b7SJohn Levon 	if (!two || two->type != EXPR_STRING) {
582*1f5207b7SJohn Levon 		sm_msg("expected: __smatch_type_rl(type, \"string\")");
583*1f5207b7SJohn Levon 		return 0;
584*1f5207b7SJohn Levon 	}
585*1f5207b7SJohn Levon 	call_results_to_rl(call, type, two->string->data, rl);
586*1f5207b7SJohn Levon 	return 1;
587*1f5207b7SJohn Levon }
588*1f5207b7SJohn Levon 
589*1f5207b7SJohn Levon static void print_left_right(struct sm_state *sm)
590*1f5207b7SJohn Levon {
591*1f5207b7SJohn Levon 	if (!sm)
592*1f5207b7SJohn Levon 		return;
593*1f5207b7SJohn Levon 	if (!sm->left && !sm->right)
594*1f5207b7SJohn Levon 		return;
595*1f5207b7SJohn Levon 
596*1f5207b7SJohn Levon 	sm_printf("[ ");
597*1f5207b7SJohn Levon 	if (sm->left)
598*1f5207b7SJohn Levon 		sm_printf("(%d: %s->'%s')", get_stree_id(sm->left->pool),  sm->left->name, sm->left->state->name);
599*1f5207b7SJohn Levon 	else
600*1f5207b7SJohn Levon 		sm_printf(" - ");
601*1f5207b7SJohn Levon 
602*1f5207b7SJohn Levon 
603*1f5207b7SJohn Levon 	print_left_right(sm->left);
604*1f5207b7SJohn Levon 
605*1f5207b7SJohn Levon 	if (sm->right)
606*1f5207b7SJohn Levon 		sm_printf("(%d: %s->'%s')", get_stree_id(sm->right->pool),  sm->right->name, sm->right->state->name);
607*1f5207b7SJohn Levon 	else
608*1f5207b7SJohn Levon 		sm_printf(" - ");
609*1f5207b7SJohn Levon 
610*1f5207b7SJohn Levon 	print_left_right(sm->right);
611*1f5207b7SJohn Levon }
612*1f5207b7SJohn Levon 
613*1f5207b7SJohn Levon static void match_print_merge_tree(const char *fn, struct expression *expr, void *info)
614*1f5207b7SJohn Levon {
615*1f5207b7SJohn Levon 	struct sm_state *sm;
616*1f5207b7SJohn Levon 	struct expression *arg;
617*1f5207b7SJohn Levon 	char *name;
618*1f5207b7SJohn Levon 
619*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
620*1f5207b7SJohn Levon 	name = expr_to_str(arg);
621*1f5207b7SJohn Levon 
622*1f5207b7SJohn Levon 	sm = get_sm_state_expr(SMATCH_EXTRA, arg);
623*1f5207b7SJohn Levon 	if (!sm) {
624*1f5207b7SJohn Levon 		sm_msg("no sm state for '%s'", name);
625*1f5207b7SJohn Levon 		goto free;
626*1f5207b7SJohn Levon 	}
627*1f5207b7SJohn Levon 
628*1f5207b7SJohn Levon 	sm_prefix();
629*1f5207b7SJohn Levon 	sm_printf("merge tree: %s -> %s", name, sm->state->name);
630*1f5207b7SJohn Levon 	print_left_right(sm);
631*1f5207b7SJohn Levon 	sm_printf("\n");
632*1f5207b7SJohn Levon 
633*1f5207b7SJohn Levon free:
634*1f5207b7SJohn Levon 	free_string(name);
635*1f5207b7SJohn Levon }
636*1f5207b7SJohn Levon 
637*1f5207b7SJohn Levon static void match_print_stree_id(const char *fn, struct expression *expr, void *info)
638*1f5207b7SJohn Levon {
639*1f5207b7SJohn Levon 	sm_msg("stree_id %d", __stree_id);
640*1f5207b7SJohn Levon }
641*1f5207b7SJohn Levon 
642*1f5207b7SJohn Levon static void match_mtag(const char *fn, struct expression *expr, void *info)
643*1f5207b7SJohn Levon {
644*1f5207b7SJohn Levon 	struct expression *arg;
645*1f5207b7SJohn Levon 	char *name;
646*1f5207b7SJohn Levon 	mtag_t tag = 0;
647*1f5207b7SJohn Levon 
648*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
649*1f5207b7SJohn Levon 	name = expr_to_str(arg);
650*1f5207b7SJohn Levon 	get_mtag(arg, &tag);
651*1f5207b7SJohn Levon 	sm_msg("mtag: '%s' => tag: %lld", name, tag);
652*1f5207b7SJohn Levon 	free_string(name);
653*1f5207b7SJohn Levon }
654*1f5207b7SJohn Levon 
655*1f5207b7SJohn Levon static void match_mtag_data_offset(const char *fn, struct expression *expr, void *info)
656*1f5207b7SJohn Levon {
657*1f5207b7SJohn Levon 	struct expression *arg;
658*1f5207b7SJohn Levon 	char *name;
659*1f5207b7SJohn Levon 	mtag_t tag = 0;
660*1f5207b7SJohn Levon 	int offset = -1;
661*1f5207b7SJohn Levon 
662*1f5207b7SJohn Levon 	arg = get_argument_from_call_expr(expr->args, 0);
663*1f5207b7SJohn Levon 	name = expr_to_str(arg);
664*1f5207b7SJohn Levon 	expr_to_mtag_offset(arg, &tag, &offset);
665*1f5207b7SJohn Levon 	sm_msg("mtag: '%s' => tag: %lld, offset: %d", name, tag, offset);
666*1f5207b7SJohn Levon 	free_string(name);
667*1f5207b7SJohn Levon }
668*1f5207b7SJohn Levon 
669*1f5207b7SJohn Levon static void match_state_count(const char *fn, struct expression *expr, void *info)
670*1f5207b7SJohn Levon {
671*1f5207b7SJohn Levon 	sm_msg("state_count = %d\n", sm_state_counter);
672*1f5207b7SJohn Levon }
673*1f5207b7SJohn Levon 
674*1f5207b7SJohn Levon static void match_mem(const char *fn, struct expression *expr, void *info)
675*1f5207b7SJohn Levon {
676*1f5207b7SJohn Levon 	show_sname_alloc();
677*1f5207b7SJohn Levon 	show_ptrlist_alloc();
678*1f5207b7SJohn Levon 	sm_msg("%lu pools", get_pool_count());
679*1f5207b7SJohn Levon 	sm_msg("%d strees", unfree_stree);
680*1f5207b7SJohn Levon 	show_smatch_state_alloc();
681*1f5207b7SJohn Levon 	show_sm_state_alloc();
682*1f5207b7SJohn Levon }
683*1f5207b7SJohn Levon 
684*1f5207b7SJohn Levon static void match_exit(const char *fn, struct expression *expr, void *info)
685*1f5207b7SJohn Levon {
686*1f5207b7SJohn Levon 	exit(0);
687*1f5207b7SJohn Levon }
688*1f5207b7SJohn Levon 
689*1f5207b7SJohn Levon static struct stree *old_stree;
690*1f5207b7SJohn Levon static void trace_var(struct statement *stmt)
691*1f5207b7SJohn Levon {
692*1f5207b7SJohn Levon 	struct sm_state *sm, *old;
693*1f5207b7SJohn Levon 	int printed = 0;
694*1f5207b7SJohn Levon 
695*1f5207b7SJohn Levon 	if (!trace_variable)
696*1f5207b7SJohn Levon 		return;
697*1f5207b7SJohn Levon 	if (__inline_fn)
698*1f5207b7SJohn Levon 		return;
699*1f5207b7SJohn Levon 
700*1f5207b7SJohn Levon 	FOR_EACH_SM(__get_cur_stree(), sm) {
701*1f5207b7SJohn Levon 		if (strcmp(sm->name, trace_variable) != 0)
702*1f5207b7SJohn Levon 			continue;
703*1f5207b7SJohn Levon 		old = get_sm_state_stree(old_stree, sm->owner, sm->name, sm->sym);
704*1f5207b7SJohn Levon 		if (old && old->state == sm->state)
705*1f5207b7SJohn Levon 			continue;
706*1f5207b7SJohn Levon 		sm_msg("[%d] %s '%s': '%s' => '%s'", stmt->type,
707*1f5207b7SJohn Levon 		       check_name(sm->owner),
708*1f5207b7SJohn Levon 		       sm->name, old ? old->state->name : "<none>", sm->state->name);
709*1f5207b7SJohn Levon 		printed = 1;
710*1f5207b7SJohn Levon 	} END_FOR_EACH_SM(sm);
711*1f5207b7SJohn Levon 
712*1f5207b7SJohn Levon 	if (printed) {
713*1f5207b7SJohn Levon 		free_stree(&old_stree);
714*1f5207b7SJohn Levon 		old_stree = clone_stree(__get_cur_stree());
715*1f5207b7SJohn Levon 	}
716*1f5207b7SJohn Levon }
717*1f5207b7SJohn Levon 
718*1f5207b7SJohn Levon static void free_old_stree(struct symbol *sym)
719*1f5207b7SJohn Levon {
720*1f5207b7SJohn Levon 	free_stree(&old_stree);
721*1f5207b7SJohn Levon }
722*1f5207b7SJohn Levon 
723*1f5207b7SJohn Levon void check_debug(int id)
724*1f5207b7SJohn Levon {
725*1f5207b7SJohn Levon 	my_id = id;
726*1f5207b7SJohn Levon 	add_function_hook("__smatch_about", &match_about, NULL);
727*1f5207b7SJohn Levon 	add_function_hook("__smatch_all_values", &match_all_values, NULL);
728*1f5207b7SJohn Levon 	add_function_hook("__smatch_state", &match_state, NULL);
729*1f5207b7SJohn Levon 	add_function_hook("__smatch_states", &match_states, NULL);
730*1f5207b7SJohn Levon 	add_function_hook("__smatch_value", &match_print_value, NULL);
731*1f5207b7SJohn Levon 	add_function_hook("__smatch_known", &match_print_known, NULL);
732*1f5207b7SJohn Levon 	add_function_hook("__smatch_implied", &match_print_implied, NULL);
733*1f5207b7SJohn Levon 	add_function_hook("__smatch_implied_min", &match_print_implied_min, NULL);
734*1f5207b7SJohn Levon 	add_function_hook("__smatch_implied_max", &match_print_implied_max, NULL);
735*1f5207b7SJohn Levon 	add_function_hook("__smatch_user_rl", &match_user_rl, NULL);
736*1f5207b7SJohn Levon 	add_function_hook("__smatch_capped", &match_capped, NULL);
737*1f5207b7SJohn Levon 	add_function_hook("__smatch_hard_max", &match_print_hard_max, NULL);
738*1f5207b7SJohn Levon 	add_function_hook("__smatch_fuzzy_max", &match_print_fuzzy_max, NULL);
739*1f5207b7SJohn Levon 	add_function_hook("__smatch_absolute", &match_print_absolute, NULL);
740*1f5207b7SJohn Levon 	add_function_hook("__smatch_absolute_min", &match_print_absolute_min, NULL);
741*1f5207b7SJohn Levon 	add_function_hook("__smatch_absolute_max", &match_print_absolute_max, NULL);
742*1f5207b7SJohn Levon 	add_function_hook("__smatch_real_absolute", &match_real_absolute, NULL);
743*1f5207b7SJohn Levon 	add_function_hook("__smatch_sval_info", &match_sval_info, NULL);
744*1f5207b7SJohn Levon 	add_function_hook("__smatch_member_name", &match_member_name, NULL);
745*1f5207b7SJohn Levon 	add_function_hook("__smatch_possible", &match_possible, NULL);
746*1f5207b7SJohn Levon 	add_function_hook("__smatch_cur_stree", &match_cur_stree, NULL);
747*1f5207b7SJohn Levon 	add_function_hook("__smatch_strlen", &match_strlen, NULL);
748*1f5207b7SJohn Levon 	add_function_hook("__smatch_buf_size", &match_buf_size, NULL);
749*1f5207b7SJohn Levon 	add_function_hook("__smatch_note", &match_note, NULL);
750*1f5207b7SJohn Levon 	add_function_hook("__smatch_dump_related", &match_dump_related, NULL);
751*1f5207b7SJohn Levon 	add_function_hook("__smatch_compare", &match_compare, NULL);
752*1f5207b7SJohn Levon 	add_function_hook("__smatch_debug_on", &match_debug_on, NULL);
753*1f5207b7SJohn Levon 	add_function_hook("__smatch_debug_check", &match_debug_check, NULL);
754*1f5207b7SJohn Levon 	add_function_hook("__smatch_debug_off", &match_debug_off, NULL);
755*1f5207b7SJohn Levon 	add_function_hook("__smatch_local_debug_on", &match_local_debug_on, NULL);
756*1f5207b7SJohn Levon 	add_function_hook("__smatch_local_debug_off", &match_local_debug_off, NULL);
757*1f5207b7SJohn Levon 	add_function_hook("__smatch_debug_implied_on", &match_debug_implied_on, NULL);
758*1f5207b7SJohn Levon 	add_function_hook("__smatch_debug_implied_off", &match_debug_implied_off, NULL);
759*1f5207b7SJohn Levon 	add_function_hook("__smatch_intersection", &match_intersection, NULL);
760*1f5207b7SJohn Levon 	add_function_hook("__smatch_type", &match_type, NULL);
761*1f5207b7SJohn Levon 	add_implied_return_hook("__smatch_type_rl_helper", &match_type_rl_return, NULL);
762*1f5207b7SJohn Levon 	add_function_hook("__smatch_merge_tree", &match_print_merge_tree, NULL);
763*1f5207b7SJohn Levon 	add_function_hook("__smatch_stree_id", &match_print_stree_id, NULL);
764*1f5207b7SJohn Levon 	add_function_hook("__smatch_mtag", &match_mtag, NULL);
765*1f5207b7SJohn Levon 	add_function_hook("__smatch_mtag_data", &match_mtag_data_offset, NULL);
766*1f5207b7SJohn Levon 	add_function_hook("__smatch_state_count", &match_state_count, NULL);
767*1f5207b7SJohn Levon 	add_function_hook("__smatch_mem", &match_mem, NULL);
768*1f5207b7SJohn Levon 	add_function_hook("__smatch_exit", &match_exit, NULL);
769*1f5207b7SJohn Levon 
770*1f5207b7SJohn Levon 	add_hook(free_old_stree, AFTER_FUNC_HOOK);
771*1f5207b7SJohn Levon 	add_hook(trace_var, STMT_HOOK_AFTER);
772*1f5207b7SJohn Levon }
773