//#define PAUSE_ON_START
+#define NOINSTR_ATTR "noinstrument"
+
static const char *aop_plugin_name;
static const struct plugin_argument *plugin_argv;
}
}
+/* This is the "gate" function for all client plug-in passes that gets
+ to decide whether the pass will execute or not.*/
+static bool
+noinstrument_gate ()
+{
+ /* Execute the pass iff the current function is not annotated with
+ the noinstrument attribute. */
+ return (lookup_attribute (NOINSTR_ATTR, DECL_ATTRIBUTES (cfun->decl))
+ == NULL);
+}
+
+/* Register an attribute only if it has not yet been registered. If
+ the user loads multiple InterAspect plug-ins, they will all try to
+ register the noinstrument attribute. We have to make sure we don't
+ attempt to call GCC's register_attribute multiple times, or it will
+ throw an assertion failure! */
+static void
+register_attribute_once(const struct attribute_spec *attr)
+{
+ if (lookup_attribute_spec (get_identifier (attr->name)) == NULL)
+ register_attribute (attr);
+}
+
+static tree
+null_attrib_handler(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
+{
+ return NULL_TREE;
+}
+
+static struct attribute_spec noinstr_attr = {
+ .name = NOINSTR_ATTR,
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = false,
+ .type_required = false,
+ .function_type_required = false,
+ .handler = null_attrib_handler,
+};
+
+static void
+register_plugin_attributes(void *event_data, void *data)
+{
+ register_attribute_once(&noinstr_attr);
+}
+
/* This pass gets called before any passes that the client plug-in
registers. It's here for any administrative details that need to
take place before the instrumentation passes can execute. */
pass_aop->name = xstrdup (pass_name);
pass_aop->execute = callback;
+ pass_aop->gate = noinstrument_gate;
pass_info.pass = pass_aop;
pass_info.reference_pass_name = "veclower";
init_type_table ();
init_prototype_table ();
+ /* Register attributes. */
+ register_callback(aop_plugin_name, PLUGIN_ATTRIBUTES, register_plugin_attributes, NULL);
+
/* Register our cleanup function. */
register_callback (aop_plugin_name, PLUGIN_FINISH, aop_cleanup, NULL);
--- /dev/null
+#include <aop.h>
+#include <stdio.h>
+#include <string.h>
+
+AOP_I_AM_GPL_COMPATIBLE();
+
+static void plugin_join_on_foo(struct aop_joinpoint *jp, void *data)
+{
+ aop_insert_advice(jp, "_advice_foo", AOP_INSERT_BEFORE, AOP_TERM_ARG);
+}
+
+static unsigned int plugin_noinstr()
+{
+ struct aop_pointcut *pc;
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_name (pc, "foo");
+ aop_join_on(pc, plugin_join_on_foo, NULL);
+
+ return 0;
+}
+
+AOP_MAIN_PROTO aop_main()
+{
+ aop_register_pass("noinstr", plugin_noinstr);
+}