summaryrefslogtreecommitdiff
path: root/lib/xref.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xref.h')
-rw-r--r--lib/xref.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/xref.h b/lib/xref.h
index e464da4131..426ffad705 100644
--- a/lib/xref.h
+++ b/lib/xref.h
@@ -119,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
@@ -218,12 +219,35 @@ 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_) \
{ \