2 * Copyright (C) 2022 Christophe Jaillet.
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 * The 'max' parameter of ida_alloc_max() and ida_alloc_range() is not interpreted
20 * as it was in the deprecated ida_simple_get().
22 * The 'max' value in the new functions is inclusive but it was exclusive before.
23 * So, in older code, this parameter was often a power of 2, such as 1 << 16, so
24 * that the maximum possible value was 0xffff.
26 * Now a power of 2 value is spurious.
35 static bool implied_power_of_two(struct expression
*expr
)
39 if (!get_implied_value(expr
, &sval
))
41 if (!(sval
.uvalue
& (sval
.uvalue
- 1)))
46 static bool is_power_of_two(struct expression
*expr
)
48 expr
= strip_expr(expr
);
50 if (expr
->type
== EXPR_BINOP
&&
51 expr
->op
== SPECIAL_LEFTSHIFT
&&
52 is_power_of_two(expr
->left
))
55 if (implied_power_of_two(expr
))
61 static void match_ida_alloc(const char *fn
, struct expression
*expr
, void *_arg_nr
)
63 int arg_nr
= PTR_INT(_arg_nr
);
64 struct expression
*arg_expr
;
66 arg_expr
= get_argument_from_call_expr(expr
->args
, arg_nr
);
67 arg_expr
= strip_expr(arg_expr
);
69 if (is_power_of_two(arg_expr
))
70 sm_error("Calling %s() with a 'max' argument which is a power of 2. -1 missing?",
74 void check_ida_alloc(int id
)
76 if (option_project
!= PROJ_KERNEL
)
81 add_function_hook("ida_alloc_max", &match_ida_alloc
, INT_PTR(1));
82 add_function_hook("ida_alloc_range", &match_ida_alloc
, INT_PTR(2));