From 38570f4325aea3451fa7d0bc04b232648a967e9d Mon Sep 17 00:00:00 2001 From: Justin Seyster Date: Tue, 1 Feb 2011 16:57:10 -0500 Subject: [PATCH] Added tc_add_call_symbol() and master tracecut list. --- src/tracecut.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/tracecut.h | 4 +++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/tracecut.c b/src/tracecut.c index 5ea4103..f7cb7d1 100644 --- a/src/tracecut.c +++ b/src/tracecut.c @@ -32,7 +32,9 @@ #undef PACKAGE_VERSION #include +#include #include +#include #include "aop.h" #include "tracecut.h" @@ -48,7 +50,9 @@ struct tc_call_symbol { }; struct tc_tracecut { - struct tracecut_symbol *tc_symbol_list; + struct tc_call_symbol *symbol_list; + + struct tc_tracecut *next; }; /** * \endcond @@ -59,6 +63,65 @@ struct tc_tracecut { * \{ */ +/* It is necessary to keep a master list of all tracecuts so that the + main tracecut pass has access to them. */ +static struct tc_tracecut *tracecut_list = NULL; + +static int +symbol_exists (struct tc_tracecut *tc, const char *name) +{ + struct tc_call_symbol *symbol; + + for (symbol = tc->symbol_list; symbol != NULL; symbol = symbol->next) + { + if (strcmp (name, symbol->name) == 0) + return 1; /* Found it. */ + } + + /* We did not find a symbol with the given name. */ + return 0; +} + +/** + * Add a new tracecut symbol representing a function call event. The + * event bound to this new symbol is triggered whenever the specified + * function is called. + * + * All symbols must have unique name: attempting to create a duplicate + * symbol will fail. It is possible to create multiple symbols for + * the same function. + * + * \param tc The tracecut to add a symbol to. + * \param name The name used to reference this symbol. + * \param func_name The name of the function that should trigger the + * new symbol's event. + * \param location Specifies whether the the symbol event should + * trigger before or after the specified function is called. + */ +void +tc_add_call_symbol (struct tc_tracecut *tc, const char *name, + const char *func_name, enum aop_insert_location location) +{ + struct tc_call_symbol *symbol; + + if (symbol_exists (tc, name)) + { + fprintf (stderr, "(Tracecut) Ignoring duplicate symbol: %s\n", name); + return; + } + + symbol = (struct tc_call_symbol *)malloc (sizeof (struct tc_call_symbol)); + aop_assert (symbol != NULL); + + symbol->name = strdup (name); + symbol->func_name = strdup (func_name); + aop_assert (symbol->name != NULL && symbol->func_name != NULL); + + /* Insert this new symbol into the list of call symbols. */ + symbol->next = tc->symbol_list; + tc->symbol_list = symbol; +} + /** * Create an empty tc_tracecut object. The caller is responsible for * freeing the object using tc_free_tracecut(). @@ -73,11 +136,29 @@ tc_create_tracecut (void) tc = (struct tc_tracecut *)malloc (sizeof (struct tc_tracecut)); aop_assert (tc != NULL); - tc->tc_symbol_list = NULL; + tc->symbol_list = NULL; return tc; } +/* Find a tracecut object in the master list and remove it (if + found). */ +static void +remove_tracecut_from_list (struct tc_tracecut *tc) +{ + struct tc_tracecut **iterator; + + for (iterator = &tracecut_list; *iterator != NULL; + iterator = &((*iterator)->next)) + { + if (*iterator == tc) + { + *iterator = (*iterator)->next; + return; /* Done. */ + } + } +} + /** * Free all the memory used by a tc_object. Every call to * tc_create_tracecut() should have a matching call to @@ -87,6 +168,8 @@ tc_create_tracecut (void) void tc_free_tracecut (struct tc_tracecut *tc) { + remove_tracecut_from_list (tc); + free(tc); } diff --git a/src/tracecut.h b/src/tracecut.h index 407f1c6..c492e39 100644 --- a/src/tracecut.h +++ b/src/tracecut.h @@ -42,6 +42,10 @@ struct tc_tracecut; +extern void tc_add_call_symbol (struct tc_tracecut *tc, const char *name, + const char *func_name, + enum aop_insert_location location); + extern struct tc_tracecut *tc_create_tracecut (void); extern void tc_free_tracecut (struct tc_tracecut *tc); -- 2.34.1