1 /* 2 * Copyright (C) 2010 Dan Carpenter. 3 * 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. 8 * 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. 13 * 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 16 */ 17 18 /* 19 * I found a bug where someone released the wrong resource and wanted to 20 * prevent that from happening again. 21 * 22 */ 23 24 #include "smatch.h" 25 26 static int my_id; 27 28 static struct tracker_list *resource_list; 29 30 static void match_request(const char *fn, struct expression *expr, void *_arg_no) 31 { 32 struct expression *arg_expr; 33 int arg_no = PTR_INT(_arg_no); 34 char *name; 35 struct symbol *sym; 36 37 arg_expr = get_argument_from_call_expr(expr->args, arg_no); 38 arg_expr = strip_expr(arg_expr); 39 40 name = expr_to_var_sym(arg_expr, &sym); 41 if (!name || !sym) 42 goto free; 43 add_tracker(&resource_list, my_id, name, sym); 44 free: 45 free_string(name); 46 } 47 48 static void match_release(const char *fn, struct expression *expr, void *_arg_no) 49 { 50 struct expression *arg_expr; 51 int arg_no = PTR_INT(_arg_no); 52 char *name; 53 struct symbol *sym; 54 55 arg_expr = get_argument_from_call_expr(expr->args, arg_no); 56 arg_expr = strip_expr(arg_expr); 57 58 if (!resource_list) 59 return; 60 61 name = expr_to_var_sym(arg_expr, &sym); 62 if (!name || !sym) 63 goto free; 64 if (in_tracker_list(resource_list, my_id, name, sym)) 65 goto free; 66 sm_warning("'%s' was not one of the resources you requested", name); 67 free: 68 free_string(name); 69 } 70 71 static void match_end_func(struct symbol *sym) 72 { 73 if (__inline_fn) 74 return; 75 free_trackers_and_list(&resource_list); 76 } 77 78 void check_release_resource(int id) 79 { 80 my_id = id; 81 82 if (option_project != PROJ_KERNEL) 83 return; 84 85 add_function_hook("request_resource", &match_request, (void *)1); 86 add_function_hook("release_resource", &match_release, (void *)0); 87 add_function_hook("request_mem_resource", &match_request, (void *)0); 88 add_function_hook("release_mem_resource", &match_release, (void *)0); 89 add_hook(&match_end_func, END_FUNC_HOOK); 90 } 91