2 * Copyright (C) 2009 Dan Carpenter.
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.
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.
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
19 * This script is for finding functions like hcd_buffer_free() which free
20 * their arguments. After running it, add those functions to check_memory.c
24 #include "smatch_slist.h"
30 static struct symbol
*this_func
;
31 static struct tracker_list
*putted_args
= NULL
;
33 static void match_function_def(struct symbol
*sym
)
38 static int parent_is_arg(struct symbol
*sym
)
42 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
45 } END_FOR_EACH_PTR(arg
);
49 static void match_put(const char *fn
, struct expression
*expr
, void *info
)
51 struct expression
*tmp
;
55 tmp
= get_argument_from_call_expr(expr
->args
, 0);
56 tmp
= strip_expr(tmp
);
57 name
= expr_to_var_sym(tmp
, &sym
);
59 if (parent_is_arg(sym
) && sym
->ident
)
60 set_state(my_id
, sym
->ident
->name
, sym
, &putted
);
63 static int return_count
= 0;
64 static void match_return(struct expression
*ret_value
)
66 struct state_list
*slist
;
68 struct tracker
*tracker
;
74 slist
= get_all_states(my_id
);
75 FOR_EACH_PTR(slist
, tmp
) {
76 if (tmp
->state
== &putted
)
77 add_tracker(&putted_args
, my_id
, tmp
->name
,
79 } END_FOR_EACH_PTR(tmp
);
82 FOR_EACH_PTR(putted_args
, tracker
) {
83 tmp
= get_sm_state(my_id
, tracker
->name
, tracker
->sym
);
84 if (tmp
&& tmp
->state
!= &putted
)
85 del_tracker(&putted_args
, my_id
, tracker
->name
,
87 } END_FOR_EACH_PTR(tracker
);
92 static void print_arg(struct symbol
*sym
)
97 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
99 sm_info("puts_arg %s %d", get_function(), i
);
103 } END_FOR_EACH_PTR(arg
);
106 static void match_end_func(struct symbol
*sym
)
108 struct tracker
*tracker
;
115 FOR_EACH_PTR(putted_args
, tracker
) {
116 print_arg(tracker
->sym
);
117 } END_FOR_EACH_PTR(tracker
);
119 free_trackers_and_list(&putted_args
);
123 void check_puts_argument(int id
)
125 if (!option_info
|| option_project
!= PROJ_KERNEL
)
129 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
130 add_function_hook("kobject_put", &match_put
, NULL
);
131 add_function_hook("kref_put", &match_put
, NULL
);
132 add_hook(&match_return
, RETURN_HOOK
);
133 add_hook(&match_end_func
, END_FUNC_HOOK
);