2 * sparse/check_frees_argument.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * This script is for finding functions like hcd_buffer_free() which free
12 * their arguments. After running it, add those functions to check_memory.c
16 #include "smatch_slist.h"
22 static struct symbol
*this_func
;
23 static struct tracker_list
*freed_args
= NULL
;
25 static void match_function_def(struct symbol
*sym
)
30 static int is_arg(char *name
, struct symbol
*sym
)
35 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
36 arg_name
= (arg
->ident
?arg
->ident
->name
:"-");
37 if (sym
== arg
&& !strcmp(name
, arg_name
))
39 } END_FOR_EACH_PTR(arg
);
43 static void match_kfree(const char *fn
, struct expression
*expr
, void *info
)
45 struct expression
*tmp
;
49 tmp
= get_argument_from_call_expr(expr
->args
, 0);
50 tmp
= strip_expr(tmp
);
51 name
= expr_to_var_sym(tmp
, &sym
);
52 if (is_arg(name
, sym
)) {
53 set_state(my_id
, name
, sym
, &freed
);
58 static int return_count
= 0;
59 static void match_return(struct expression
*ret_value
)
61 struct state_list
*slist
;
63 struct tracker
*tracker
;
69 slist
= get_all_states(my_id
);
70 FOR_EACH_PTR(slist
, tmp
) {
71 if (tmp
->state
== &freed
)
72 add_tracker(&freed_args
, my_id
, tmp
->name
,
74 } END_FOR_EACH_PTR(tmp
);
77 FOR_EACH_PTR(freed_args
, tracker
) {
78 tmp
= get_sm_state(my_id
, tracker
->name
, tracker
->sym
);
79 if (tmp
&& tmp
->state
!= &freed
)
80 del_tracker(&freed_args
, my_id
, tracker
->name
,
82 } END_FOR_EACH_PTR(tracker
);
87 static void print_arg(struct symbol
*sym
)
92 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
94 sm_info("free_arg %s %d", get_function(), i
);
98 } END_FOR_EACH_PTR(arg
);
101 static void match_end_func(struct symbol
*sym
)
103 struct tracker
*tracker
;
110 FOR_EACH_PTR(freed_args
, tracker
) {
111 print_arg(tracker
->sym
);
112 } END_FOR_EACH_PTR(tracker
);
114 free_trackers_and_list(&freed_args
);
118 void check_frees_argument(int id
)
124 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
125 if (option_project
== PROJ_KERNEL
)
126 add_function_hook("kfree", &match_kfree
, NULL
);
128 add_function_hook("free", &match_kfree
, NULL
);
129 add_hook(&match_return
, RETURN_HOOK
);
130 add_hook(&match_end_func
, END_FUNC_HOOK
);