Here's my attempt to use gcc-10's new symver attribute to avoid global
asm statements that cause trouble with LTO. That requires converting
from triple @ syntax to double @ syntax. To satisfy those picky linkers,
the unversioned name of the affected symbols has to be changed.
The NEW_VERSION macros have to be moved before the function definitions.
Also tried to improve the situation for older gcc versions. Although
gcc-5 added a no_reorder attribute that's supposed to help here, it
doesn't work reliably (but improves the situation substantially).
I've tested the patch with different compilers (gcc-10, gcc-9, gcc-6,
clang-11), linkers (bfd, gold, lld), 32/64 bit (x86), with/without LTO.
Of course you need to cheat a bit to build elfutils with clang, and
lld can't be used with every combination. The workaround for older gcc
was enough for gcc-9 and 32bit gcc-6, but 64bit gcc-6 builds needed
-flto-partition=none, so this seems to depend on the version and options
used.
Symbol versioning worked as expected in all cases, at least the list
of dynamic symbols of the libs looked good to me.
The test suite seems brittle, though. It fails on 32bit builds, with
gold or lld, and with lto builds using clang (unknown object format)
or gcc-6 (debug info not found). But that's not related to this patch.
For 64bit builds with gcc-{9,10} and bfd, the test suite succeeds even
with lto enabled.
Additional notes:
* The asm names for the compat versions seem unnecessary, but I've
kept them.
* Commenting out old versions in the .map file may not be needed.
It's mostly a leftover from an earlier attempt, but I didn't want to
re-run all test and I actually prefer it like this, so I left it in.
* See commit message below.
8<
Use symver attribute for symbol versioning instead of .symver
assembler directive when available. Convert to use double @ syntax
for default version in all cases (required when using the attribute).
Add the attributes externally_visible, no_reorder if available when
using assembler directives to improve the situation for < gcc-10.
This is not 100% reliable, though; -flto-partition=none may still be
needed in some cases.
Note that -Wno-error=stack-usage= is still needed to build with LTO.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24498
Signed-off-by: Alexander Miller
---
lib/ChangeLog | 13 +++
lib/eu-config.h| 63 +++---
libdw/ChangeLog| 13 +++
libdw/dwarf_aggregate_size.c | 4 +--
libdw/dwarf_arrayorder.c | 2 +-
libdw/dwarf_bitoffset.c| 2 +-
libdw/dwarf_bitsize.c | 2 +-
libdw/dwarf_bytesize.c | 2 +-
libdw/dwarf_decl_column.c | 2 +-
libdw/dwarf_decl_file.c| 2 +-
libdw/dwarf_decl_line.c| 2 +-
libdw/dwarf_srclang.c | 4 +--
libdw/libdw.map| 41 +++---
libdwelf/ChangeLog | 5 +++
libdwelf/dwelf_elf_begin.c | 2 +-
libdwfl/ChangeLog | 7
libdwfl/core-file.c| 4 +--
libdwfl/dwfl_module_build_id.c | 4 +--
libdwfl/dwfl_report_elf.c | 4 +--
19 files changed, 128 insertions(+), 50 deletions(-)
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 371e213..1f4cd62 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,16 @@
+2021-02-14 Alexander Miller
+
+ * eu-config.h (used_in_asm): New macro.
+ (NEW_INTDEF): New macro.
+ (NEW_VERSION): Mark symbol as used_in_asm. Use @@ symver and change
+ asm name instead. New variant using symver attribute if available.
+ (OLD_VERSION): Update new symbol name. Indent asm directives. New
+ variant using symver attribute.
+ (COMPAT_VERSION_NEWPROTO): Mark symbol as used_in_asm. Reorder
+ lines. Replace asm with __asm__ in declaration. New variant using
+ symver attribute.
+ (COMPAT_VERSION): Likewise.
+
2021-02-05 Mark Wielaard
* printversion.c (print_version): Update copyright year.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index f0e3d07..7e9bd1e 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -176,27 +176,66 @@ asm (".section predict_data, \"aw\"; .previous\n"
/* This macro is used by the tests conditionalize for standalone building. */
#define ELFUTILS_HEADER(name)
+/* Don't reorder with global asm blocks or optimize away. (Doesn't reliably
+ keep it in the same LTO partition, though; -flto-partition=none may be
+ still needed for some gcc versions < 10.) */
+#ifdef __has_attribute
+# if __has_attribute(no_reorder)
+# define used_in_asm __attribute__ ((externally_visible, no_reorder))
+# endif
+#endif
+#ifndef used_in_asm
+# define used_in_asm /* empty */
+#endif
#ifdef SYMBOL_VERSIONING
-# define OLD_VERSION(name, version) \
- asm (".globl _compat." #version "." #name "\n" \
- "_compat." #version "." #name " = " #name "\n" \
- ".symver