public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] lib: Use attribute symver when available to define symbol versioning.
@ 2020-04-10 19:42 Mark Wielaard
  2020-04-14 15:25 ` Mark Wielaard
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Wielaard @ 2020-04-10 19:42 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

GCC 10 introduces a function attribute to define symbol versioning.
Add a configure check to see if __attribute__((symver)) is supported.
If it is then define the OLD_VERSION, NEW_VERSION, COMPAT_VERSION
and COMPAT_VERSION_NEWPROTO macros using just attribute symver,
attribute alias and typeof function names. And avoid defining symbols
in asm statements.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 ChangeLog       |  4 ++++
 configure.ac    | 13 +++++++++++++
 lib/ChangeLog   |  5 +++++
 lib/eu-config.h | 20 ++++++++++++++++++--
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 854568e0..bff3bdef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2020-04-10  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add __attribute__((symver)) check.
+
 2020-03-30  Mark Wielaard  <mark@klomp.org>
 
 	* configure.ac: Set version to 0.179.
diff --git a/configure.ac b/configure.ac
index a39e800f..2a0aaca8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,19 @@ if test "$ac_cv_gcc_struct" = "yes"; then
 		  [Defined if __attribute__((gcc_struct)) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((symver))],
+	ac_cv_gcc_symver, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+__attribute__ ((__symver__ ("foo@VERS_1"))) int foo_v1 (void) { }
+])], ac_cv_gcc_symver=yes, ac_cv_gcc_symver=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_gcc_symver" = "yes"; then
+	AC_DEFINE([HAVE_GCC_SYMVER], [1],
+		  [Defined if __attribute__((symver)) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
 save_CFLAGS="$CFLAGS"
 CFLAGS="$save_CFLAGS -fPIC -Werror"
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 51c79841..07837cce 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-10  Mark Wielaard  <mark@klomp.org>
+
+	* eu-config.h: If HAVE_GCC_SYMVER define symbol versioning macros
+	using attribute symver.
+
 2019-08-25  Srđan Milaković  <sm108@rice.edu>
 
 	* dynamicsizehash_concurrent.{c,h}: New files.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 84b22d7c..ccbedeb0 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -177,6 +177,21 @@ asm (".section predict_data, \"aw\"; .previous\n"
 
 
 #ifdef SYMBOL_VERSIONING
+#ifdef HAVE_GCC_SYMVER
+# define OLD_VERSION(name, version) \
+  __attribute__((__symver__( #name "@" #version))) \
+  __attribute__((__alias__( #name ))) \
+  __typeof__( name ) _compat_##version_##name;
+#define NEW_VERSION(name, version) \
+  __attribute__((__symver__(#name "@@" #version))) \
+  __typeof__ ( name ) name ;
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+  __attribute__((__symver__ ( #name "@" #version ))) \
+  __typeof__(_compat_##prefix##_##name) _compat_##prefix##_##name;
+# define COMPAT_VERSION(name, version, prefix) \
+  __attribute__((__symver__(#name "@" #version))) \
+  __typeof__(name) _compat_##prefix##_##name;
+#else /* HAVE_GCC_SYMVER */
 # define OLD_VERSION(name, version) \
   asm (".globl _compat." #version "." #name "\n" \
        "_compat." #version "." #name " = " #name "\n" \
@@ -190,13 +205,14 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define COMPAT_VERSION(name, version, prefix) \
   asm (".symver _compat." #version "." #name "," #name "@" #version); \
   __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name);
-#else
+#endif /* HAVE_GCC_SYMVER */
+#else /* SYMBOL_VERSIONING */
 # 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"
-#endif
+#endif /* SYMBOL_VERSIONING */
 
 #ifndef FALLTHROUGH
 # ifdef HAVE_FALLTHROUGH
-- 
2.18.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] lib: Use attribute symver when available to define symbol versioning.
  2020-04-10 19:42 [PATCH] lib: Use attribute symver when available to define symbol versioning Mark Wielaard
@ 2020-04-14 15:25 ` Mark Wielaard
  2020-04-14 19:54   ` Mark Wielaard
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Wielaard @ 2020-04-14 15:25 UTC (permalink / raw)
  To: elfutils-devel

Hi,

On Fri, 2020-04-10 at 21:42 +0200, Mark Wielaard wrote:
> GCC 10 introduces a function attribute to define symbol versioning.
> Add a configure check to see if __attribute__((symver)) is supported.
> If it is then define the OLD_VERSION, NEW_VERSION, COMPAT_VERSION
> and COMPAT_VERSION_NEWPROTO macros using just attribute symver,
> attribute alias and typeof function names. And avoid defining symbols
> in asm statements.

Turns out this almost, but not completely work.

> +#define NEW_VERSION(name, version) \
> +  __attribute__((__symver__(#name "@@" #version))) \
> +  __typeof__ ( name ) name ;

Using the two @@ variant keeps the original name in the symbol table,
which will cause that symbol to be doubly marked as a version symbol my
the linker. We really need the tripple @@@ variant which will actually
rename and remove the original non-versioned name. But gcc10
attribute((symver)) only accepts the single and double @ variants.

I am looking how to work around this. The gcc function attribute
documentation implies that you shouldn't use the bare non-versioned
symbol name, but that is precisely what we do (so we don't have to mark
up each symbol, but can simply rely on the linker version map script).

Back to the drawing board...

Cheers,

Mark

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] lib: Use attribute symver when available to define symbol versioning.
  2020-04-14 15:25 ` Mark Wielaard
@ 2020-04-14 19:54   ` Mark Wielaard
  0 siblings, 0 replies; 3+ messages in thread
From: Mark Wielaard @ 2020-04-14 19:54 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 1511 bytes --]

On Tue, 2020-04-14 at 17:25 +0200, Mark Wielaard wrote:
> On Fri, 2020-04-10 at 21:42 +0200, Mark Wielaard wrote:
> > GCC 10 introduces a function attribute to define symbol versioning.
> > Add a configure check to see if __attribute__((symver)) is supported.
> > If it is then define the OLD_VERSION, NEW_VERSION, COMPAT_VERSION
> > and COMPAT_VERSION_NEWPROTO macros using just attribute symver,
> > attribute alias and typeof function names. And avoid defining symbols
> > in asm statements.
> 
> Turns out this almost, but not completely work.
> 
> > +#define NEW_VERSION(name, version) \
> > +  __attribute__((__symver__(#name "@@" #version))) \
> > +  __typeof__ ( name ) name ;
> 
> Using the two @@ variant keeps the original name in the symbol table,
> which will cause that symbol to be doubly marked as a version symbol my
> the linker. We really need the tripple @@@ variant which will actually
> rename and remove the original non-versioned name. But gcc10
> attribute((symver)) only accepts the single and double @ variants.
> 
> I am looking how to work around this. The gcc function attribute
> documentation implies that you shouldn't use the bare non-versioned
> symbol name, but that is precisely what we do (so we don't have to mark
> up each symbol, but can simply rely on the linker version map script).
> 
> Back to the drawing board...

OK, I found a workaround, as attached.
It feels a bit like a hack, but seems to do what is expected.

Cheers,

Mark

[-- Attachment #2: 0001-lib-Use-attribute-symver-when-available-to-define-sy.patch --]
[-- Type: text/x-patch, Size: 6695 bytes --]

From 60f18cd09d771eceb8762af2c46f27ae75b72422 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Wed, 8 Apr 2020 16:11:41 +0200
Subject: [PATCH] lib: Use attribute symver when available to define symbol
 versioning.

GCC 10 introduces a function attribute to define symbol versioning.
Add a configure check to see if __attribute__((symver)) is supported.
If it is then define the OLD_VERSION, NEW_VERSION, COMPAT_VERSION
and COMPAT_VERSION_NEWPROTO macros using just attribute symver,
attribute alias and typeof function names. And avoid defining symbols
in asm statements.

The attribute doesn't accept triple @ symver definitions.
The special foo@@@VERSION_XY version replaces all symbol references to
foo with foo@@VERSION_XY in the file, so there is no bare foo symbol
anymore. When there is still a bare foo symbol the linker creates
a default version for the first section it sees in the version script.
This might create duplicate default versions of the symbol.
we use a trick by placing a non-default alias of the symbol in
ELFUTILS_0 version section (which doesn't have any global symbols).
This prevents the linker from adding an (extra) default version of
the symbol.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 ChangeLog       |  4 ++++
 configure.ac    | 13 +++++++++++++
 lib/ChangeLog   |  5 +++++
 lib/eu-config.h | 23 +++++++++++++++++++++--
 libdw/ChangeLog | 10 ++++++++++
 libdw/libdw.map | 17 ++++-------------
 6 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 854568e0..bff3bdef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2020-04-10  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add __attribute__((symver)) check.
+
 2020-03-30  Mark Wielaard  <mark@klomp.org>
 
 	* configure.ac: Set version to 0.179.
diff --git a/configure.ac b/configure.ac
index a39e800f..2a0aaca8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,19 @@ if test "$ac_cv_gcc_struct" = "yes"; then
 		  [Defined if __attribute__((gcc_struct)) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((symver))],
+	ac_cv_gcc_symver, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+__attribute__ ((__symver__ ("foo@VERS_1"))) int foo_v1 (void) { }
+])], ac_cv_gcc_symver=yes, ac_cv_gcc_symver=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_gcc_symver" = "yes"; then
+	AC_DEFINE([HAVE_GCC_SYMVER], [1],
+		  [Defined if __attribute__((symver)) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
 save_CFLAGS="$CFLAGS"
 CFLAGS="$save_CFLAGS -fPIC -Werror"
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 51c79841..07837cce 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-10  Mark Wielaard  <mark@klomp.org>
+
+	* eu-config.h: If HAVE_GCC_SYMVER define symbol versioning macros
+	using attribute symver.
+
 2019-08-25  Srđan Milaković  <sm108@rice.edu>
 
 	* dynamicsizehash_concurrent.{c,h}: New files.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 84b22d7c..f5a6be22 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -177,6 +177,24 @@ asm (".section predict_data, \"aw\"; .previous\n"
 
 
 #ifdef SYMBOL_VERSIONING
+#ifdef HAVE_GCC_SYMVER
+# define OLD_VERSION(name, version) \
+  __attribute__((__symver__(#name "@" #version))) \
+  __attribute__((__alias__(#name))) \
+  __typeof__(name) _compat_##version_##name;
+#define NEW_VERSION(name, version) \
+  __attribute__((__symver__(#name "@@" #version))) \
+  __typeof__(name) name; \
+  __attribute__((__symver__(#name "@ELFUTILS_0"))) \
+  __attribute__((__alias__(#name))) \
+  __typeof__(name) _local_##name;
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+  __attribute__((__symver__(#name "@" #version))) \
+  __typeof__(_compat_##prefix##_##name) _compat_##prefix##_##name;
+# define COMPAT_VERSION(name, version, prefix) \
+  __attribute__((__symver__(#name "@" #version))) \
+  __typeof__(name) _compat_##prefix##_##name;
+#else /* HAVE_GCC_SYMVER */
 # define OLD_VERSION(name, version) \
   asm (".globl _compat." #version "." #name "\n" \
        "_compat." #version "." #name " = " #name "\n" \
@@ -190,13 +208,14 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define COMPAT_VERSION(name, version, prefix) \
   asm (".symver _compat." #version "." #name "," #name "@" #version); \
   __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name);
-#else
+#endif /* HAVE_GCC_SYMVER */
+#else /* SYMBOL_VERSIONING */
 # 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"
-#endif
+#endif /* SYMBOL_VERSIONING */
 
 #ifndef FALLTHROUGH
 # ifdef HAVE_FALLTHROUGH
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 59f33f9e..dae71b78 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,13 @@
+2020-04-14  Mark Wielaard  <mark@klomp.org>
+
+	* libdw.map (ELFUTILS_0): Explicitly mark everything local.
+	(ELFUTILS_0.122): Remove local wildcard.
+	(ELFUTILS_0.126): Likewise.
+	(ELFUTILS_0.127): Likewise.
+	(ELFUTILS_0.130): Likewise.
+	(ELFUTILS_0.136): Likewise.
+	(ELFUTILS_0.138): Likewise.
+
 2019-10-28  Aaron Merey  <amerey@redhat.com>
 
 	* Makefile.am (libdw_so_LDLIBS): Add -ldl for libdebuginfod.so dlopen.
diff --git a/libdw/libdw.map b/libdw/libdw.map
index decac05c..20009868 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -1,4 +1,7 @@
-ELFUTILS_0 { };
+ELFUTILS_0 {
+  local: *;
+};
+
 ELFUTILS_0.122 {
   global:
     dwarf_abbrevhaschildren;
@@ -141,16 +144,12 @@ ELFUTILS_0.122 {
     dwfl_standard_find_debuginfo;
     dwfl_version;
 
-  local:
-    *;
 } ELFUTILS_0;
 
 ELFUTILS_0.126 {
   global:
     dwarf_getelf;
 
-  local:
-    *;
 } ELFUTILS_0.122;
 
 ELFUTILS_0.127 {
@@ -161,8 +160,6 @@ ELFUTILS_0.127 {
     dwfl_report_begin_add;
     dwfl_module_address_section;
 
-  local:
-    *;
 } ELFUTILS_0.126;
 
 ELFUTILS_0.130 {
@@ -172,8 +169,6 @@ ELFUTILS_0.130 {
     dwfl_module_build_id;
     dwfl_module_report_build_id;
 
-  local:
-    *;
 } ELFUTILS_0.127;
 
 ELFUTILS_0.136 {
@@ -181,8 +176,6 @@ ELFUTILS_0.136 {
     dwfl_addrsegment;
     dwfl_report_segment;
 
-  local:
-    *;
 } ELFUTILS_0.130;
 
 ELFUTILS_0.138 {
@@ -190,8 +183,6 @@ ELFUTILS_0.138 {
     # Replaced ELFUTILS_0.130 version, which has bug-compatibility wrapper.
     dwfl_module_build_id;
 
-  local:
-    *;
 } ELFUTILS_0.136;
 
 ELFUTILS_0.142 {
-- 
2.18.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-04-14 19:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-10 19:42 [PATCH] lib: Use attribute symver when available to define symbol versioning Mark Wielaard
2020-04-14 15:25 ` Mark Wielaard
2020-04-14 19:54   ` Mark Wielaard

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).