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 
22 /* this is stolen from the kernel but it's totally fair use dude...  */
23 #define __GFP_DMA       (0x01u)
24 #define __GFP_HIGHMEM   (0x02u)
25 #define __GFP_DMA32     (0x04u)
26 #define __GFP_MOVABLE   (0x08u)
27 #define GFP_ZONEMASK    (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
28 
match_alloc(const char * fn,struct expression * expr,void * _arg)29 static void match_alloc(const char *fn, struct expression *expr, void *_arg)
30 {
31 	int arg_nr = PTR_INT(_arg);
32 	struct expression *arg_expr;
33 	sval_t sval;
34 
35 	arg_expr = get_argument_from_call_expr(expr->args, arg_nr);
36 	if (!get_value(arg_expr, &sval))
37 		return;
38 	if (sval.uvalue == 0) /* GFP_NOWAIT */
39 		return;
40 	if (!(sval.uvalue & ~GFP_ZONEMASK))
41 		sm_error("no modifiers for allocation.");
42 }
43 
check_gfp_dma(int id)44 void check_gfp_dma(int id)
45 {
46 	my_id = id;
47 	if (option_project != PROJ_KERNEL)
48 		return;
49 	add_function_hook("kmalloc", &match_alloc, INT_PTR(1));
50 	add_function_hook("kzalloc", &match_alloc, INT_PTR(1));
51 }
52