Tracecut advice compiles rules and reports tracecut matches.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Feb 2011 20:57:29 +0000 (15:57 -0500)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 17 Feb 2011 20:57:29 +0000 (15:57 -0500)
src/Makefile.am
src/tracecut-advice.c

index feb9275774558cf8a4f6eba0278fad40c5334ca0..b41f072c552a887e05bf2528fa9c44cf4932a9fd 100644 (file)
@@ -6,5 +6,5 @@ libinteraspect_la_CFLAGS = -Wall -Werror -fvisibility=hidden -prefer-pic
 libinteraspect_la_LDFLAGS = -static -prefer-pic -version-info 1:0:0
 libinteraspect_la_CPPFLAGS = -DHAVE_CONFIG_H -DIN_GCC -I$(gcc_includes)
 
-libtracecut_la_SOURCES = tracecut-advice.c
+libtracecut_la_SOURCES = tracecut-advice.c nfa.c
 libtracecut_la_CFLAGS = -Wall -Werror -fvisibility=hidden
index 105dca735cfaa11a4106e89a9d8b816f6cb2f8f7..a0863e717e59d598abf5608b27ee9dbbadcc3c9c 100644 (file)
@@ -3,6 +3,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "nfa.h"
+
 /* Advice functions should be externally visible. */
 #define ADVICE_FUNC __attribute__((visibility("default")))
 
@@ -16,7 +18,7 @@ struct tracecut {
   int num_rules;
 
   const char **symbol_names;
-  const char **rules;
+  struct NFA **rules;
 
   struct tuple *tuple_list;
 };
@@ -49,12 +51,14 @@ static struct event *current_event = NULL;
    every state machine whose params match the non-vacant params in the
    event. */
 struct tuple {
-  int state;
-
   /* For now, tuples are stored in a linked list. */
   struct tuple *next;
 
-  struct param_val param_vals[];
+  struct param_val *param_vals;
+
+  /* The state this tuple is in for each of the tracecut's regexp
+     rules. */
+  struct NState **states;
 };
 
 static void
@@ -90,8 +94,15 @@ get_tracecut (int tc_index)
 }
 
 void
-advance_state_machine (struct tuple *tuple, int symbol_index)
+advance_state_machine (struct tuple *tuple, int num_rules, int symbol_index)
 {
+  int i;
+  for (i = 0; i < num_rules; i++)
+    {
+      step (tuple->states[i], symbol_index);
+      if (ismatch (tuple->states[i]))
+       fprintf (stderr, "Match!\n");
+    }
 }
 
 int
@@ -126,12 +137,13 @@ update_matching_tuples (struct event *event)
   struct tracecut *tc = event->tracecut;
   struct tuple *tuple;
   int tuples_updated = 0;
+  int num_rules = event->tracecut->num_rules;
 
   for (tuple = tc->tuple_list; tuple != NULL; tuple = tuple->next)
     {
       if (event_matches_tuple (event, tuple))
        {
-         advance_state_machine (tuple, event->symbol_index);
+         advance_state_machine (tuple, num_rules, event->symbol_index);
          tuples_updated++;
          fprintf (stderr, "Advancing existing tuple.\n");
        }
@@ -142,6 +154,7 @@ update_matching_tuples (struct event *event)
 
 struct tuple *add_tuple_for_event (struct event *event)
 {
+  int i;
   struct tracecut *tc = event->tracecut;
   struct tuple *tuple;
   size_t tuple_size;
@@ -155,15 +168,44 @@ struct tuple *add_tuple_for_event (struct event *event)
       return NULL;
     }
 
-  tuple->state = 0;
+  tuple->param_vals = calloc (tc->num_params, sizeof (struct param_val));
+  tuple->states = calloc (tc->num_rules, sizeof (struct DState *));
+  if (tuple->param_vals == NULL || tuple->states == NULL)
+    goto nomem;
+
+  /* Initialize the param_vals array. */
   memcpy (tuple->param_vals, event->param_vals,
          tc->num_params * sizeof (struct param_val));
 
+  /* Set each rule to its initial state. */
+  for (i = 0; i < tc->num_rules; i++)
+    {
+      tuple->states[i] = getstartstate (tc->rules[i]);
+      if (tuple->states[i] == NULL)
+       goto nomem;
+    }
+
   /* Insert the tuple into the tracecut's tuple list. */
   tuple->next = tc->tuple_list;
   tc->tuple_list = tuple;
 
   return tuple;
+
+ nomem:
+  if (tuple != NULL)
+    {
+      if (tuple->states != NULL)
+       {
+         for (i = 0; i < tc->num_rules; i++)
+           if (tuple->states[i] != NULL)
+             freenstate (tuple->states[i]);
+         free (tuple->states);
+       }
+
+      free (tuple->param_vals);
+      free (tuple);
+    }
+  return NULL;
 }
 
 /* An event is "complete" iff only if all its params are specified
@@ -185,6 +227,7 @@ void
 do_transition (struct event *event)
 {
   int tuples_updated;
+  int num_rules = event->tracecut->num_rules;
 
   tuples_updated = update_matching_tuples (event);
 
@@ -194,7 +237,7 @@ do_transition (struct event *event)
 
       tuple = add_tuple_for_event (event);
       if (tuple != NULL)
-       advance_state_machine (tuple, event->symbol_index);
+       advance_state_machine (tuple, num_rules, event->symbol_index);
       fprintf (stderr, "Creating new tuple.\n");
     }
 }
@@ -221,12 +264,19 @@ _tc_new_tracecut (int tc_index, int num_params, int num_symbols, int num_rules)
   tc->num_symbols = num_symbols;
   tc->num_rules = num_rules;
 
-  if (tc->num_symbols > 0)
+  if (num_symbols > 0)
     {
       tc->symbol_names = calloc (num_symbols, sizeof (const char *));
       if (tc->symbol_names == NULL)
        fatal_tracecut_error ("Out of memory");
     }
+
+  if (num_rules > 0)
+    {
+      tc->rules = calloc (num_rules, sizeof (struct State *));
+      if (tc->rules == NULL)
+       fatal_tracecut_error ("Out of memory");
+    }
 }
 
 ADVICE_FUNC void
@@ -254,7 +304,20 @@ _tc_compile_rule (int tc_index, int rule_index, const char *specification)
 
   tc = get_tracecut (tc_index);
   if (tc == NULL)
-    return;
+    {
+      return;
+    }
+  else if (rule_index < 0 || rule_index >= tc->num_rules)
+    {
+      fatal_tracecut_error ("Bad rule index at initialization.");
+    }
+
+  tc->rules[rule_index] = compile_re (specification, tc->symbol_names,
+                                     tc->num_symbols);
+  if (tc->rules[rule_index] == NULL)
+    {
+      fatal_tracecut_error ("Failed to compile rule.");
+    }
 }
 
 ADVICE_FUNC void