Fix dynamic linking with GNU gold linker
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 8 Dec 2011 13:28:42 +0000 (08:28 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 8 Dec 2011 13:28:42 +0000 (08:28 -0500)
Programs that were not linked explicitely with -lurcu-bp generated no
trace output when linked with GNU gold, because the urcu-bp library
symbols were not used to populate the weak urcu-bp symbols used by the
program. (even though they worked fine with the standard GNU ld).

Solve this by creating those wrapper symbols into tracepoint.c, and
explicitely get them with dlsym() in the constructor.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/Makefile.am
include/lttng/tracepoint-rcu.h [new file with mode: 0644]
include/lttng/tracepoint.h
liblttng-ust/tracepoint.c
tests/demo/demo.c
tests/hello.cxx/hello.cpp
tests/hello/hello.c

index 13fa44b3cdf0988164136a09752562173877788f..efaffc85ac913cd7fa478ff5b889defa69e1b403 100644 (file)
@@ -1,5 +1,6 @@
 nobase_include_HEADERS = \
        lttng/tracepoint.h \
+       lttng/tracepoint-rcu.h \
        lttng/tracepoint-types.h \
        lttng/tracepoint-event.h \
        lttng/ust-tracepoint-event.h \
diff --git a/include/lttng/tracepoint-rcu.h b/include/lttng/tracepoint-rcu.h
new file mode 100644 (file)
index 0000000..852cfe4
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _LTTNG_TRACEPOINT_RCU_H
+#define _LTTNG_TRACEPOINT_RCU_H
+
+/*
+ * Copyright (c) 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose,  provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ * This file allows weak linking on tracepoint RCU symbols for non-LGPL
+ * code.
+ */
+
+#include <urcu/compiler.h>
+
+#ifdef _LGPL_SOURCE
+
+#include <urcu-bp.h>
+
+#define TP_RCU_LINK_TEST()     1
+#define tp_rcu_read_lock_bp    rcu_read_lock_bp
+#define tp_rcu_read_unlock_bp  rcu_read_unlock_bp
+#define tp_rcu_dereference_bp  rcu_dereference_bp
+
+#else  /* _LGPL_SOURCE */
+
+#define TP_RCU_LINK_TEST()     tp_rcu_read_lock_bp
+
+/* Symbols looked up with dlsym */
+static void (*tp_rcu_read_lock_bp)(void) __attribute__((unused));
+static void (*tp_rcu_read_unlock_bp)(void) __attribute__((unused));
+static void *(*tp_rcu_dereference_sym_bp)(void *p) __attribute__((unused));
+
+#define tp_rcu_dereference_bp(p)                                            \
+       ({                                                                   \
+               typeof(p) _________p1 = URCU_FORCE_CAST(typeof(p),           \
+                       tp_rcu_dereference_sym_bp(URCU_FORCE_CAST(void *, p))); \
+               (_________p1);                                               \
+       })
+
+#endif /* _LGPL_SOURCE */
+
+#endif /* _LTTNG_TRACEPOINT_RCU_H */
index a224caebcd8485cf731648a0b6ce0e718d8d0bae..2942c175e7cf0580ecf39edd99b78a1eb47d9c9c 100644 (file)
  * modified is included with the above copyright notice.
  */
 
-#include <urcu-bp.h>
 #include <lttng/tracepoint-types.h>
+#include <lttng/tracepoint-rcu.h>
 #include <urcu/compiler.h>
 #include <dlfcn.h>     /* for dlopen */
+#include <assert.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -113,22 +114,16 @@ extern "C" {
 #define _TP_ARGS_DATA_VAR(...)         _TP_DATA_VAR_N(_TP_NARGS(0, ##__VA_ARGS__), ##__VA_ARGS__)
 #define _TP_PARAMS(...)                        __VA_ARGS__
 
-#ifdef _LGPL_SOURCE
-#define _TP_RCU_LINK_TEST()    1
-#else
-#define _TP_RCU_LINK_TEST()    rcu_read_lock_bp
-#endif
-
 #define _DECLARE_TRACEPOINT(provider, name, ...)                                       \
 extern struct tracepoint __tracepoint_##provider##___##name;                           \
 static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARGS__))  \
 {                                                                                      \
        struct tracepoint_probe *__tp_probe;                                            \
                                                                                        \
-       if (!_TP_RCU_LINK_TEST())                                                       \
+       if (!TP_RCU_LINK_TEST())                                                        \
                return;                                                                 \
-       rcu_read_lock_bp();                                                             \
-       __tp_probe = rcu_dereference_bp(__tracepoint_##provider##___##name.probes);     \
+       tp_rcu_read_lock_bp();                                                          \
+       __tp_probe = tp_rcu_dereference_bp(__tracepoint_##provider##___##name.probes);  \
        if (caa_unlikely(!__tp_probe))                                                  \
                goto end;                                                               \
        do {                                                                            \
@@ -139,7 +134,7 @@ static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARG
                                (_TP_ARGS_DATA_VAR(__VA_ARGS__));                       \
        } while ((++__tp_probe)->func);                                                 \
 end:                                                                                   \
-       rcu_read_unlock_bp();                                                           \
+       tp_rcu_read_unlock_bp();                                                        \
 }                                                                                      \
 static inline void __tracepoint_register_##provider##___##name(char *name,             \
                void *func, void *data)                                                 \
@@ -206,6 +201,20 @@ static void __attribute__((constructor)) __tracepoints__init(void)
                URCU_FORCE_CAST(int (*)(struct tracepoint * const *),
                                dlsym(liblttngust_handle,
                                        "tracepoint_unregister_lib"));
+#ifndef _LGPL_SOURCE
+       tp_rcu_read_lock_bp =
+               URCU_FORCE_CAST(void (*)(void),
+                               dlsym(liblttngust_handle,
+                                       "tp_rcu_read_lock_bp"));
+       tp_rcu_read_unlock_bp =
+               URCU_FORCE_CAST(void (*)(void),
+                               dlsym(liblttngust_handle,
+                                       "tp_rcu_read_unlock_bp"));
+       tp_rcu_dereference_sym_bp =
+               URCU_FORCE_CAST(void *(*)(void *p),
+                               dlsym(liblttngust_handle,
+                                       "tp_rcu_dereference_sym_bp"));
+#endif
        tracepoint_register_lib(__start___tracepoints_ptrs,
                                __stop___tracepoints_ptrs -
                                __start___tracepoints_ptrs);
index 3a50df66a08de552256a342987c153dbcdd701e0..0393aa467a282b17139a05ae17fd8336e7271fb9 100644 (file)
@@ -579,3 +579,25 @@ void exit_tracepoint(void)
 {
        initialized = 0;
 }
+
+/*
+ * Create the wrapper symbols.
+ */
+#undef tp_rcu_read_lock_bp
+#undef tp_rcu_read_unlock_bp
+#undef tp_rcu_dereference_bp
+
+void tp_rcu_read_lock_bp(void)
+{
+       rcu_read_lock_bp();
+}
+
+void tp_rcu_read_unlock_bp(void)
+{
+       rcu_read_unlock_bp();
+}
+
+void *tp_rcu_dereference_sym_bp(void *p)
+{
+       return rcu_dereference_bp(p);
+}
index 3ab8bfd8fbf3e55dbed4c3f4cd36cbf7f6ad2a50..66a90607fee7dc3bab04ccb5e269f0eec4c38a6c 100644 (file)
@@ -27,6 +27,7 @@
 #include <signal.h>
 #include <string.h>
 #include <arpa/inet.h>
+#include <stdlib.h>
 
 #define TRACEPOINT_DEFINE
 #include "ust_tests_demo.h"
index da33407b0db671aeb3e37bf5c332af4b074c543a..584d3f7b9f1b107d2d8a4986164127c6c2c45863 100644 (file)
@@ -27,6 +27,7 @@
 #include <signal.h>
 #include <string.h>
 #include <arpa/inet.h>
+#include <stdlib.h>
 
 #define TRACEPOINT_DEFINE
 #include "ust_tests_hello.h"
index da33407b0db671aeb3e37bf5c332af4b074c543a..584d3f7b9f1b107d2d8a4986164127c6c2c45863 100644 (file)
@@ -27,6 +27,7 @@
 #include <signal.h>
 #include <string.h>
 #include <arpa/inet.h>
+#include <stdlib.h>
 
 #define TRACEPOINT_DEFINE
 #include "ust_tests_hello.h"
This page took 0.02871 seconds and 4 git commands to generate.