summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Miller <[email protected]>2021-02-18 03:38:56 +0100
committerMark Wielaard <[email protected]>2021-11-08 22:33:05 +0100
commit039f427a3574ec75985c755108399a2bb37c2c86 (patch)
tree5011f802564349666f35d32da38fc6bd6197bf3d
parentc1e8c8c6b25cb2b5c16553609f19a9ed5dd4e146 (diff)
Improve building with LTO
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. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24498 Signed-off-by: Alexander Miller <[email protected]>
-rw-r--r--lib/ChangeLog13
-rw-r--r--lib/eu-config.h65
-rw-r--r--libdw/ChangeLog11
-rw-r--r--libdw/dwarf_aggregate_size.c4
-rw-r--r--libdw/dwarf_arrayorder.c2
-rw-r--r--libdw/dwarf_bitoffset.c2
-rw-r--r--libdw/dwarf_bitsize.c2
-rw-r--r--libdw/dwarf_bytesize.c2
-rw-r--r--libdw/dwarf_decl_column.c2
-rw-r--r--libdw/dwarf_decl_file.c2
-rw-r--r--libdw/dwarf_decl_line.c2
-rw-r--r--libdw/dwarf_srclang.c4
-rw-r--r--libdwelf/ChangeLog5
-rw-r--r--libdwelf/dwelf_elf_begin.c2
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/core-file.c4
-rw-r--r--libdwfl/dwfl_module_build_id.c4
-rw-r--r--libdwfl/dwfl_report_elf.c4
18 files changed, 107 insertions, 30 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog
index c72452b1..8f4d4d9f 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,16 @@
+2021-02-14 Alexander Miller <[email protected]>
+
+ * 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-09-10 Colin Cross <[email protected]>
* error.c (error): Call fflush on stdout and stderr. Setup errno and
diff --git a/lib/eu-config.h b/lib/eu-config.h
index f0e3d07a..c7d7cbb2 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -176,27 +176,68 @@ asm (".section predict_data, \"aw\"; .previous\n"
/* This macro is used by the tests conditionalize for standalone building. */
#define ELFUTILS_HEADER(name) <lib##name.h>
+/* 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 _compat." #version "." #name "," #name "@" #version);
-# define NEW_VERSION(name, version) \
- asm (".symver " #name "," #name "@@@" #version);
-# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
- asm (".symver _compat." #version "." #name "," #name "@" #version); \
+# define NEW_INTDEF(name) __typeof (name) INTUSE(name) \
+ __attribute__ ((alias ("_new." #name))) attribute_hidden;
+# ifdef __has_attribute
+# if __has_attribute(symver)
+# define NEW_VERSION(name, version) \
+ __typeof (name) name __asm__ ("_new." #name) \
+ __attribute__ ((symver (#name "@@" #version)));
+# define OLD_VERSION(name, version) _OLD_VERSION1(name, __COUNTER__, version)
+# define _OLD_VERSION1(name, num, version) _OLD_VERSION2(name, num, version)
+# define _OLD_VERSION2(name, num, version) \
+ __typeof (name) _compat_old##num##_##name \
+ __asm__ ("_compat." #version "." #name) \
+ __attribute__ ((alias ("_new." #name), symver (#name "@" #version)));
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
__typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \
- asm ("_compat." #version "." #name);
-# define COMPAT_VERSION(name, version, prefix) \
+ __asm__ ("_compat." #version "." #name) \
+ __attribute__ ((symver (#name "@" #version)));
+# define COMPAT_VERSION(name, version, prefix) \
asm (".symver _compat." #version "." #name "," #name "@" #version); \
- __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name);
+ __typeof (name) _compat_##prefix##_##name \
+ __asm__ ("_compat." #version "." #name) \
+ __attribute__ ((symver (#name "@" #version)));
+# endif
+# endif
+# ifndef NEW_VERSION
+# define OLD_VERSION(name, version) \
+ asm (".globl _compat." #version "." #name "\n\t" \
+ "_compat." #version "." #name " = _new." #name "\n\t" \
+ ".symver _compat." #version "." #name "," #name "@" #version);
+# define NEW_VERSION(name, version) \
+ __typeof (name) name __asm__ ("_new." #name) used_in_asm; \
+ asm (".symver _new." #name ", " #name "@@" #version);
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+ __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \
+ __asm__ ("_compat." #version "." #name) used_in_asm; \
+ asm (".symver _compat." #version "." #name ", " #name "@" #version);
+# define COMPAT_VERSION(name, version, prefix) \
+ __typeof (name) _compat_##prefix##_##name \
+ __asm__ ("_compat." #version "." #name) used_in_asm; \
+ asm (".symver _compat." #version "." #name ", " #name "@" #version);
+# endif
#else
+# define NEW_INTDEF(name) INTDEF(name)
# define OLD_VERSION(name, version) /* Nothing for static linking. */
# define NEW_VERSION(name, version) /* Nothing for static linking. */
# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
error "should use #ifdef SYMBOL_VERSIONING"
-# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) \
+ error "should use #ifdef SYMBOL_VERSIONING"
#endif
#ifndef FALLTHROUGH
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 311f34b5..b3836833 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,14 @@
+2021-02-14 Alexander Miller <[email protected]>
+
+ * dwarf_aggregate_size.c (dwarf_aggregate_size): Move NEW_VERSION
+ before definition. Replace INTDEF with NEW_INTDEF.
+ * dwarf_srclang.c (dwarf_srclang): Likewise.
+ * dwarf_arrayorder.c (dwarf_arrayorder): Move NEW_VERSION.
+ * dwarf_bitoffset.c (dwarf_bitoffset): Likewise.
+ * dwarf_bitsize.c (dwarf_bitsize): Likewise.
+ * dwarf_bytesize.c (dwarf_bytesize): Likewise.
+ * dwarf_decl_column.c (dwarf_decl_column): Likewise.
+
2021-10-18 Mark Wielaard <[email protected]>
* dwarf_aggregate_size.c (get_type): Don't pass NULL to
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index 89f2029e..8216ae42 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -241,6 +241,7 @@ aggregate_size (Dwarf_Die *die, Dwarf_Word *size,
return -1;
}
+NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161)
int
dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size)
{
@@ -251,6 +252,5 @@ dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size)
return aggregate_size (&die_mem, size, &type_mem, 0);
}
-INTDEF (dwarf_aggregate_size)
+NEW_INTDEF (dwarf_aggregate_size)
OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
-NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161)
diff --git a/libdw/dwarf_arrayorder.c b/libdw/dwarf_arrayorder.c
index da64f992..782e075c 100644
--- a/libdw/dwarf_arrayorder.c
+++ b/libdw/dwarf_arrayorder.c
@@ -35,6 +35,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_arrayorder, ELFUTILS_0.143)
int
dwarf_arrayorder (Dwarf_Die *die)
{
@@ -46,4 +47,3 @@ dwarf_arrayorder (Dwarf_Die *die)
&value) == 0 ? (int) value : -1;
}
OLD_VERSION (dwarf_arrayorder, ELFUTILS_0.122)
-NEW_VERSION (dwarf_arrayorder, ELFUTILS_0.143)
diff --git a/libdw/dwarf_bitoffset.c b/libdw/dwarf_bitoffset.c
index c1a3a343..61a0d593 100644
--- a/libdw/dwarf_bitoffset.c
+++ b/libdw/dwarf_bitoffset.c
@@ -35,6 +35,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_bitoffset, ELFUTILS_0.143)
int
dwarf_bitoffset (Dwarf_Die *die)
{
@@ -46,4 +47,3 @@ dwarf_bitoffset (Dwarf_Die *die)
&value) == 0 ? (int) value : -1;
}
OLD_VERSION (dwarf_bitoffset, ELFUTILS_0.122)
-NEW_VERSION (dwarf_bitoffset, ELFUTILS_0.143)
diff --git a/libdw/dwarf_bitsize.c b/libdw/dwarf_bitsize.c
index 0ed9b710..35e8744c 100644
--- a/libdw/dwarf_bitsize.c
+++ b/libdw/dwarf_bitsize.c
@@ -35,6 +35,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_bitsize, ELFUTILS_0.143)
int
dwarf_bitsize (Dwarf_Die *die)
{
@@ -46,4 +47,3 @@ dwarf_bitsize (Dwarf_Die *die)
&value) == 0 ? (int) value : -1;
}
OLD_VERSION (dwarf_bitsize, ELFUTILS_0.122)
-NEW_VERSION (dwarf_bitsize, ELFUTILS_0.143)
diff --git a/libdw/dwarf_bytesize.c b/libdw/dwarf_bytesize.c
index 116cd321..6d1ff9ae 100644
--- a/libdw/dwarf_bytesize.c
+++ b/libdw/dwarf_bytesize.c
@@ -35,6 +35,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_bytesize, ELFUTILS_0.143)
int
dwarf_bytesize (Dwarf_Die *die)
{
@@ -46,4 +47,3 @@ dwarf_bytesize (Dwarf_Die *die)
&value) == 0 ? (int) value : -1;
}
OLD_VERSION (dwarf_bytesize, ELFUTILS_0.122)
-NEW_VERSION (dwarf_bytesize, ELFUTILS_0.143)
diff --git a/libdw/dwarf_decl_column.c b/libdw/dwarf_decl_column.c
index 08d36b87..3225fd18 100644
--- a/libdw/dwarf_decl_column.c
+++ b/libdw/dwarf_decl_column.c
@@ -35,10 +35,10 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_decl_column, ELFUTILS_0.143)
int
dwarf_decl_column (Dwarf_Die *decl, int *colp)
{
return __libdw_attr_intval (decl, colp, DW_AT_decl_column);
}
OLD_VERSION (dwarf_decl_column, ELFUTILS_0.122)
-NEW_VERSION (dwarf_decl_column, ELFUTILS_0.143)
diff --git a/libdw/dwarf_decl_file.c b/libdw/dwarf_decl_file.c
index d4aa0a18..75662a33 100644
--- a/libdw/dwarf_decl_file.c
+++ b/libdw/dwarf_decl_file.c
@@ -36,6 +36,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_decl_file, ELFUTILS_0.143)
const char *
dwarf_decl_file (Dwarf_Die *die)
{
@@ -86,4 +87,3 @@ dwarf_decl_file (Dwarf_Die *die)
return cu->files->info[idx].name;
}
OLD_VERSION (dwarf_decl_file, ELFUTILS_0.122)
-NEW_VERSION (dwarf_decl_file, ELFUTILS_0.143)
diff --git a/libdw/dwarf_decl_line.c b/libdw/dwarf_decl_line.c
index 80fae6c9..6b31eebe 100644
--- a/libdw/dwarf_decl_line.c
+++ b/libdw/dwarf_decl_line.c
@@ -37,13 +37,13 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_decl_line, ELFUTILS_0.143)
int
dwarf_decl_line (Dwarf_Die *func, int *linep)
{
return __libdw_attr_intval (func, linep, DW_AT_decl_line);
}
OLD_VERSION (dwarf_decl_line, ELFUTILS_0.122)
-NEW_VERSION (dwarf_decl_line, ELFUTILS_0.143)
int internal_function
diff --git a/libdw/dwarf_srclang.c b/libdw/dwarf_srclang.c
index f10e7642..77bd58c2 100644
--- a/libdw/dwarf_srclang.c
+++ b/libdw/dwarf_srclang.c
@@ -35,6 +35,7 @@
#include "libdwP.h"
+NEW_VERSION (dwarf_srclang, ELFUTILS_0.143)
int
dwarf_srclang (Dwarf_Die *die)
{
@@ -45,6 +46,5 @@ dwarf_srclang (Dwarf_Die *die)
(die, DW_AT_language, &attr_mem),
&value) == 0 ? (int) value : -1;
}
-INTDEF (dwarf_srclang)
+NEW_INTDEF (dwarf_srclang)
OLD_VERSION (dwarf_srclang, ELFUTILS_0.122)
-NEW_VERSION (dwarf_srclang, ELFUTILS_0.143)
diff --git a/libdwelf/ChangeLog b/libdwelf/ChangeLog
index 1abee0e8..5f7fb4ed 100644
--- a/libdwelf/ChangeLog
+++ b/libdwelf/ChangeLog
@@ -1,3 +1,8 @@
+2021-02-14 Alexander Miller <[email protected]>
+
+ * dwelf_elf_begin.c (dwelf_elf_begin): Move NEW_VERSION before
+ definition.
+
2021-09-06 Dmitry V. Levin <[email protected]>
* dwelf_strtab.c (dwelf_strtab_init): Remove cast of calloc return
diff --git a/libdwelf/dwelf_elf_begin.c b/libdwelf/dwelf_elf_begin.c
index c7d63a1c..c3cfe633 100644
--- a/libdwelf/dwelf_elf_begin.c
+++ b/libdwelf/dwelf_elf_begin.c
@@ -36,6 +36,7 @@
#include <unistd.h>
+NEW_VERSION (dwelf_elf_begin, ELFUTILS_0.177)
Elf *
dwelf_elf_begin (int fd)
{
@@ -61,4 +62,3 @@ dwelf_elf_begin (int fd)
return NULL;
}
OLD_VERSION (dwelf_elf_begin, ELFUTILS_0.175)
-NEW_VERSION (dwelf_elf_begin, ELFUTILS_0.177)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d35674c7..f7e24a21 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2021-02-14 Alexander Miller <[email protected]>
+
+ * core-file.c (dwfl_core_file_report): Move NEW_VERSION before
+ definition. Replace INTDEF with NEW_INTDEF.
+ * dwfl_module_build_id.c (dwfl_module_build_id): Likewise.
+ * dwfl_report_elf.c (dwfl_report_elf): Likewise.
+
2021-09-06 Dmitry V. Levin <[email protected]>
* linux-pid-attach.c (read_cached_memory): Remove cast of malloc
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index a0ccc9b3..4e4c9b3c 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -440,6 +440,7 @@ __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
return false;
}
+NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
int
dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
{
@@ -625,8 +626,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
error rather than just nothing found. */
return listed > 0 ? listed : retval;
}
-INTDEF (dwfl_core_file_report)
-NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
+NEW_INTDEF (dwfl_core_file_report)
#ifdef SYMBOL_VERSIONING
int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c
index 6ca93761..0c198f23 100644
--- a/libdwfl/dwfl_module_build_id.c
+++ b/libdwfl/dwfl_module_build_id.c
@@ -77,6 +77,7 @@ __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr);
}
+NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
int
dwfl_module_build_id (Dwfl_Module *mod,
const unsigned char **bits, GElf_Addr *vaddr)
@@ -102,8 +103,7 @@ dwfl_module_build_id (Dwfl_Module *mod,
*vaddr = mod->build_id_vaddr;
return mod->build_id_len;
}
-INTDEF (dwfl_module_build_id)
-NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
+NEW_INTDEF (dwfl_module_build_id)
#ifdef SYMBOL_VERSIONING
COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 9da86698..a5f0e5e5 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -287,6 +287,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
return m;
}
+NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
Dwfl_Module *
dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
GElf_Addr base, bool add_p_vaddr)
@@ -322,8 +323,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
return mod;
}
-INTDEF (dwfl_report_elf)
-NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
+NEW_INTDEF (dwfl_report_elf)
#ifdef SYMBOL_VERSIONING
Dwfl_Module *