Bug 1688766 - gcc: Linking against libgcc_s should imply linking with libgcc
Summary: gcc: Linking against libgcc_s should imply linking with libgcc
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: 29
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2019-03-14 11:53 UTC by Florian Weimer
Modified: 2019-05-07 05:41 UTC (History)
14 users (show)

Fixed In Version: gcc-9.0.1-0.11.fc30 gcc-9.1.1-1.fc30
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-05-07 05:41:43 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Florian Weimer 2019-03-14 11:53:55 UTC
When a g++-compiled shared object is linked, __builtin_cpu_init and __builtin_cpu_supports result in undefined symbol errors __cpu_indicator_init, __cpu_model.

Reproducer:

static int
implementation_avx2 (void)
{
  return 1;
}

static int
implementation (void)
{
  return 0;
}

static __typeof__ (implementation) * resolver (void) __asm__ ("resolver");

static __typeof__ (implementation) *
resolver (void)
{
  __builtin_cpu_init ();
  if (__builtin_cpu_supports ("avx2"))
    return implementation_avx2;
  else
    return implementation;
}

int magic (void) __attribute__ ((ifunc ("resolver")));

Compile with:

g++ -O2 -fpic -shared

The assembler output contains a reference to __cpu_model:

resolver:
	subq	$8, %rsp
	call	__cpu_indicator_init
	movl	$_ZL19implementation_avx2v, %eax
	movl	$_ZL14implementationv, %edx
	testb	$4, __cpu_model+13(%rip)
	cmove	%rdx, %rax
	addq	$8, %rsp
	ret

__cpu_model is a compat symbol in libgcc_s.so.1 (with a single @ in the version):

$ eu-readelf -s /usr/lib64/libgcc_s.so.1  | grep cpu_model
  151: 000000000001a190     16 OBJECT  GLOBAL DEFAULT       27 __cpu_model.0

This means that the link editor will not use this symbol and leave it unversioned and undefined:

$ eu-readelf -s a.out | grep cpu_model
    3: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF __cpu_model
   49: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF __cpu_model

I think the expectation is that the definition from libgcc.a is used instead: A local definition has to be used because relocations in IFUNC resolvers are invalid.

But g++ does not link against libgcc.a.

gcc links against libgcc.a and does not have this problem:

$ eu-readelf -s a.out | grep cpu_model
   44: 0000000000004030     16 OBJECT  LOCAL  DEFAULT       22 __cpu_model

Comment 1 Florian Weimer 2019-03-14 11:54:19 UTC
Jakub said this on the upstream bug:

That is a Fedora/RHEL gcc.spec bug rather than upstream bug.
r222178 has added t-slibgcc-libgcc to i?86/x86_64, from the usual Fedora/RHEL targets also arm and powerpc* have that in libgcc/configure.host.
Fedora spec file reshuffles/changes lots of stuff, e.g. because I do not want the lib*.{so,a} files in /usr/lib{,64}/, but in gcc versioned directories, and does this (somewhat extended) libgcc_s.so stuff only for ppc (32-bit only) and arm:
%ifarch ppc
rm -f $FULLPATH/libgcc_s.so
echo '/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-powerpc)
GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so
%endif
%ifarch ppc64 ppc64p7
rm -f $FULLPATH/32/libgcc_s.so
echo '/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-powerpc)
GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/32/libgcc_s.so
%endif
%ifarch %{arm}
rm -f $FULLPATH/libgcc_s.so
echo '/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so
%endif

The extension from upstream is in the OUTPUT_FORMAT, that helps linker to ignore it if it is looking for some other ABI.

So, clearly I need to add this also for ppc64 (64-bit), ppc64le, x86_64 (both 32-bit and 64-bit) and i?86.

Comment 2 Florian Weimer 2019-03-14 11:56:09 UTC
Maybe it's possible to use “ld --print-output-format” to avoid special-casing all these architectures?

Comment 4 Sergio Basto 2019-03-22 00:23:18 UTC
Build of libprojectM with gcc-9.0.1-0.11.fc31, on i686 seems fixed [1] Thanks

[1]
https://koji.fedoraproject.org/koji/buildinfo?buildID=1237679

Comment 5 Jakub Jelinek 2019-04-12 16:28:46 UTC
Fixed for FC30/31.

Comment 6 Sergio Basto 2019-04-23 21:56:18 UTC
Please update gcc in Fedora 30 the current version is 9.0.1-0.10.fc30 [1] and btw this bug still exist in F29 .  


[1]
https://copr-be.cloud.fedoraproject.org/results/sergiomb/builds_for_Stable_Releases/fedora-30-i386/00887045-libprojectM/
gcc                        i686   9.0.1-0.10.fc30

Comment 7 Sergio Basto 2019-05-01 03:31:15 UTC
and this only fixed on gcc-9.0.1-0.11.fc30

Reopen it , to not be lost

Comment 8 Fedora Update System 2019-05-04 13:01:14 UTC
gcc-9.1.1-1.fc30 has been submitted as an update to Fedora 30. https://bodhi.fedoraproject.org/updates/FEDORA-2019-007851f216

Comment 9 Fedora Update System 2019-05-05 00:53:55 UTC
gcc-9.1.1-1.fc30 has been pushed to the Fedora 30 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2019-007851f216

Comment 10 Nicolas Dufresne 2019-05-06 18:02:23 UTC
It looks like it's working for x86_64, but on aarch64 I still get an absolute link:

ls -l /srv/nfs/nicolas/rk3399/usr/lib/gcc/aarch64-redhat-linux/9/libgcc_s.so
lrwxrwxrwx 1 root root 20  3 mai 14:07 /srv/nfs/nicolas/rk3399/usr/lib/gcc/aarch64-redhat-linux/9/libgcc_s.so -> /lib64/libgcc_s.so.1

So as a rootfs for cross-build it breaks.

rpm -qf /usr/lib/gcc/aarch64-redhat-linux/9/libgcc_s.so
gcc-9.1.1-1.fc30.aarch64

Comment 11 Fedora Update System 2019-05-07 05:41:43 UTC
gcc-9.1.1-1.fc30 has been pushed to the Fedora 30 stable repository. If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.