summaryrefslogtreecommitdiff
path: root/lib/xref.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xref.h')
-rw-r--r--lib/xref.h42
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/xref.h b/lib/xref.h
index 11796bc4f8..b3243fa058 100644
--- a/lib/xref.h
+++ b/lib/xref.h
@@ -23,6 +23,10 @@
#include <errno.h>
#include "compiler.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum xref_type {
XREFT_NONE = 0,
@@ -115,6 +119,7 @@ struct xref_block {
extern struct xref_block *xref_blocks;
extern void xref_block_add(struct xref_block *block);
+extern void xref_gcc_workaround(const struct xref *xref);
#ifndef HAVE_SECTION_SYMS
/* we have a build system patch to use GNU ld on Solaris; if that doesn't
@@ -139,8 +144,11 @@ extern const struct xref * const __stop_xref_array[1] DSO_LOCAL;
*/
#define XREF_SETUP() \
static const struct xref _dummy_xref = { \
- .file = __FILE__, .line = __LINE__, .func = "dummy", \
- .type = XREFT_NONE, \
+ /* .xrefdata = */ NULL, \
+ /* .type = */ XREFT_NONE, \
+ /* .line = */ __LINE__, \
+ /* .file = */ __FILE__, \
+ /* .func = */ "dummy", \
}; \
static const struct xref * const _dummy_xref_p \
__attribute__((used, section("xref_array"))) \
@@ -214,17 +222,43 @@ extern const struct xref * const __stop_xref_array[1] DSO_LOCAL;
#endif /* HAVE_SECTION_SYMS */
/* emit the array entry / pointer to xref */
+#if defined(__clang__) || !defined(__cplusplus)
#define XREF_LINK(dst) \
static const struct xref * const NAMECTR(xref_p_) \
__attribute__((used, section("xref_array"))) \
= &(dst) \
/* end */
+#else /* GCC && C++ */
+/* workaround for GCC bug 41091 (dated 2009), added in 2021...
+ *
+ * this breaks extraction of xrefs with xrelfo.py (because the xref_array
+ * entry will be missing), but provides full runtime functionality. To get
+ * the proper list of xrefs from C++ code, build with clang...
+ */
+struct _xref_p {
+ const struct xref * const ptr;
+
+ _xref_p(const struct xref *_ptr) : ptr(_ptr)
+ {
+ xref_gcc_workaround(_ptr);
+ }
+};
+
+#define XREF_LINK(dst) \
+ static const struct _xref_p __attribute__((used)) \
+ NAMECTR(xref_p_)(&(dst)) \
+ /* end */
+#endif
+
/* initializer for a "struct xref" */
#define XREF_INIT(type_, xrefdata_, func_) \
{ \
- .type = (type_), .xrefdata = (xrefdata_), \
- .file = __FILE__, .line = __LINE__, .func = func_, \
+ /* .xrefdata = */ (xrefdata_), \
+ /* .type = */ (type_), \
+ /* .line = */ __LINE__, \
+ /* .file = */ __FILE__, \
+ /* .func = */ func_, \
} \
/* end */