From: Ketan Dixit Date: Wed, 14 Apr 2010 22:13:51 +0000 (-0400) Subject: fun call pointcut X-Git-Tag: release-v1.0~108 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=a421099bdf768c62411e7709efc23666c6e6bb29;p=interaspect.git fun call pointcut --- diff --git a/src/Makefile.am b/src/Makefile.am index 1d5a579..e353f15 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) diff --git a/src/aop-dynval.h b/src/aop-dynval.h index 0af81f1..9edf7d7 100644 --- a/src/aop-dynval.h +++ b/src/aop-dynval.h @@ -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 diff --git a/src/aop-main.c b/src/aop-main.c index 1a461e1..b379c06 100644 --- a/src/aop-main.c +++ b/src/aop-main.c @@ -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; diff --git a/src/aop-pc-entry.c b/src/aop-pc-entry.c index 51717e3..95129c8 100644 --- a/src/aop-pc-entry.c +++ b/src/aop-pc-entry.c @@ -31,6 +31,7 @@ #include #include #include +#include #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 index 0000000..d4d8e73 --- /dev/null +++ b/src/aop-pc-fun-call.c @@ -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 . +*/ + +/* 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/src/aop-pointcut.h b/src/aop-pointcut.h index 85420b3..2433abf 100644 --- a/src/aop-pointcut.h +++ b/src/aop-pointcut.h @@ -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; }; }; diff --git a/src/aop-weave.c b/src/aop-weave.c index 550a5d4..0349801 100644 --- a/src/aop-weave.c +++ b/src/aop-weave.c @@ -21,6 +21,7 @@ #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION +#define PAUSE_ON_START #include #include diff --git a/src/aop.h b/src/aop.h index 3675615..cfa5b22 100644 --- 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