Closed Quuxplusone closed 4 years ago
This bug currently causes a Swift build failure on Linux:
Swift.o: relocation R_X86_64_PC32 against protected symbol
`_Tvs19_emptyStringStorageVs6UInt32' can not be used when making a shared object
ld.bfd: final link failed: Bad value
% ./swift-demangle _Tvs19_emptyStringStorageVs6UInt32
_Tvs19_emptyStringStorageVs6UInt32 ---> Swift._emptyStringStorage : Swift.UInt32
I can't reproduce the part about ld.bfd complaining. I have:
GNU ld version 2.25-15.fc23
I also get an abort when compiling with gcc (gcc (GCC) 5.3.1 20151207 (Red Hat
5.3.1-2)). Is the same bug present in gcc?
(In reply to comment #2)
> I can't reproduce the part about ld.bfd complaining. I have:
> GNU ld version 2.25-15.fc23
>
>
> I also get an abort when compiling with gcc (gcc (GCC) 5.3.1 20151207 (Red
> Hat 5.3.1-2)). Is the same bug present in gcc?
Please get binutils 2.26.
Attached run.sh
(849 bytes, application/x-shellscript): test
(In reply to comment #3)
> (In reply to comment #2)
> > I can't reproduce the part about ld.bfd complaining. I have:
> > GNU ld version 2.25-15.fc23
> >
> >
> > I also get an abort when compiling with gcc (gcc (GCC) 5.3.1 20151207 (Red
> > Hat 5.3.1-2)). Is the same bug present in gcc?
>
> Please get binutils 2.26.
I can't reproduce even with trunk.
I have attached the exact script I am using. I get the same results with gcc
and clang: No warnings and ./t aborts.
The ld version is:
GNU ld (GNU Binutils) 2.26.51.20160212
(In reply to comment #5)
> (In reply to comment #3)
> > (In reply to comment #2)
> > > I can't reproduce the part about ld.bfd complaining. I have:
> > > GNU ld version 2.25-15.fc23
> > >
> > >
> > > I also get an abort when compiling with gcc (gcc (GCC) 5.3.1 20151207 (Red
> > > Hat 5.3.1-2)). Is the same bug present in gcc?
> >
> > Please get binutils 2.26.
>
> I can't reproduce even with trunk.
>
> I have attached the exact script I am using. I get the same results with gcc
> and clang: No warnings and ./t aborts.
>
> The ld version is:
> GNU ld (GNU Binutils) 2.26.51.20160212
GCC 5 above is fixed. Please upload your bar.o compiled with -fPIC -O3 using
clang and GCC 5.
To get the correct run-time behavior, glibc with fix for
https://sourceware.org/bugzilla/show_bug.cgi?id=17711
is required.
> $CC -shared bar.o -o bar.so -fuse-ld=bfd
You have to make sure that the correct linker is used here.
Put it first in your $PATH, for example.
I have the same problem on Arch Linux:
GNU ld (GNU Binutils) 2.26.0.20160302
gcc version 5.3.0 (GCC)
Target: x86_64-unknown-linux-gnu
/usr/bin/ld: stdlib/public/core/linux/x86_64/Swift.o: relocation R_X86_64_PC32
against protected symbol `_TMPSa' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
Forgot to say, I'm using Clang ToT-ish at 266363.
I try to reproduce this issue on Fedora 29. The situation is changed.
I tested a clean Fedora 29 docker environment. All packages come from official
repo.
# rpm -q clang binutils gcc
clang-7.0.0-2.fc29.x86_64
binutils-2.31.1-13.fc29.x86_64
gcc-8.2.1-4.fc29.x86_64
Linking with bfd is done but running is aborted:
# make y
clang -O3 -c -o x.o x.c
clang -O3 -fpic -c -o bar.o bar.c
clang -fuse-ld=bfd -shared -o libfoo.so bar.o
clang -fuse-ld=bfd -o y x.o libfoo.so -Wl,-R,.
[root@d44816330e72 clang-protected-link]# ./y
Aborted (core dumped)
Linking with gold is failed:
# make y
clang -O3 -c -o x.o x.c
clang -O3 -fpic -c -o bar.o bar.c
clang -fuse-ld=gold -shared -o libfoo.so bar.o
clang -fuse-ld=gold -o y x.o libfoo.so -Wl,-R,.
/usr/bin/ld.gold: error: x.o: cannot make copy relocation for protected symbol
'a', defined in libfoo.so
clang-7: error: linker command failed with exit code 1 (use -v to see
invocation)
make: *** [Makefile:10: y] Error 1
(In reply to Robin Lee from comment #11)
> I try to reproduce this issue on Fedora 29. The situation is changed.
> I tested a clean Fedora 29 docker environment. All packages come from
> official repo.
>
> # rpm -q clang binutils gcc
> clang-7.0.0-2.fc29.x86_64
> binutils-2.31.1-13.fc29.x86_64
> gcc-8.2.1-4.fc29.x86_64
>
> Linking with bfd is done but running is aborted:
>
> # make y
> clang -O3 -c -o x.o x.c
> clang -O3 -fpic -c -o bar.o bar.c
# readelf -r bar.o
Relocation section '.rela.text' at offset 0x120 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000002 000300000002 R_X86_64_PC32 0000000000000004 a - 8
Relocation section '.rela.eh_frame' at offset 0x138 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
# objdump -d bar.o
bar.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <bar>:
0: c7 05 00 00 00 00 1e movl $0x1e,0x0(%rip) # a <bar+0xa>
7: 00 00 00
a: c3 retq
Same on Debian using clang-7 packages from apt.llvm.org
(In reply to Robin Lee from comment #12)
> (In reply to Robin Lee from comment #11)
> > I try to reproduce this issue on Fedora 29. The situation is changed.
> > I tested a clean Fedora 29 docker environment. All packages come from
> > official repo.
> >
> > # rpm -q clang binutils gcc
> > clang-7.0.0-2.fc29.x86_64
> > binutils-2.31.1-13.fc29.x86_64
> > gcc-8.2.1-4.fc29.x86_64
> >
> > Linking with bfd is done but running is aborted:
> >
> > # make y
> > clang -O3 -c -o x.o x.c
> > clang -O3 -fpic -c -o bar.o bar.c
>
> # readelf -r bar.o
>
> Relocation section '.rela.text' at offset 0x120 contains 1 entry:
> Offset Info Type Sym. Value Sym. Name +
> Addend
> 000000000002 000300000002 R_X86_64_PC32 0000000000000004 a - 8
>
> Relocation section '.rela.eh_frame' at offset 0x138 contains 1 entry:
> Offset Info Type Sym. Value Sym. Name +
> Addend
> 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
>
> # objdump -d bar.o
>
> bar.o: file format elf64-x86-64
>
>
> Disassembly of section .text:
>
> 0000000000000000 <bar>:
> 0: c7 05 00 00 00 00 1e movl $0x1e,0x0(%rip) # a <bar+0xa>
> 7: 00 00 00
> a: c3 retq
GCC 8 generates:
[hjl@gnu-cfl-1 pr65248]$ objdump -dwr bar.o
bar.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <bar>:
0: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 7 <bar+0x7> 3: R_X86_64_REX_GOTPCRELX a-0x4
7: c7 00 1e 00 00 00 movl $0x1e,(%rax)
d: c3 retq
[hjl@gnu-cfl-1 pr65248]$
What I found is the regression of ld.bfd. The issue with clang is still the same as previous.
(In reply to Robin Lee from comment #15)
> What I found is the regression of ld.bfd. The issue with clang is still the
> same as previous.
GCC, glibc and ld.bfd have been updated to cope with protected symbols.
(In reply to H.J. Lu from comment #16)
> (In reply to Robin Lee from comment #15)
> GCC, glibc and ld.bfd have been updated to cope with protected symbols.
I know that. But ld.bfd works as expected on Fedora 28 but breaks on Fedora 29.
Hello, I still get the same issue on Ubuntu i386 architecture.
The file seems to be miscompiled on clang, while gcc builds it just fine.
What is interesting is that bfd fails to link the libary, and ld is good.
So maybe this is a double bug, in this case please help me reporting it to
glib/binutils folks accordingly :)
$ echo '
extern int a;
extern void bar (void);
int main() {
bar ();
if (a != 30)
__builtin_abort();
return 0;
}' > x.c
echo 'int a;
__attribute__((visibility("protected"))) int a;
void bar () {
a = 30;
}
' > bar.c
$ VERSION=7
$ clang-$VERSION -O3 -c -o x.o x.c
$ clang-$VERSION -O3 -fpic -c -o bar.o bar.c
$ clang-$VERSION -fuse-ld=bfd -shared -o libfoo.so bar.o
/usr/bin/ld.bfd: bar.o: relocation R_386_GOTOFF against protected data `a' can
not be used when making a shared object
/usr/bin/ld.bfd: final link failed: bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ objdump -d bar.o
bar.o: file format elf32-i386
Disassembly of section .text:
00000000 <bar>:
0: e8 00 00 00 00 call 5 <bar+0x5>
5: 58 pop %eax
6: 81 c0 03 00 00 00 add $0x3,%eax
c: c7 80 00 00 00 00 1e movl $0x1e,0x0(%eax)
13: 00 00 00
16: c3 ret
$ readelf -r bar.o
Relocation section '.rel.text' at offset 0xe0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000008 0000020a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
0000000e 00000309 R_386_GOTOFF 00000004 a
$ clang-$VERSION -fuse-ld=gold -shared -o libfoo.so bar.o
(this is ok)
$ gcc -v -shared -o libfoo.so bar.o
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/8/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.2.0-13ubuntu1'
--with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-
languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-
major-version-only --program-suffix=-8 --program-prefix=i686-linux-gnu- --
enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-
gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-
clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-
libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-
libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-
system-zlib --enable-objc-gc=auto --enable-targets=all --enable-multiarch --
disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-
multilib --with-tune=generic --enable-checking=release --build=i686-linux-gnu --
host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 8.2.0 (Ubuntu 8.2.0-13ubuntu1)
COMPILER_PATH=/usr/lib/gcc/i686-linux-gnu/8/:/usr/lib/gcc/i686-linux-gnu/8/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/8/:/usr/lib/gcc/i686-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/8/:/usr/lib/gcc/i686-linux-gnu/8/../../../i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/8/../../../../lib/:/lib/i386-linux-gnu/:/lib/../lib/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/8/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-shared' '-o' 'libfoo.so' '-mtune=generic' '-
march=i686'
/usr/lib/gcc/i686-linux-gnu/8/collect2 -plugin /usr/lib/gcc/i686-linux-gnu/8/liblto_plugin.so -plugin-opt=/usr/lib/gcc/i686-linux-gnu/8/lto-wrapper -plugin-opt=-fresolution=/tmp/ccMVGMSP.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu --as-needed -shared -z relro -o libfoo.so /usr/lib/gcc/i686-linux-gnu/8/../../../i386-linux-gnu/crti.o /usr/lib/gcc/i686-linux-gnu/8/crtbeginS.o -L/usr/lib/gcc/i686-linux-gnu/8 -L/usr/lib/gcc/i686-linux-gnu/8/../../../i386-linux-gnu -L/usr/lib/gcc/i686-linux-gnu/8/../../../../lib -L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/i686-linux-gnu/8/../../.. bar.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/i686-linux-gnu/8/crtendS.o /usr/lib/gcc/i686-linux-gnu/8/../../../i386-linux-gnu/crtn.o
/usr/bin/ld: bar.o: relocation R_386_GOTOFF against protected data `a' can not
be used when making a shared object
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
$ gcc -O3 -fpic -c -o bar.o bar.c
$ readelf -r bar.o
Relocation section '.rel.text' at offset 0x1dc contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00000001 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.ax
00000006 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
0000000c 00000d2b R_386_GOT32X 00000004 a
Relocation section '.rel.eh_frame' at offset 0x1f4 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000202 R_386_PC32 00000000 .text
00000034 00000502 R_386_PC32 00000000 .text.__x86.get_pc_thu
$ objdump -d bar.o
bar.o: file format elf32-i386
Disassembly of section .text:
00000000 <bar>:
0: e8 fc ff ff ff call 1 <bar+0x1>
5: 05 01 00 00 00 add $0x1,%eax
a: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
10: c7 00 1e 00 00 00 movl $0x1e,(%eax)
16: c3 ret
Disassembly of section .text.__x86.get_pc_thunk.ax:
00000000 <__x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret
$ clang-$VERSION -fuse-ld=bfd -shared -o libfoo.so bar.o
(with gcc compiling bar.c the bfd linker succeedes)
$ clang-$VERSION -fuse-ld=gold -shared -o libfoo.so bar.o
(with gcc compiling bar.c the gold linker succeedes)
(In reply to Gianfranco from comment #18)
> Hello, I still get the same issue on Ubuntu i386 architecture.
> The file seems to be miscompiled on clang, while gcc builds it just fine.
Which version of your ld's?
ld --version
ld.bfd --version
ld.gold --version
And which version of Ubuntu are you using?
(In reply to Robin Lee from comment #19)
> (In reply to Gianfranco from comment #18)
> > Hello, I still get the same issue on Ubuntu i386 architecture.
> > The file seems to be miscompiled on clang, while gcc builds it just fine.
> Which version of your ld's?
> ld --version
> ld.bfd --version
> ld.gold --version
>
> And which version of Ubuntu are you using?
The linker doesn't matter; LLVM produced wrong code. Glibc defines
DL_EXTERN_PROTECTED_DATA on all of aarch64, arm, i386, (nios2) and x86_64,
which means that, for all of those, LLVM must assume that protected symbols can
be subjected to copy relocations and therefore may be external. Specifically
for i386, this means we can't use @GOTOFF and have to do a full indirection via
the GOT.
# ld --version
GNU ld (GNU Binutils for Ubuntu) 2.31.1
Copyright (C) 2018 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
# ld.bfd --version
GNU ld (GNU Binutils for Ubuntu) 2.31.1
Copyright (C) 2018 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
# ld.gold --version
GNU gold (GNU Binutils for Ubuntu 2.31.1) 1.16
Copyright (C) 2018 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
The original issue is "Copy relocation against protected symbol doesn't work".
I agree with Rich Felker (https://gcc.gnu.org/ml/gcc/2016-04/msg00168.html) and
Cary Coutant (https://sourceware.org/ml/binutils/2016-03/msg00407.html
https://gcc.gnu.org/ml/gcc/2016-04/msg00158.html
https://gcc.gnu.org/ml/gcc/2016-04/msg00169.html) that we should
keep using direct access against protected symbols and disallow copy
relocations against protected symbols.
I appreciate that Cary Coutant and Rafael Ávila de Espíndola added diagnostics
to gold and lld, respectively:
gold (https://sourceware.org/bugzilla/show_bug.cgi?id=19823)
lld (https://bugs.llvm.org/show_bug.cgi?id=31476)
And I hope the following resolutions could be reworked:
GCC 5 x86-64 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248)
i386 was flagged as a reproduce
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55012)
__attribute__((visibility("protected"))) int a;
int foo() { return a; } // GCC>=5 uses R_X86_64_GOTPCREL/R_X86_64_REX_GOTPCRELX
instead of R_X86_64_PC32
binutils 2.26: R_X86_64_PC32 can no longer be used against a protected symbol
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=ca3fe95e469b9daec153caa2c90665f5daaec2b5
GCC x86-64 issue can be nicely fixed with https://gcc.gnu.org/ml/gcc/2019-05/msg00215.html
run.sh
(849 bytes, application/x-shellscript)