Summary: | Gold should support i386 TLS code sequences without PLT | ||
---|---|---|---|
Product: | binutils | Reporter: | H.J. Lu <hjl.tools> |
Component: | gold | Assignee: | Cary Coutant <ccoutant> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | ian, ncahill_alt |
Priority: | P2 | ||
Version: | 2.27 | ||
Target Milestone: | 2.27 | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Attachments: |
object files that then failed the test
Try this result of changes |
Description
H.J. Lu
2016-06-28 15:02:51 UTC
A patch is posted at https://sourceware.org/ml/binutils/2016-06/msg00500.html The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b287eca391bbb10e709fb8ba9a56be166ab2ff1d commit b287eca391bbb10e709fb8ba9a56be166ab2ff1d Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Jun 29 08:38:43 2016 -0700 gold: Support 386 TLS code sequences without PLT There are extensions to 386 psABI: https://groups.google.com/forum/#!topic/ia32-abi/awsRSvJOJfs to call tls_get_addr via GOT: call *___tls_get_addr@GOT(%reg) where EBX register isn't required as GOT base. Since direct call is 4-byte long and indirect call, is 5-byte long, the extra one byte must be handled properly. For general dynamic model, 7-byte lea instruction before call instruction is replaced by 6-byte one to make room for indirect call. For local dynamic model, we simply use 5-byte indirect call. TLS linker optimization is updated to recognize new instruction patterns. For local dynamic model to local exec model transition, we generate a 6-byte lea instruction as nop, instead of a 1-byte nop plus a 4-byte lea instruction. PR gold/20308 * i386.cc (Target_i386::Relocate::relocate): Allow R_386_GOT32X relocation against ___tls_get_addr. (Target_i386::Relocate::tls_gd_to_ie): Support indirect call to __tls_get_addr. (Target_i386::Relocate::tls_gd_to_le): Likewise. (Target_i386::Relocate::tls_ld_to_le): Likewise. * testsuite/Makefile.am (check_PROGRAMS): Add pr20308a_test, pr20308b_test, pr20308c_test, pr20308d_test, pr20308e_test. (pr20308a_test_SOURCES): New. (pr20308a_test_DEPENDENCIES): Likewise. (pr20308a_test_CFLAGS): Likewise. (pr20308a_test_LDFLAGS): Likewise. (pr20308a_test_LDADD): Likewise. (pr20308b_test_SOURCES): Likewise. (pr20308b_test_DEPENDENCIES): Likewise. (pr20308b_test_CFLAGS): Likewise. (pr20308b_test_LDFLAGS): Likewise. (pr20308b_test_LDADD): Likewise. (pr20308c_test_SOURCES): Likewise. (pr20308c_test_DEPENDENCIES): Likewise. (pr20308c_test_CFLAGS): Likewise. (pr20308c_test_LDFLAGS): Likewise. (pr20308c_test_LDADD): Likewise. (pr20308d_test_SOURCES): Likewise. (pr20308d_test_DEPENDENCIES): Likewise. (pr20308d_test_CFLAGS): Likewise. (pr20308d_test_LDFLAGS): Likewise. (pr20308d_test_LDADD): Likewise. (pr20308e_test_SOURCES): Likewise. (pr20308e_test_DEPENDENCIES): Likewise. (pr20308e_test_CFLAGS): Likewise. (pr20308e_test_LDFLAGS): Likewise. (pr20308e_test_LDADD): Likewise. (pr20308a.so): Likewise. (pr20308b.so): Likewise. (pr20308_gd.o): Likewise. (pr20308_ld.o): Likewise. (MOSTLYCLEANFILES): Add pr20308a.so pr20308b.so. * testsuite/Makefile.in: Regenerated. * testsuite/pr20308_def.c: New file. * testsuite/pr20308_gd.S: Likewise. * testsuite/pr20308_ld.S: Likewise. * testsuite/pr20308_main.c: Likewise. Fixed for 2.27. Created attachment 9443 [details]
object files that then failed the test
Regarding this update, I'm getting a failure on "make testsuite/pr20308a_test": pr20308_gd.o:function test_gd: error: missing expected TLS relocation gcctestdir/ld: error: missing expected TLS relocation pr20308_ld.o:function test_ld: error: missing expected TLS relocation pr20308_ld.o:function test_ld: error: missing expected TLS relocation gcctestdir/ld: error: missing expected TLS relocation I see this message twice in i386.cc: ------ line 634 ---------- ~Relocate() { if (this->skip_call_tls_get_addr_) { // FIXME: This needs to specify the location somehow. gold_error(_("missing expected TLS relocation")); } } ------ line 2787 ----------- const elfcpp::Rel<32, false> rel(preloc); unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info()); if (this->skip_call_tls_get_addr_) { if ((r_type != elfcpp::R_386_PLT32 && r_type != elfcpp::R_386_GOT32X && r_type != elfcpp::R_386_PC32) || gsym == NULL || strcmp(gsym->name(), "___tls_get_addr") != 0) gold_error_at_location(relinfo, relnum, rel.get_r_offset(), _("missing expected TLS relocation")); else { this->skip_call_tls_get_addr_ = false; return false; } } --------------- One thing I notice is this: 00000066 R_386_GOT32 ___tls_get_addr Hopefully that's the problem. Also I wonder if it would be helpful to make those two error messages slightly different so one could pick out which is which. Thank you. Neil. Created attachment 9444 [details]
Try this
Created attachment 9445 [details] result of changes It still fails: pr20308_gd.o:function test_gd: error: missing expected TLS relocation pr20308_ld.o:function test_ld: error: missing expected TLS relocation (In reply to ncahill_alt from comment #7) > Created attachment 9445 [details] > result of changes > > It still fails: > > pr20308_gd.o:function test_gd: error: missing expected TLS relocation > pr20308_ld.o:function test_ld: error: missing expected TLS relocation Please show the output of "readelf -r pr20308_gd.o" Relocation section '.rel.text' at offset 0x2ec contains 12 entries: Offset Info Type Sym.Value Sym. Name 00000002 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx 00000008 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ 00000012 00000d12 R_386_TLS_GD 00000000 gd 00000017 00000e04 R_386_PLT32 00000000 ___tls_get_addr 00000022 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx 00000028 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ 00000031 00000d12 R_386_TLS_GD 00000000 gd 00000036 00000e04 R_386_PLT32 00000000 ___tls_get_addr 00000051 00001102 R_386_PC32 00000000 __x86.get_pc_thunk.cx 00000057 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ 00000060 00000d12 R_386_TLS_GD 00000000 gd 00000066 00000e03 R_386_GOT32 00000000 ___tls_get_addr CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops CXXFLAGS = -g -O2 LDFLAGS = -Wl,-O1 GCC is 5.2.0, i686-pc-linux-gnu-gcc (In reply to ncahill_alt from comment #9) > Relocation section '.rel.text' at offset 0x2ec contains 12 entries: > Offset Info Type Sym.Value Sym. Name > 00000002 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx > 00000008 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > 00000012 00000d12 R_386_TLS_GD 00000000 gd > 00000017 00000e04 R_386_PLT32 00000000 ___tls_get_addr > 00000022 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx > 00000028 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > 00000031 00000d12 R_386_TLS_GD 00000000 gd > 00000036 00000e04 R_386_PLT32 00000000 ___tls_get_addr > 00000051 00001102 R_386_PC32 00000000 __x86.get_pc_thunk.cx > 00000057 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > 00000060 00000d12 R_386_TLS_GD 00000000 gd > 00000066 00000e03 R_386_GOT32 00000000 ___tls_get_addr > > CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe > -funroll-loops -funswitch-loops > CXXFLAGS = -g -O2 > LDFLAGS = -Wl,-O1 > > GCC is 5.2.0, i686-pc-linux-gnu-gcc Please show the command line used to compile pr20308_gd.o. BTW, did you run "make clean" first? > Please show the command line used to compile pr20308_gd.o. > > BTW, did you run "make clean" first? Yeah, the build rules should also have a dependency on gcctestdir/as. Forgot that when fixing the x86_64 test, sorry. -cary (In reply to H.J. Lu from comment #10) > (In reply to ncahill_alt from comment #9) > > Relocation section '.rel.text' at offset 0x2ec contains 12 entries: > > Offset Info Type Sym.Value Sym. Name > > 00000002 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx > > 00000008 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > > 00000012 00000d12 R_386_TLS_GD 00000000 gd > > 00000017 00000e04 R_386_PLT32 00000000 ___tls_get_addr > > 00000022 00000b02 R_386_PC32 00000000 __x86.get_pc_thunk.bx > > 00000028 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > > 00000031 00000d12 R_386_TLS_GD 00000000 gd > > 00000036 00000e04 R_386_PLT32 00000000 ___tls_get_addr > > 00000051 00001102 R_386_PC32 00000000 __x86.get_pc_thunk.cx > > 00000057 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ > > 00000060 00000d12 R_386_TLS_GD 00000000 gd > > 00000066 00000e03 R_386_GOT32 00000000 ___tls_get_addr > > > > CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe > > -funroll-loops -funswitch-loops > > CXXFLAGS = -g -O2 > > LDFLAGS = -Wl,-O1 > > > > GCC is 5.2.0, i686-pc-linux-gnu-gcc > > Please show the command line used to compile pr20308_gd.o. i686-pc-linux-gnu-gcc -Bgcctestdir/ -fPIE -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops -Bgcctestdir/ -Wl,-R,. -Wl,-O1 -o pr20308a_test pr20308a_test-pr20308_main.o pr20308a_test-pr20308_def.o pr20308_gd.o pr20308_ld.o -ldl > > BTW, did you run "make clean" first? Yes, I built binutils from scratch each time. This all looks odd but basically... 1. CFLAGS is very well tested, I won't go into it but it gives helpful profiling results, for example I was able to report performance issues with GCC. 2. CXXFLAGS should have been the same, I had a script that set everything but I had to recreate it and forgot to set CXXFLAGS. Oh sorry, here it is: `echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I../../../binutils-2.27/gold/testsuite -I.. -I../../../binutils-2.27/gold/testsuite -I../../../binutils-2.27/gold/testsuite/.. -I../../../binutils-2.27/gold/testsuite/../../include -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\"" -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o ../../../binutils-2.27/gold/testsuite/pr20308_gd.S which translates to i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I../../../binutils-2.27/gold/testsuite -I.. -I../../../binutils-2.27/gold/testsuite -I../../../binutils-2.27/gold/testsuite/.. -I../../../binutils-2.27/gold/testsuite/../../include -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o ../../../binutils-2.27/gold/testsuite/pr20308_gd.S (In reply to ncahill_alt from comment #13) > Oh sorry, here it is: > > `echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. > -I../../../binutils-2.27/gold/testsuite -I.. > -I../../../binutils-2.27/gold/testsuite > -I../../../binutils-2.27/gold/testsuite/.. > -I../../../binutils-2.27/gold/testsuite/../../include > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. > -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\"" > -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow > -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 > -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 > -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e > 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S > > which translates to > > i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. > -I../../../binutils-2.27/gold/testsuite -I.. > -I../../../binutils-2.27/gold/testsuite > -I../../../binutils-2.27/gold/testsuite/.. > -I../../../binutils-2.27/gold/testsuite/../../include > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. > -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W > -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 > -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 > -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops > -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S This should generate R_386_GOT32X, not R_386_GOT32 relocation. (In reply to H.J. Lu from comment #14) > (In reply to ncahill_alt from comment #13) > > Oh sorry, here it is: > > > > `echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. > > -I../../../binutils-2.27/gold/testsuite -I.. > > -I../../../binutils-2.27/gold/testsuite > > -I../../../binutils-2.27/gold/testsuite/.. > > -I../../../binutils-2.27/gold/testsuite/../../include > > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. > > -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\"" > > -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow > > -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 > > -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 > > -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e > > 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o > > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S > > > > which translates to > > > > i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. > > -I../../../binutils-2.27/gold/testsuite -I.. > > -I../../../binutils-2.27/gold/testsuite > > -I../../../binutils-2.27/gold/testsuite/.. > > -I../../../binutils-2.27/gold/testsuite/../../include > > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. > > -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W > > -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 > > -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 > > -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops > > -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o > > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S > > This should generate R_386_GOT32X, not R_386_GOT32 relocation. Could this be a glibc problem? I see this patch dated December 2015: > diff --git a/backends/ChangeLog b/backends/ChangeLog > index 4b604fd..cc0dd6f 100644 > --- a/backends/ChangeLog > +++ b/backends/ChangeLog > @@ -1,3 +1,8 @@ > +2015-12-28 Mark Wielaard <mjw(a)redhat.com>; > + > + * i386_reloc.def: Add GOT32X. > + * x86_64_reloc.def: Add GOTPCRELX and REX_GOTPCRELX. > + 2015-12-08 Jose E. Marchesi <jose.marchesi(a)oracle.com>; I'm using glibc-2.22 from 2015-08-14. In fact, I can confirm that elf.h defines R_386_GOT32 but not R_386_GOT32X: > #define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ > #define R_68K_GOT32O 10 /* 32 bit GOT offset */ > #define R_386_GOT32 3 /* 32 bit GOT entry */ > #define R_ARM_GOT32 26 /* 32 bit GOT entry */ > #define R_SH_GOT32 160 > #define R_390_GOT32 7 /* 32 bit GOT offset. */ > #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ > #define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ I think this must be it. I've tried this again: 1. I build binutils-2.27 in an empty folder. 2. I run "make check" in "binutils-2.27/gold/" 3. It fails with "missing expected TLS relocation". "readelf -r pr20308_gd.o" shows R_386_GOT32. 4. I run "make clean" in "binutils-2.27/gold/testsuite/". 5. I run "make check" in "binutils-2.27/gold/". 6. All tests pass and readelf shows "unrecognized: 2b". This is with the changes above in the "try this" attachment. I also tried without them, the error is not resolved. (In reply to ncahill_alt from comment #16) > I've tried this again: > > 1. I build binutils-2.27 in an empty folder. > 2. I run "make check" in "binutils-2.27/gold/" > 3. It fails with "missing expected TLS relocation". > "readelf -r pr20308_gd.o" shows R_386_GOT32. > > 4. I run "make clean" in "binutils-2.27/gold/testsuite/". > 5. I run "make check" in "binutils-2.27/gold/". > 6. All tests pass and readelf shows "unrecognized: 2b". > > This is with the changes above in the "try this" attachment. I also tried > without them, the error is not resolved. You need to find out why #3 fails and #6 passes. diff -ur a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am --- a/gold/testsuite/Makefile.am 2016-08-18 17:00:09.969119174 +0000 +++ b/gold/testsuite/Makefile.am 2016-08-18 17:09:28.772423751 +0000 @@ -1297,10 +1297,10 @@ pr20308b.so: pr20308_def.o gcctestdir/ld $(LINK) -Bgcctestdir/ -shared pr20308_def.o -pr20308_gd.o: pr20308_gd.S +pr20308_gd.o: pr20308_gd.S gcctestdir/as $(COMPILE) -Bgcctestdir/ -c -o $@ $< -pr20308_ld.o: pr20308_ld.S +pr20308_ld.o: pr20308_ld.S gcctestdir/as $(COMPILE) -Bgcctestdir/ -c -o $@ $< endif DEFAULT_TARGET_I386 |