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 #include "smatch.h" 19 20 static int my_id; 21 extern int check_assigned_expr_id; 22 23 static int is_probably_ok(struct expression *expr) 24 { 25 expr = strip_expr(expr); 26 27 if (expr->type == EXPR_BINOP) 28 return 1; 29 if (expr->type == EXPR_SIZEOF) 30 return 1; 31 32 return 0; 33 } 34 35 static void verify_size_expr(struct expression *expr) 36 { 37 if (expr->type != EXPR_BINOP) 38 return; 39 if (expr->op != '-') 40 return; 41 if (is_probably_ok(expr->left)) 42 return; 43 if (is_probably_ok(expr->right)) 44 return; 45 sm_warning("consider using resource_size() here"); 46 } 47 48 static void handle_assigned_expr(struct expression *expr) 49 { 50 struct smatch_state *state; 51 52 state = get_state_expr(check_assigned_expr_id, expr); 53 if (!state || !state->data) 54 return; 55 expr = (struct expression *)state->data; 56 verify_size_expr(expr); 57 } 58 59 static void match_resource(const char *fn, struct expression *expr, void *_arg_no) 60 { 61 struct expression *arg_expr; 62 int arg_no = PTR_INT(_arg_no); 63 64 arg_expr = get_argument_from_call_expr(expr->args, arg_no); 65 arg_expr = strip_expr(arg_expr); 66 if (!arg_expr) 67 return; 68 69 if (arg_expr->type == EXPR_SYMBOL) { 70 handle_assigned_expr(arg_expr); 71 return; 72 } 73 verify_size_expr(arg_expr); 74 } 75 76 void check_resource_size(int id) 77 { 78 my_id = id; 79 80 if (option_project != PROJ_KERNEL) 81 return; 82 83 add_function_hook("ioremap_nocache", &match_resource, (void *)1); 84 add_function_hook("ioremap", &match_resource, (void *)1); 85 add_function_hook("__request_region", &match_resource, (void *)2); 86 add_function_hook("__release_region", &match_resource, (void *)2); 87 add_function_hook("__devm_request_region", &match_resource, (void *)3); 88 add_function_hook("__devm_release_region", &match_resource, (void *)3); 89 } 90