From b7d1701786ce7de35c4c13b6d5c13ecedcef3f3b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Mar 2009 16:40:16 +0300 Subject: [PATCH] core: add_function_hook() Up to now every check has had a call back for every function. Then they all call strcmp() to see if it's one of the functions they care about. The problem is that is slow for large numbers of functions. The new way is that you'll: add_function_hook("down", &lock_function, NULL); The lock_function() will look at the arguments and set the state locked. The last argument is for if you want to pass other data to lock_function(). Signed-off-by: Dan Carpenter --- Makefile | 3 ++- smatch.c | 2 ++ smatch.h | 1 + smatch_function_hooks.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 smatch_function_hooks.c diff --git a/Makefile b/Makefile index 7aaf83ab..f71afc1f 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ PKGCONFIGDIR=$(LIBDIR)/pkgconfig PROGRAMS=test-lexing test-parsing obfuscate compile graph sparse test-linearize example \ test-unssa test-dissect ctags smatch -SMATCH_FILES=smatch_flow.o smatch_conditions.o smatch_slist.o smatch_states.o smatch_helper.o smatch_hooks.o smatch_extra.o smatch_implied.o smatch_ignore.o smatch_tracker.o +SMATCH_FILES=smatch_flow.o smatch_conditions.o smatch_slist.o smatch_states.o smatch_helper.o smatch_hooks.o smatch_function_hooks.o smatch_extra.o smatch_implied.o smatch_ignore.o smatch_tracker.o SMATCH_CHECKS=$(shell ls check_*.c | sed -e 's/\.c/.o/') @@ -175,6 +175,7 @@ smatch_implied.o: $(LIB_H) smatch.h smatch_slist.h smatch_ignore.o: $(LIB_H) smatch.h smatch_tracker.o: $(LIB_H) smatch.h smatch_hooks.o: $(LIB_H) smatch.h +smatch_function_hooks.o: $(LIB_H) smatch.h smatch_helper.o: $(LIB_H) smatch.h smatch_slist.o: $(LIB_H) smatch.h smatch_slist.h smatch_states.o: $(LIB_H) smatch.h smatch_slist.h diff --git a/smatch.c b/smatch.c index d9f4d0d1..3b72d36f 100644 --- a/smatch.c +++ b/smatch.c @@ -14,6 +14,7 @@ typedef void (*reg_func) (int id); void register_smatch_extra(int id); void register_smatch_ignore(int id); void register_implications(int id); +void register_function_hooks(int id); void check_null_deref(int id); void check_overflow(int id); void check_locking(int id); @@ -25,6 +26,7 @@ void check_frees_argument(int id); static const reg_func reg_funcs[] = { ®ister_smatch_extra, /* smatch_extra always has to be first */ ®ister_smatch_ignore, + ®ister_function_hooks, &check_null_deref, &check_overflow, &check_locking, diff --git a/smatch.h b/smatch.h index d59cc27d..9f812e57 100644 --- a/smatch.h +++ b/smatch.h @@ -68,6 +68,7 @@ typedef struct smatch_state *(merge_func_t)(const char *name, typedef struct smatch_state *(unmatched_func_t)(struct sm_state *state); void add_merge_hook(int client_id, merge_func_t *func); void add_unmatched_state_hook(int client_id, unmatched_func_t *func); +void add_function_hook(const char *lock_for, void *call_back, void *data); #define smatch_msg(msg...) \ do { \ diff --git a/smatch_function_hooks.c b/smatch_function_hooks.c new file mode 100644 index 00000000..ca4cca28 --- /dev/null +++ b/smatch_function_hooks.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include "smatch.h" + +struct fcall_back { + void *call_back; + void *data; +}; + +ALLOCATOR(fcall_back, "call backs"); +DECLARE_PTR_LIST(call_back_list, struct fcall_back); + +static int my_id; + +void add_function_hook(const char *lock_for, void *call_back, void *data) +{ + ENTRY e, *ep; + struct fcall_back *cb; + + cb = __alloc_fcall_back(0); + cb->call_back = call_back; + cb->data = data; + e.key = alloc_string(lock_for); + ep = hsearch(e, FIND); + if (!ep) { + struct call_back_list *list = NULL; + + add_ptr_list(&list, cb); + e.data = list; + } else { + free_string(ep->key); + add_ptr_list((struct call_back_list **)&ep->data, cb); + e.data = ep->data; + } + hsearch(e, ENTER); +} + +typedef void (expr_func)(struct expression *expr, void *data); +static void match_function_call(struct expression *expr) +{ + ENTRY e, *ep; + struct fcall_back *tmp; + + if (expr->fn->type != EXPR_SYMBOL || !expr->fn->symbol) + return; + + e.key = expr->fn->symbol->ident->name; + ep = hsearch(e, FIND); + if (!ep) + return; + + FOR_EACH_PTR((struct call_back_list *)ep->data, tmp) { + ((expr_func *) tmp->call_back)(expr, tmp->data); + } END_FOR_EACH_PTR(tmp); +} + +void register_function_hooks(int id) +{ + my_id = id; + hcreate(1000); // We will track maybe 1000 functions. + add_hook(&match_function_call, FUNCTION_CALL_AFTER_HOOK); +} -- 2.11.4.GIT