fun call pointcut
authorKetan Dixit <ketan.dixit@gmail.com>
Wed, 14 Apr 2010 22:13:51 +0000 (18:13 -0400)
committerKetan Dixit <ketan.dixit@gmail.com>
Wed, 14 Apr 2010 22:13:51 +0000 (18:13 -0400)
src/Makefile.am
src/aop-dynval.h
src/aop-main.c
src/aop-pc-entry.c
src/aop-pc-fun-call.c [new file with mode: 0644]
src/aop-pointcut.h
src/aop-weave.c
src/aop.h

index 1d5a579b588fab0e3a9a57c0b788907bd5c4d460..e353f15c5570aed850b9b4c8edba05b7751bb43c 100644 (file)
@@ -1,5 +1,5 @@
 lib_LTLIBRARIES = libinteraspect.la
-libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c aop-weave.c aop-pc-entry.c aop-pc-exit.c
+libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c aop-weave.c aop-pc-entry.c aop-pc-exit.c aop-pc-fun-call.c
 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)
index 0af81f1960d5a8b8925420392b4421b5157428ef..9edf7d73f905d30f950cdda277fd256dbcd9ad34 100644 (file)
@@ -23,6 +23,8 @@ struct aop_type;
 
 enum aop_dvkind {
   ADV_LHS_ADDR,
+  ADV_FUN_PARAM,
+  ADV_FUN_RETVAL
 };
 
 /* An aop-dynval represents a dynamic value in the target program that
index 1a461e18c65c402ee1b19d8e99044677c6532fae..b379c067f540ce295981d632c9e6dfc2fdc35a29 100644 (file)
@@ -53,7 +53,7 @@
 #include "aop.h"
 #include "aop-pointcut.h"
 
-//#define PAUSE_ON_START
+#define PAUSE_ON_START
 
 static const char *aop_plugin_name;
 
index 51717e3078bcfe6556fefab1df86f0ed0ac0d292..95129c8fa200f25cf818a10865990d69b96efe72 100644 (file)
@@ -31,6 +31,7 @@
 #include <ggc.h>
 #include <basic-block.h>
 #include <gimple.h>
+#include <string.h>
 
 #include "aop.h"
 #include "aop-pointcut.h"
@@ -44,6 +45,17 @@ op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb,
   basic_block bb;
   aop_assert (pc->kind == ATP_ENTRY);
 
+  if(pc->pc_entry.function_name!= NULL)
+    {   
+      if (strcmp(IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
+                ,pc->pc_entry.function_name)!=0)
+       {
+         fprintf(stderr,"%s function does not match the pointcut specifier",
+                 pc->pc_entry.function_name);
+         return;
+       }
+    }
+
   FOR_EACH_BB(bb)
     {
       gimple_stmt_iterator gsi;
@@ -71,3 +83,10 @@ aop_match_function_entry ()
 
   return pc;
 }
+
+void aop_filter_function_entry_pointcut(struct aop_pointcut *pc_function_entry,
+                                       const char *advice_function_entry)
+{
+  pc_function_entry->pc_entry.function_name=advice_function_entry;
+}
+
diff --git a/src/aop-pc-fun-call.c b/src/aop-pc-fun-call.c
new file mode 100644 (file)
index 0000000..d4d8e73
--- /dev/null
@@ -0,0 +1,210 @@
+/* This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation, either version 3 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Whether we want them or not (we don't), Autoconf _insists_ on
+   defining these.  Since GCC's config.h (which we must include) also
+   defines them, we have to undef them here. */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <locale.h>
+
+#include <config.h>
+#include <system.h>
+#include <coretypes.h>
+#include <tm.h>
+#include <tree.h>
+#include <ggc.h>
+#include <basic-block.h>
+#include <gimple.h>
+#include <string.h>
+
+#include "aop.h"
+#include "aop-pointcut.h"
+#include "aop-type.h"
+#include "aop-dynval.h"
+
+
+static void
+op_join_on_function_call (struct aop_pointcut *pc, join_callback cb,
+                          void *callback_param)
+{
+  aop_assert (pc->kind == ATP_CALL);
+
+  basic_block my_basic_block;
+  gimple_stmt_iterator gsi;
+  tree func_decl;
+  tree func;
+
+  const char * func_name;
+
+  FOR_EACH_BB(my_basic_block)
+  {
+    for (gsi = gsi_start_bb (my_basic_block);
+         !gsi_end_p (gsi);
+         gsi_next (&gsi)) 
+      {
+       gimple my_statement = gsi_stmt (gsi);
+
+       /* At this stage, there should be no GIMPLE statements with sub-statements. */
+       gcc_assert(!gimple_has_substatements (my_statement));
+
+       if (gimple_code (my_statement) == GIMPLE_CALL)
+         {
+           func = gimple_call_fn(my_statement);
+           func_decl = TREE_OPERAND (func, 0);
+           func_name = IDENTIFIER_POINTER (DECL_NAME (func_decl));
+           if (strcmp (pc->pc_call.function_name, func_name) == 0) 
+             {
+               struct aop_joinpoint jp;
+               jp.pc = pc;
+               jp.gsi = &gsi;
+               cb (&jp, callback_param);
+               fprintf (stderr,"Function call to %s captured...",pc->pc_call.function_name);
+             }
+         }
+
+      }
+  } 
+}
+
+struct aop_pointcut *
+aop_match_function_call ()
+{
+  struct aop_pointcut *pc;
+
+  pc = ggc_alloc (sizeof (struct aop_pointcut));
+  pc->kind = ATP_CALL;
+  pc->join_on = op_join_on_function_call;
+  pc->insert_before = op_default_insert_before;
+  return pc;
+}
+
+void aop_filter_function_call_pointcut(struct aop_pointcut *pc_function_call,
+                                       const char *advice_function_call)
+{
+  pc_function_call->pc_call.function_name=advice_function_call;
+
+}
+
+void aop_filter_function_call_pointcut_by_param_index(struct aop_pointcut *pc,
+                                                     int param_id)
+{
+  pc->pc_call.param_id=param_id;
+
+}
+
+/*
+void aop_filter_function_call_pointcut(struct aop_pointcut *pc_function_call,
+                                       const char *advice_function_call)
+{
+  pc_function_call->pc_call.function_name=advice_function_call;
+
+}
+*/
+static tree
+op_get_return_value (struct aop_dynval *dv)
+{
+  gimple stmt;
+  tree return_value;
+
+  /* 
+     If this function isn't on the right side of an assignment, we
+     need to _put it_ on the right hand side of an assignment so
+     we can grab its return value. 
+  */
+  struct aop_joinpoint *jp = dv->jp;
+  stmt = gsi_stmt (*(jp->gsi));
+  
+  /* If this function isn't on the right side of an assignment, we
+     need to _put it_ on the right hand side of an assignment so
+     we can grab its return value. */
+  if (gimple_call_lhs(stmt) == NULL)
+    {
+      fprintf(stderr,"call_lhs is NULL\n");
+      /*
+      tree new_lhs = create_tmp_var(gimple_call_return_type(stmt), "hcos_mem_result");
+      add_referenced_var(new_lhs);
+      new_lhs = make_ssa_name(new_lhs, stmt);
+      
+      gimple_call_set_lhs(stmt, new_lhs);
+      update_stmt(stmt); 
+      */
+    }
+  fprintf(stderr,"Before stabilize_reference\n");
+  return_value = stabilize_reference(gimple_call_lhs(stmt));
+  return return_value;
+}
+
+struct aop_dynval *
+aop_capture_return_value (struct aop_joinpoint *jp)
+{
+  struct aop_dynval *dv;
+  dv = ggc_alloc (sizeof (struct aop_dynval));
+  dv->kind = ADV_FUN_RETVAL;
+  dv->type = aop_t_all_unsigned ();
+  dv->jp = jp;
+  dv->get_dynval = op_get_return_value;
+  fprintf(stderr,"Came here.......\n");
+  return dv;
+  
+}
+
+static tree
+op_get_param (struct aop_dynval *dv)
+{
+  gimple stmt;
+  tree param;
+
+  struct aop_joinpoint *jp = dv->jp;
+  fprintf(stderr,"In op_get_param\n");
+
+  aop_assert (dv->kind == ADV_FUN_PARAM);
+  aop_assert (jp->pc->kind == ATP_CALL);
+
+  fprintf(stderr,"op_get_param after assert\n");
+  stmt = gsi_stmt (*(jp->gsi));
+
+  /*
+  if (gimple_call_num_args(stmt) < 1)
+    {
+      error("Invalid argument specification in ptcut.\n");
+      return NULL;
+    }
+  */
+  fprintf(stderr,"op_get_param before stab ref \n");
+  param = stabilize_reference(gimple_call_arg(stmt, 0));
+//  param = gimple_call_arg(stmt, 0);  
+//   param = build_int_cst(integer_type_node, 0);
+  fprintf(stderr,"op_get_param after stab ref \n");        
+  return param;
+}
+
+
+struct aop_dynval *
+aop_capture_param (struct aop_joinpoint *jp)
+{
+  struct aop_dynval *dv;
+  dv = ggc_alloc (sizeof (struct aop_dynval));
+  dv->kind = ADV_FUN_PARAM;
+  dv->type = aop_t_all_unsigned ();
+  dv->jp = jp;
+  dv->get_dynval = op_get_param;
+  return dv;
+}
+
index 85420b331e8e633e9c67f6716cfdba320b20007c..2433abf700601ab2688bfa122d28a3ae6c822c7a 100644 (file)
@@ -26,6 +26,7 @@ enum aop_pckind {
   ATP_ASSIGN,
   ATP_ENTRY,
   ATP_EXIT,
+  ATP_CALL
 };
 
 /* Information specific to assignment pointcuts. */
@@ -37,7 +38,17 @@ struct aop_pc_assign {
   bool include_temp_vars;
 };
 
-/* An AOP pointcut represents a set of joinponts: locations in the
+struct aop_pc_entry {
+  const char *function_name;
+};
+
+struct aop_pc_fun_call {
+  const char *function_name;
+  int param_id;  
+};
+
+/* An AOP pointcut represents the a set of joinponts: locations in the
+>>>>>>> Stashed changes:src/aop-pointcut.h
    source code that are available for inserting instrumentation.
 
    In practice, we do not directly store the set of joinpoints.
@@ -51,6 +62,8 @@ struct aop_pointcut {
 
   union {
     struct aop_pc_assign pc_assign;
+    struct aop_pc_entry pc_entry;
+    struct aop_pc_fun_call pc_call;
   };
 };
 
index 550a5d4892c60677dbf710deef45cc116ad325bb..03498017fff2be5f11d2e6f818dc5261d1947071 100644 (file)
@@ -21,6 +21,7 @@
 #undef PACKAGE_STRING
 #undef PACKAGE_TARNAME
 #undef PACKAGE_VERSION
+#define PAUSE_ON_START
 
 #include <locale.h>
 #include <stdarg.h>
index 36756156fe8ef5e358ce7e530078574b4f0fd721..cfa5b2297254a6fb1e2e01e2123f19fc9ba63351 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -94,5 +94,20 @@ const char *aop_capture_function_name (struct aop_joinpoint *jp);
 struct aop_dynval *aop_capture_lhs_addr (struct aop_joinpoint *jp);
 struct aop_pointcut *aop_match_function_entry ();
 struct aop_pointcut *aop_match_function_exit ();
+struct aop_pointcut *aop_match_function_call ();
 
+void aop_filter_function_entry_pointcut(struct aop_pointcut *pc_function_entry,
+                                       const char *advice_function_entry);
+
+void aop_filter_function_call_pointcut(struct aop_pointcut *pc_function_call,
+                                       const char *advice_function_call);
+
+void aop_filter_function_call_pointcut_by_param_index(struct aop_pointcut *pc,
+                                                     int param_index);  
+
+struct aop_dynval *
+aop_capture_return_value (struct aop_joinpoint *jp);
+
+struct aop_dynval *
+aop_capture_param (struct aop_joinpoint *jp);
 #endif