diff options
author | David Lamparter <equinox@diac24.net> | 2021-02-02 19:38:38 +0100 |
---|---|---|
committer | David Lamparter <equinox@diac24.net> | 2021-02-03 00:55:07 +0100 |
commit | 08a73c422de98eb12a5f3a86112e7a4829eb3fd6 (patch) | |
tree | 4e70d2ce2c2c5ecaae37799acf1b1fafcc7beed9 /lib/xref.h | |
parent | lib/xref: restore lost extern "C" beginning (diff) | |
download | frr-08a73c422de98eb12a5f3a86112e7a4829eb3fd6.tar.xz frr-08a73c422de98eb12a5f3a86112e7a4829eb3fd6.zip |
lib/xref: work around GCC bug 41091
gcc fucks up global variables with section attributes when they're used
in templated C++ code. The template instantiation "magic" kinda breaks
down (it's implemented through COMDAT in the linker, which clashes with
the section attribute.)
The workaround provides full runtime functionality, but the xref
extraction tool (xrelfo.py) won't work on C++ code compiled by GCC.
FWIW, clang gets this right.
Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'lib/xref.h')
-rw-r--r-- | lib/xref.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/xref.h b/lib/xref.h index e464da413..426ffad70 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_) \ { \ |