Added tc_add_call_symbol() and master tracecut list.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Tue, 1 Feb 2011 21:57:10 +0000 (16:57 -0500)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Tue, 1 Feb 2011 21:57:10 +0000 (16:57 -0500)
src/tracecut.c
src/tracecut.h

index 5ea4103ac59d4d98ad3564f6c9f4c70d8dcae574..f7cb7d1f8146af7d21cee4c97a64ae0f88c8f7a6 100644 (file)
@@ -32,7 +32,9 @@
 #undef PACKAGE_VERSION
 
 #include <locale.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #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);
 }
 
index 407f1c68f302859e90dfb4d135a99fabf6056d13..c492e3965f4b050f9b16dcb53b009b8977727b14 100644 (file)
 
 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);