#include "smatch.h"
#include "linearize.h"
static int my_id;
static struct symbol *cur_syscall;
static const char *expression_type_name(enum expression_type type)
{
static const char *expression_type_name[] = {
[EXPR_VALUE] = "EXPR_VALUE",
[EXPR_STRING] = "EXPR_STRING",
[EXPR_SYMBOL] = "EXPR_SYMBOL",
[EXPR_TYPE] = "EXPR_TYPE",
[EXPR_BINOP] = "EXPR_BINOP",
[EXPR_ASSIGNMENT] = "EXPR_ASSIGNMENT",
[EXPR_LOGICAL] = "EXPR_LOGICAL",
[EXPR_DEREF] = "EXPR_DEREF",
[EXPR_PREOP] = "EXPR_PREOP",
[EXPR_POSTOP] = "EXPR_POSTOP",
[EXPR_CAST] = "EXPR_CAST",
[EXPR_FORCE_CAST] = "EXPR_FORCE_CAST",
[EXPR_IMPLIED_CAST] = "EXPR_IMPLIED_CAST",
[EXPR_SIZEOF] = "EXPR_SIZEOF",
[EXPR_ALIGNOF] = "EXPR_ALIGNOF",
[EXPR_PTRSIZEOF] = "EXPR_PTRSIZEOF",
[EXPR_CONDITIONAL] = "EXPR_CONDITIONAL",
[EXPR_SELECT] = "EXPR_SELECT",
[EXPR_STATEMENT] = "EXPR_STATEMENT",
[EXPR_CALL] = "EXPR_CALL",
[EXPR_COMMA] = "EXPR_COMMA",
[EXPR_COMPARE] = "EXPR_COMPARE",
[EXPR_LABEL] = "EXPR_LABEL",
[EXPR_INITIALIZER] = "EXPR_INITIALIZER",
[EXPR_IDENTIFIER] = "EXPR_IDENTIFIER",
[EXPR_INDEX] = "EXPR_INDEX",
[EXPR_POS] = "EXPR_POS",
[EXPR_FVALUE] = "EXPR_FVALUE",
[EXPR_SLICE] = "EXPR_SLICE",
[EXPR_OFFSETOF] = "EXPR_OFFSETOF",
};
return expression_type_name[type] ?: "UNKNOWN_EXPRESSION_TYPE";
}
static inline void prefix() {
printf("%s:%d %s() ", get_filename(), get_lineno(), get_function());
}
static void match_syscall_definition(struct symbol *sym)
{
char *macro;
char *name;
int is_syscall = 0;
macro = get_macro_name(sym->pos);
if (macro &&
(strncmp("SYSCALL_DEFINE", macro, strlen("SYSCALL_DEFINE")) == 0 ||
strncmp("COMPAT_SYSCALL_DEFINE", macro, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
is_syscall = 1;
name = get_function();
if (!is_syscall)
return;
printf("-------------------------\n");
printf("\nsyscall found: %s at: ", name);
prefix(); printf("\n");
cur_syscall = sym;
}
static void match_after_syscall(struct symbol *sym) {
if (cur_syscall && sym == cur_syscall) {
printf("\n"); prefix();
printf("exiting scope of syscall %s\n", get_function());
printf("-------------------------\n");
cur_syscall = NULL;
}
}
static void print_member_type(struct expression *expr)
{
char *member;
member = get_member_name(expr);
if (!member)
return;
prefix();
printf("info: uses %s\n", member);
free_string(member);
}
static void match_condition(struct expression *expr) {
if (!cur_syscall)
return;
prefix(); printf("-- condition found\n");
if (expr->type == EXPR_COMPARE || expr->type == EXPR_BINOP
|| expr->type == EXPR_LOGICAL
|| expr->type == EXPR_ASSIGNMENT
|| expr->type == EXPR_COMMA) {
match_condition(expr->left);
match_condition(expr->right);
return;
}
print_member_type(expr);
}
static void match_function_call(struct expression *expr) {
if (!cur_syscall)
return;
prefix();
printf("function call %s\n", expression_type_name(expr->type));
}
void check_implicit_dependencies_tester(int id)
{
my_id = id;
if (option_project != PROJ_KERNEL)
return;
add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
add_hook(&match_after_syscall, AFTER_FUNC_HOOK);
add_hook(&match_condition, CONDITION_HOOK);
add_hook(&match_function_call, FUNCTION_CALL_HOOK);
}