2 * Copyright (C) 2014 Oracle.
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 #include "smatch_slist.h"
23 static int capable_id
;
24 static int ns_capable_id
;
26 static void match_capable(const char *fn
, struct expression
*expr
, void *_param
)
28 struct expression
*arg
;
32 arg
= get_argument_from_call_expr(expr
->args
, 0);
33 if (!get_implied_value(arg
, &sval
))
35 snprintf(buf
, sizeof(buf
), "%s", sval_to_str(sval
));
36 set_state(capable_id
, buf
, NULL
, &capable
);
39 static void match_ns_capable(const char *fn
, struct expression
*expr
, void *_param
)
41 struct expression
*arg
;
45 if (get_function() && strcmp(get_function(), "capable") == 0)
48 arg
= get_argument_from_call_expr(expr
->args
, 1);
49 if (!get_implied_value(arg
, &sval
))
51 snprintf(buf
, sizeof(buf
), "%s", sval_to_str(sval
));
52 set_state(ns_capable_id
, buf
, NULL
, &capable
);
55 static void save_call_info(struct expression
*call
)
59 FOR_EACH_MY_SM(capable_id
, __get_cur_stree(), sm
) {
60 if (sm
->state
== &capable
)
61 sql_insert_caller_info(call
, CAPABLE
, 0, sm
->name
, "");
62 } END_FOR_EACH_SM(sm
);
64 FOR_EACH_MY_SM(ns_capable_id
, __get_cur_stree(), sm
) {
65 if (sm
->state
== &capable
)
66 sql_insert_caller_info(call
, NS_CAPABLE
, 0, sm
->name
, "");
67 } END_FOR_EACH_SM(sm
);
70 static void save_return_info(int return_id
, char *return_ranges
, struct expression
*expr
)
74 FOR_EACH_MY_SM(capable_id
, __get_cur_stree(), sm
) {
75 if (sm
->state
== &capable
)
76 sql_insert_return_states(return_id
, return_ranges
,
77 CAPABLE
, 0, sm
->name
, "");
78 } END_FOR_EACH_SM(sm
);
80 FOR_EACH_MY_SM(ns_capable_id
, __get_cur_stree(), sm
) {
81 if (sm
->state
== &capable
)
82 sql_insert_return_states(return_id
, return_ranges
,
83 CAPABLE
, 0, sm
->name
, "");
84 } END_FOR_EACH_SM(sm
);
87 static void set_db_capable(const char *name
, struct symbol
*sym
, char *key
, char *value
)
91 snprintf(buf
, sizeof(buf
), "%s", key
);
92 set_state(capable_id
, buf
, NULL
, &capable
);
95 static void set_db_ns_capable(const char *name
, struct symbol
*sym
, char *key
, char *value
)
99 snprintf(buf
, sizeof(buf
), "%s", key
);
100 set_state(ns_capable_id
, buf
, NULL
, &capable
);
103 void check_capable(int id
)
105 if (option_project
!= PROJ_KERNEL
)
109 add_function_hook("capable", &match_capable
, INT_PTR(0));
111 add_hook(&save_call_info
, FUNCTION_CALL_HOOK
);
112 add_split_return_callback(save_return_info
);
113 select_caller_info_hook(set_db_capable
, CAPABLE
);
116 void check_ns_capable(int id
)
118 if (option_project
!= PROJ_KERNEL
)
122 add_function_hook("ns_capable", &match_ns_capable
, INT_PTR(0));
123 select_caller_info_hook(set_db_ns_capable
, NS_CAPABLE
);