X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=libust%2Fmarker.h;h=06f2b93f826d25fbf4ec976668b3ff14a3658126;hb=75667d04f4c255687def1876cf15baf3bbd1ffc5;hp=25c27f62ca774020ae43c7c7e2e86e52810af8d2;hpb=9160b4e4541d3a6010e4e671ee5deb3ea89f4211;p=ust.git diff --git a/libust/marker.h b/libust/marker.h index 25c27f6..06f2b93 100644 --- a/libust/marker.h +++ b/libust/marker.h @@ -6,8 +6,19 @@ * (C) Copyright 2006 Mathieu Desnoyers * (C) Copyright 2009 Pierre-Marc Fournier * - * This file is released under the GPLv2. - * See the file COPYING for more details. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _LINUX_MARKER_H @@ -18,8 +29,9 @@ #include "immediate.h" //ust// #include #include "kernelcompat.h" -#include "compiler.h" #include +#include "localerr.h" +#include "registers.h" //ust// struct module; //ust// struct task_struct; @@ -39,7 +51,7 @@ struct marker; * format string to recover the variable argument list. */ typedef void marker_probe_func(const struct marker *mdata, - void *probe_private, void *call_private, + void *probe_private, struct registers *regs, void *call_private, const char *fmt, va_list *args); struct marker_probe_closure { @@ -58,11 +70,12 @@ struct marker { /* Probe wrapper */ u16 channel_id; /* Numeric channel identifier, dynamic */ u16 event_id; /* Numeric event identifier, dynamic */ - void (*call)(const struct marker *mdata, void *call_private, ...); + void (*call)(const struct marker *mdata, void *call_private, struct registers *regs, ...); struct marker_probe_closure single; struct marker_probe_closure *multi; const char *tp_name; /* Optional tracepoint name */ void *tp_cb; /* Optional tracepoint callback */ + void *location; /* Address of marker in code */ } __attribute__((aligned(8))); #define CONFIG_MARKERS @@ -72,6 +85,7 @@ struct marker { static const char __mstrtab_##channel##_##name[] \ __attribute__((section("__markers_strings"))) \ = #channel "\0" #name "\0" format; \ + struct registers regs; \ static struct marker __mark_##channel##_##name \ __attribute__((section("__markers"), aligned(8))) = \ { __mstrtab_##channel##_##name, \ @@ -80,7 +94,16 @@ struct marker { sizeof(#name)], \ 0, 0, 0, 0, marker_probe_cb, \ { __mark_empty_function, NULL}, \ - NULL, tp_name_str, tp_cb } + NULL, tp_name_str, tp_cb }; \ + asm (".section __marker_addr,\"aw\",@progbits\n\t" \ + _ASM_PTR "%c[marker_struct], (1f)\n\t" \ + ".previous\n\t" \ + "\n\t" \ + "1:\n\t" \ + :: [marker_struct] "i" (&__mark_##channel##_##name));\ + save_registers(®s) + + #define DEFINE_MARKER(channel, name, format) \ _DEFINE_MARKER(channel, name, NULL, NULL, format) @@ -106,13 +129,13 @@ struct marker { __mark_##channel##_##name.state))) \ (*__mark_##channel##_##name.call) \ (&__mark_##channel##_##name, \ - call_private, ## args); \ + call_private, ®s, ## args); \ } else { \ if (unlikely(_imv_read( \ __mark_##channel##_##name.state))) \ (*__mark_##channel##_##name.call) \ (&__mark_##channel##_##name, \ - call_private, ## args); \ + call_private, ®s, ## args); \ } \ } while (0) @@ -126,7 +149,7 @@ struct marker { DEFINE_MARKER_TP(channel, name, tp_name, tp_cb, format);\ __mark_check_format(format, ## args); \ (*__mark_##channel##_##name.call)(&__mark_##channel##_##name, \ - call_private, ## args); \ + call_private, ®s, ## args); \ } while (0) extern void marker_update_probe_range(struct marker *begin, @@ -220,7 +243,7 @@ static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) extern marker_probe_func __mark_empty_function; extern void marker_probe_cb(const struct marker *mdata, - void *call_private, ...); + void *call_private, struct registers *regs, ...); /* * Connect a probe to a marker. @@ -276,27 +299,33 @@ extern int is_marker_enabled(const char *channel, const char *name); //ust// } //ust// #endif +struct marker_addr { + struct marker *marker; + void *addr; +}; struct lib { struct marker *markers_start; + struct marker_addr *markers_addr_start; int markers_count; struct list_head list; }; -extern int marker_register_lib(struct marker *markers_start, - int markers_count); - -#define MARKER_LIB \ -extern struct marker __start___markers[] __attribute__((visibility("hidden"))); \ -extern struct marker __stop___markers[] __attribute__((visibility("hidden"))); \ - \ -static void __attribute__((constructor)) __markers__init(void) \ -{ \ - marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));\ +extern int marker_register_lib(struct marker *markers_start, struct marker_addr *marker_addr_start, int markers_count); + +#define MARKER_LIB \ +extern struct marker __start___markers[] __attribute__((visibility("hidden"))); \ +extern struct marker __stop___markers[] __attribute__((visibility("hidden"))); \ +extern struct marker_addr __start___marker_addr[] __attribute__((visibility("hidden"))); \ +extern struct marker_addr __stop___marker_addr[] __attribute__((visibility("hidden"))); \ + \ +static void __attribute__((constructor)) __markers__init(void) \ +{ \ + DBG("next registration in "__FILE__"\n"); \ + marker_register_lib(__start___markers, __start___marker_addr, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker)); \ } -void marker_set_new_marker_cb(void (*cb)(struct marker *)); - -void init_markers(void); +extern void marker_set_new_marker_cb(void (*cb)(struct marker *)); +extern void init_markers(void); #endif