1 /* 2 * Copyright (C) 2009 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 22 static void match_dma_func(const char *fn, struct expression *expr, void *param) 23 { 24 struct expression *arg; 25 struct symbol *sym; 26 char *name; 27 28 arg = get_argument_from_call_expr(expr->args, PTR_INT(param)); 29 arg = strip_expr(arg); 30 if (!arg) 31 return; 32 if (arg->type == EXPR_PREOP && arg->op == '&') { 33 if (arg->unop->type != EXPR_SYMBOL) 34 return; 35 name = expr_to_str(arg); 36 sm_error("doing dma on the stack (%s)", name); 37 free_string(name); 38 return; 39 } 40 if (arg->type != EXPR_SYMBOL) 41 return; 42 sym = get_type(arg); 43 if (!sym || sym->type != SYM_ARRAY) 44 return; 45 if (get_param_num(arg) >= 0) 46 return; 47 name = expr_to_var(arg); 48 sm_error("doing dma on the stack (%s)", name); 49 free_string(name); 50 } 51 52 static void register_funcs_from_file(void) 53 { 54 struct token *token; 55 const char *func; 56 int arg; 57 58 token = get_tokens_file("kernel.dma_funcs"); 59 if (!token) 60 return; 61 if (token_type(token) != TOKEN_STREAMBEGIN) 62 return; 63 token = token->next; 64 while (token_type(token) != TOKEN_STREAMEND) { 65 if (token_type(token) != TOKEN_IDENT) 66 return; 67 func = show_ident(token->ident); 68 token = token->next; 69 if (token_type(token) != TOKEN_NUMBER) 70 return; 71 arg = atoi(token->number); 72 add_function_hook(func, &match_dma_func, INT_PTR(arg)); 73 token = token->next; 74 } 75 clear_token_alloc(); 76 } 77 78 void check_dma_on_stack(int id) 79 { 80 if (option_project != PROJ_KERNEL) 81 return; 82 my_id = id; 83 register_funcs_from_file(); 84 } 85