--- /dev/null	Fri Dec 21 15:00:04 2018
+++ new/usr/src/tools/smatch/src/check_implicit_dependencies_tester.c	Fri Dec 21 15:00:04 2018
@@ -0,0 +1,168 @@
+#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)
+{
+	// struct symbol *arg;
+	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 (!option_no_db && get_state(my_id, "this_function", NULL) != &called) {
+		if (name && strncmp(name, "sys_", 4) == 0)
+			is_syscall = 1;
+	}
+	*/
+
+	/* Ignore compat_sys b/c syzkaller doesn't fuzz these?
+	if (name && strncmp(name, "compat_sys_", 11) == 0)
+		is_syscall = 1;
+	*/
+
+	if (!is_syscall)
+		return;
+	printf("-------------------------\n");	
+	printf("\nsyscall found: %s at: ", name);
+	prefix(); printf("\n");
+	cur_syscall = sym;
+
+	/*
+	FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
+		set_state(my_id, arg->ident->name, arg, &user_data_set);
+	} END_FOR_EACH_PTR(arg);
+	*/
+}
+
+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;
+	// sm_msg("info: uses %s", member);
+	prefix();
+	printf("info: uses %s\n", member);
+	free_string(member);
+}
+
+static void match_condition(struct expression *expr) {
+    if (!cur_syscall)
+	return;
+    
+    /*
+    prefix();
+    printf("found conditional %s on line %d\n", expression_type_name(expr->type), get_lineno());
+    printf("expr_str: %s\n", expr_to_str(expr));
+    */
+
+    /* 
+    switch (expr->type) {
+	case EXPR_COMPARE:
+	    match_condition(expr->left);
+	    match_condition(expr->right);
+	    break;
+	case EXPR_SYMBOL:
+	    printf("symbol: %s\n", expr->symbol_name->name);
+	    break;
+	case EXPR_CALL:
+	    break;
+    }
+    */
+
+    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);
+}
+
