+/*
+ * Deal with gcc O1 optimisation issues with weak hidden symbols. gcc
+ * 4.8 and prior does not have the same behavior for symbol scoping on
+ * 32-bit powerpc depending on the object size: symbols for objects of 8
+ * bytes or less have the same address throughout a module, whereas they
+ * have different addresses between compile units for objects larger
+ * than 8 bytes. Add this pointer indirection to ensure that the symbol
+ * scoping match that of the other weak hidden symbols found in this
+ * header.
+ */
+struct lttng_ust_tracepoint_dlopen *tracepoint_dlopen_ptr
+ __attribute__((weak, visibility("hidden")));
+
+/*
+ * Tracepoint dynamic linkage handling (callbacks). Hidden visibility: shared
+ * across objects in a module/main executable. The callbacks are used to
+ * control and check if the destructors should be executed.
+ */
+struct lttng_ust_tracepoint_destructors_syms {
+ int *old_tracepoint_disable_destructors;
+ void (*tracepoint_disable_destructors)(void);
+ int (*tracepoint_get_destructors_state)(void);
+};
+
+extern struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms;
+extern struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr;
+
+struct lttng_ust_tracepoint_destructors_syms tracepoint_destructors_syms
+ __attribute__((weak, visibility("hidden")));
+struct lttng_ust_tracepoint_destructors_syms *tracepoint_destructors_syms_ptr
+ __attribute__((weak, visibility("hidden")));
+
+static inline void tracepoint_disable_destructors(void)
+{
+ if (!tracepoint_dlopen_ptr)
+ tracepoint_dlopen_ptr = &tracepoint_dlopen;
+ if (!tracepoint_destructors_syms_ptr)
+ tracepoint_destructors_syms_ptr = &tracepoint_destructors_syms;
+ if (tracepoint_dlopen_ptr->liblttngust_handle
+ && tracepoint_destructors_syms_ptr->tracepoint_disable_destructors)
+ tracepoint_destructors_syms_ptr->tracepoint_disable_destructors();
+ *tracepoint_destructors_syms_ptr->old_tracepoint_disable_destructors = 1;
+}
+
+#ifndef _LGPL_SOURCE
+static inline void lttng_ust_notrace
+__tracepoint__init_urcu_sym(void);
+static inline void
+__tracepoint__init_urcu_sym(void)
+{
+ if (!tracepoint_dlopen_ptr)
+ tracepoint_dlopen_ptr = &tracepoint_dlopen;
+ /*
+ * Symbols below are needed by tracepoint call sites and probe
+ * providers.
+ */
+ if (!tracepoint_dlopen_ptr->rcu_read_lock_sym_bp)
+ tracepoint_dlopen_ptr->rcu_read_lock_sym_bp =
+ URCU_FORCE_CAST(void (*)(void),
+ dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
+ "tp_rcu_read_lock_bp"));
+ if (!tracepoint_dlopen_ptr->rcu_read_unlock_sym_bp)
+ tracepoint_dlopen_ptr->rcu_read_unlock_sym_bp =
+ URCU_FORCE_CAST(void (*)(void),
+ dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
+ "tp_rcu_read_unlock_bp"));
+ if (!tracepoint_dlopen_ptr->rcu_dereference_sym_bp)
+ tracepoint_dlopen_ptr->rcu_dereference_sym_bp =
+ URCU_FORCE_CAST(void *(*)(void *p),
+ dlsym(tracepoint_dlopen_ptr->liblttngust_handle,
+ "tp_rcu_dereference_sym_bp"));
+}
+#else
+static inline void lttng_ust_notrace
+__tracepoint__init_urcu_sym(void);
+static inline void
+__tracepoint__init_urcu_sym(void)
+{
+}
+#endif