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
= get_variable_from_expr(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
;
66 slist
= get_all_states(my_id
);
67 FOR_EACH_PTR(slist
, tmp
) {
68 if (tmp
->state
== &freed
)
69 add_tracker(&freed_args
, my_id
, tmp
->name
,
71 } END_FOR_EACH_PTR(tmp
);
74 FOR_EACH_PTR(freed_args
, tracker
) {
75 tmp
= get_sm_state(my_id
, tracker
->name
, tracker
->sym
);
76 if (tmp
&& tmp
->state
!= &freed
)
77 del_tracker(&freed_args
, my_id
, tracker
->name
,
79 } END_FOR_EACH_PTR(tracker
);
84 static void print_arg(struct symbol
*sym
)
89 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
91 sm_info("free_arg %s %d", get_function(), i
);
95 } END_FOR_EACH_PTR(arg
);
98 static void match_end_func(struct symbol
*sym
)
100 struct tracker
*tracker
;
105 FOR_EACH_PTR(freed_args
, tracker
) {
106 print_arg(tracker
->sym
);
107 } END_FOR_EACH_PTR(tracker
);
109 free_trackers_and_list(&freed_args
);
113 void check_frees_argument(int id
)
119 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
120 if (option_project
== PROJ_KERNEL
)
121 add_function_hook("kfree", &match_kfree
, NULL
);
123 add_function_hook("free", &match_kfree
, NULL
);
124 add_hook(&match_return
, RETURN_HOOK
);
125 add_hook(&match_end_func
, END_FUNC_HOOK
);