Gentoolto: GCC __symver__ attribute support

Created on 30 Dec 2019  Â·  14Comments  Â·  Source: InBetweenNames/gentooLTO

It looks like future versions of GCC (>=10.0 ?) will introduce __symver__ attribute as possible replacement for the asm (".symver foo_v1, foo@VERS_1") code. Which will likely help some packages to compile with -flto (#458 ?).

Description

_Note: I manually converted formatting to MD, so there might be errors, especially with \@_

symver ("name2@nodename")

On ELF targets this attribute creates a symbol version. The name2 part
of the parameter is the actual name of the symbol by which it will be
externally referenced. The nodename portion should be the name of a
node specified in the version script supplied to the linker when building a
shared library. Versioned symbol must be defined and must be exported with
default visibility.

__attribute__ ((__symver__ ("foo@VERS_1"))) int
foo_v1 (void)
{
}

Will produce a .symver foo_v1, foo@VERS_1 directive in the assembler
output.

It's an error to define multiple version of a given symbol. In such case
an alias can be used.

__attribute__ ((__symver__ ("foo@VERS_2")))
__attribute__ ((alias ("foo_v1")))
int symver_foo_v1 (void);

This example creates an alias of foo_v1 with symbol name
symver_foo_v1 which will be version VERS_2 of foo.

Finally if the parameter is "name2@@nodename" then in
addition to creating a symbol version (as if
"name2@nodename" was used) the version will be also used
to resolve name2 by the linker.

Discussions

https://gcc.gnu.org/ml/gcc-patches/2019-11/threads.html#01334
https://gcc.gnu.org/ml/gcc-patches/2019-12/threads.html#00032

https://gcc.gnu.org/ml/gcc-patches/2019-12/threads.html#01162

Patches

https://gcc.gnu.org/ml/gcc-patches/2019-11/msg02712.html - symver attribute support
https://gcc.gnu.org/ml/gcc-patches/2019-12/msg01363.html - some binutils workarounds

Possible conversion

before

void foo () { ... }

asm (".symver ...");

after

void foo () { ... }

extern __typeof (foo) foo __attribute__((symver ("bar@@BAZ")));

https://gcc.gnu.org/ml/gcc-patches/2019-12/msg00040.html

Most helpful comment

Found an suspect in my overrides: media-libs/alsa-lib-1.2.1.2

--- a/include/alsa-symbols.h
+++ b/include/alsa-symbols.h
@@ -30,9 +30,9 @@
 #define INTERNAL(Name) INTERNAL_CONCAT2_2(__, Name)

 #define symbol_version(real, name, version) \
-       __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@" #version)
+       extern __typeof (real) real __attribute__((symver (#name "@" #version)))
 #define default_symbol_version(real, name, version) \
-       __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version)
+       extern __typeof (real) real __attribute__((symver (#name "@@" #version)))

 #define EXPORT_SYMBOL __attribute__((visibility("default"),externally_visible))

Compiled fine with -flto enabled. Looks like everything works as before so far.


I guess we should kindly ask Gentooâ„¢ to backport those GCC patches, so we will be able to play w/ symver more freely. Anyone with account on bugs.gentoo.org ?

All 14 comments

Ok, I patched sys-devel/gcc-9.2.0-r3, sys-cluster/glusterfs-6.5 for testing and at least it compiles with -flto enabled.

Patch for sys-cluster/glusterfs-6.5:

--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -81,16 +81,16 @@
 #define GFAPI_PRIVATE(sym, ver) /**/
 #endif
 #define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver)                                   \
-    asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver))
+    extern __typeof (pub_##fn) pub_##fn __attribute__((symver (STR(fn) "@@GFAPI_" STR(ver))))

 #define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver)                                  \
-    asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver))
+    extern __typeof (priv_##fn) priv_##fn __attribute__((symver (STR(fn) "@@GFAPI_PRIVATE_" STR(ver))))

 #define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver)                                     \
-    asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver))
+    extern __typeof (pub_##fn1) pub_##fn1 __attribute__((symver (STR(fn2) "@GFAPI_" STR(ver))))

 #define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver)                                    \
-    asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver))
+    extern __typeof (priv_##fn1) priv_##fn1 __attribute__((symver (STR(fn2) "@GFAPI_PRIVATE_" STR(ver))))
 #define STR(str) #str
 #else
 #ifndef GFAPI_PUBLIC

Found an suspect in my overrides: media-libs/alsa-lib-1.2.1.2

--- a/include/alsa-symbols.h
+++ b/include/alsa-symbols.h
@@ -30,9 +30,9 @@
 #define INTERNAL(Name) INTERNAL_CONCAT2_2(__, Name)

 #define symbol_version(real, name, version) \
-       __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@" #version)
+       extern __typeof (real) real __attribute__((symver (#name "@" #version)))
 #define default_symbol_version(real, name, version) \
-       __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version)
+       extern __typeof (real) real __attribute__((symver (#name "@@" #version)))

 #define EXPORT_SYMBOL __attribute__((visibility("default"),externally_visible))

Compiled fine with -flto enabled. Looks like everything works as before so far.


I guess we should kindly ask Gentooâ„¢ to backport those GCC patches, so we will be able to play w/ symver more freely. Anyone with account on bugs.gentoo.org ?

Do we know when gcc-10 will be released? If it's not too long (their release timeline if they've stuck to it seems to suggest it won't be much longer), rather than backporting patches it could be more beneficial to import a newer snapshot of gcc to this overlay for testing.

Near 2020-05 according to release timeline? Then 10.1 will be masked for a while in portage.

My attempt to port them for gcc-9.2.0:
0001-gcc-symver-attribute.patch.gz
0002-gcc-symver-attribute-lto-binutils-workarounds.patch.gz
Unpack into /etc/portage/patches/sys-devel/gcc-9.2.0/. Use at your own risk.

We should really look into this for when GCC 10 comes around. It could knock off a chunk of overrides

Hm... Are there any GCC 10 live ebuilds in the Gentoo tree? If so, how smart would it be to switch to the compiler on a day-to-day system?

@elsandosgrande
Un-keyword sys-devel/gcc:10, use eselect gcc set only on packages you want to test. I see no problem.

  1. Thank you! Opens the Gentoo wiki in another tab
  2. Um... I was thinking of using it on all of the packages.

@pchome So...

~~~
sandy@sandys-pavilion:~$ equery meta sys-devel/gcc

  • sys-devel/gcc [gentoo]
    Maintainer: [email protected] (Gentoo Toolchain Project)
    Upstream: Remote-ID: cpe:/a:gnu:gcc ID: cpe
    Remote-ID: dgcc ID: sourceforge
    Homepage: https://gcc.gnu.org/
    Location: /usr/portage/sys-devel/gcc
    Keywords: 3.3.6-r5:3.3.6: ~amd64 ~x86
    Keywords: 3.4.6-r5:3.4.6: ~alpha ~amd64 ~arm ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 -*
    Keywords: 4.0.4-r3:4.0.4:
    Keywords: 4.1.2-r2:4.1.2: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 -*
    Keywords: 4.2.4-r4:4.2.4: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~ppc ~ppc64 ~sparc ~x86
    Keywords: 4.3.6-r4:4.3.6: -hppa ~alpha ~amd64 ~arm ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.4.7-r3:4.4.7: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.5.4-r3:4.5.4: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.6.4-r3:4.6.4: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.7.4-r3:4.7.4: ~alpha ~amd64 ~arm ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.8.5-r3:4.8.5: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 4.9.4-r1:4.9.4: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 5.5.0:5.5.0: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 6.5.0-r1:6.5.0: alpha amd64 arm arm64 hppa ia64 m68k ppc ppc64 s390 sh sparc x86 ~mips
    Keywords: 7.4.0-r2:7.4.0: alpha amd64 arm arm64 hppa ia64 m68k ppc ppc64 s390 sh sparc x86 ~mips ~ppc-macos
    Keywords: 7.5.0:7.5.0: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc-macos ~ppc64 ~s390 ~sh ~sparc ~x86
    Keywords: 8.3.0-r1:8.3.0: alpha amd64 arm arm64 hppa ia64 m68k ppc ppc64 s390 sh sparc x86
    Keywords: 8.3.0-r3:8.3.0: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sh ~sparc ~x86
    Keywords: 9.2.0-r2:9.2.0: alpha amd64 arm arm64 hppa ia64 ppc ppc64 s390 sparc x86
    Keywords: 9.2.0-r3:9.2.0: ~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sh ~sparc ~x86
    Keywords: 10.0.0_pre9999:10:
    License: GPL-3+ LGPL-3+ || ( GPL-3+ libgcc libstdc++ gcc-runtime-library-exception-3.1 ) FDL-1.3+
    sandy@sandys-pavilion:~$ emerge --pretend =sys-devel/gcc:10
    !!! '=sys-devel/gcc:10' is not a valid package atom.
    !!! Please check ebuild(5) for full details.
    ~~~

I see no keywords for GCC 10...

I mean echo 'sys-devel/gcc:10 **' >> /etc/portage/package.accept_keywords
https://wiki.gentoo.org/wiki//etc/portage/package.accept_keywords

Also use emerge --pretend sys-devel/gcc:10 , w/o = ,
or emerge --pretend =sys-devel/gcc-10.0.0_pre9999

Since this is an unstable package you also have to promise not to bug the Gentoo toolchain maintainers (do not file bugs on bugs.gentoo.org):

/etc/portage/env/i-promise-to-supply-patches-with-bugs

I_PROMISE_TO_SUPPLY_PATCHES_WITH_BUGS=1

/etc/portage/package.env

(that can also be a folder in which case use something like /etc/portage/package.env/gcc)

sys-devel/gcc:10 i-promise-to-supply-patches-with-bugs

I wouldn't use this on your host system, maybe in a chroot though.

  1. I know that such bug reports go directly to GNU, if anywhere.
  2. I figured it out from a forum post of a guy accidentally having it unmasked.
  3. https://forums.gentoo.org/viewtopic-p-8410082.html

BTW, ...
https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Common-Function-Attributes.html

EDIT: a live example how to use this:
$ grep flto /var/db/pkg/*/*/*.ebuild

...
/var/db/pkg/sys-apps/attr-2.4.48-r5/attr-2.4.48-r5.ebuild:      # Remove -flto* from flags as this breaks binaries (bug #644048)
/var/db/pkg/sys-apps/attr-2.4.48-r5/attr-2.4.48-r5.ebuild:      filter-flags -flto*
...

There is a patch and it compiles with LTO. It has some interesting parts:

Add __attribute__((no_reorder)) to the wrapper functions
to avoid problems during LTO partitioning, since function definitions
and their corresponding .symver directives must be emitted to the same
partition to work correctly.

-int libattr_lsetxattr(const char *path, const char *name,
-             void *value, size_t size, int flags)
+__attribute__((no_reorder))
+int lsetxattr(const char *path, const char *name,
+         const void *value, size_t size, int flags)
 {
    return syscall(__NR_lsetxattr, path, name, value, size, flags);
 }
+__asm__(".symver lsetxattr, lsetxattr@ATTR_1.0");

The GCC 10 specific changes could look like this:

+__attribute__((__symver__ ("lsetxattr@ATTR_1.0")))
 int libattr_lsetxattr(const char *path, const char *name,
              const void *value, size_t size, int flags)

Which compiles and passes symbol test too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nivedita76 picture nivedita76  Â·  17Comments

jelinekto picture jelinekto  Â·  11Comments

nvertigo picture nvertigo  Â·  10Comments

javashin picture javashin  Â·  5Comments

imesg picture imesg  Â·  4Comments