public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: Alexander Miller <alex.miller@gmx.de>
To: elfutils-devel@sourceware.org
Subject: [PATCH v2] Improve building with LTO
Date: Thu, 18 Feb 2021 03:38:56 +0100	[thread overview]
Message-ID: <20210218033856.18053044.alex.miller@gmx.de> (raw)
In-Reply-To: <20210214235718.7654b5f1.alex.miller@gmx.de>

From: Alexander Miller <alex.miller@gmx.de>

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 <alex.miller@gmx.de>
---
 lib/ChangeLog                  | 13 +++++++
 lib/eu-config.h                | 65 +++++++++++++++++++++++++++-------
 libdw/ChangeLog                | 11 ++++++
 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 +--
 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 +--
 18 files changed, 107 insertions(+), 30 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  <alex.miller@gmx.de>
+
+	* 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  <mark@klomp.org>
 
 	* printversion.c (print_version): Update copyright year.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index f0e3d07..c7d7cbb 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 b8038f0..597f54b 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,14 @@
+2021-02-14  Alexander Miller  <alex.miller@gmx.de>
+
+	* 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.
+
 2020-12-20  Dmitry V. Levin  <ldv@altlinux.org>
 
 	* .gitignore: New file.
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index 75105e4..552f122 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -209,6 +209,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)
 {
@@ -219,6 +220,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 da64f99..782e075 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 c1a3a34..61a0d59 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 0ed9b71..35e8744 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 116cd32..6d1ff9a 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 08d36b8..3225fd1 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 d4aa0a1..75662a3 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 80fae6c..6b31eeb 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 f10e764..77bd58c 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 a0ff9f4..cbfe1ec 100644
--- a/libdwelf/ChangeLog
+++ b/libdwelf/ChangeLog
@@ -1,3 +1,8 @@
+2021-02-14  Alexander Miller  <alex.miller@gmx.de>
+
+	* dwelf_elf_begin.c (dwelf_elf_begin): Move NEW_VERSION before
+	definition.
+
 2020-12-12  Dmitry V. Levin  <ldv@altlinux.org>
 
 	* libdwelf.h: Fix spelling typos in comments.
diff --git a/libdwelf/dwelf_elf_begin.c b/libdwelf/dwelf_elf_begin.c
index c7d63a1..c3cfe63 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 d107e78..c96c716 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2021-02-14  Alexander Miller  <alex.miller@gmx.de>
+
+	* 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-02-01  Érico Nogueira  <ericonr@disroot.org>
 
 	* dwfl_error.c (strerror_r): Only use the GNU version when available.
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index a0ccc9b..4e4c9b3 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 6ca9376..0c198f2 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 9da8669..a5f0e5e 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 *
-- 
2.26.2


  parent reply	other threads:[~2021-02-18  2:39 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-14 22:57 [PATCH] " Alexander Miller
2021-02-17 20:22 ` Mark Wielaard
2021-02-18 14:27   ` Alexander Miller
2021-02-18  2:38 ` Alexander Miller [this message]
2021-08-28  9:31   ` [PATCH v2] " Dmitry V. Levin
2021-11-04 11:23     ` Dmitry V. Levin
2021-11-04 12:12       ` Mark Wielaard
2021-11-08 10:02         ` Dmitry V. Levin
2021-11-08 23:18           ` Mark Wielaard
2021-11-09  8:58             ` Dmitry V. Levin
2021-11-09  9:04               ` Martin Liška
2021-11-09  9:09                 ` Dmitry V. Levin
2021-11-09  9:11                   ` Martin Liška
2021-11-09 11:45                 ` Mark Wielaard
2021-11-09 13:31                   ` Martin Liška
2021-11-09 13:33                     ` Martin Liška
2021-11-09 17:49                     ` Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210218033856.18053044.alex.miller@gmx.de \
    --to=alex.miller@gmx.de \
    --cc=elfutils-devel@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).