From: Max Filippov Date: Tue, 23 Aug 2022 12:25:55 +0000 (-0700) Subject: xtensa: bfd: fix TLS relocations generated for PIE X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=658ba81aef5e85a08d67eb211a43c6db775a36b3;p=binutils-gdb.git xtensa: bfd: fix TLS relocations generated for PIE When generating TLS dynamic relocations the existing xtensa BFD code treats linking to a PIE exactly as linking to a shared object, resulting in generation of wrong relocations for TLS entries. Fix that and add tests. bfd/ * elf32-xtensa.c (elf_xtensa_check_relocs): Use bfd_link_dll instead of bfd_link_pic. Add elf_xtensa_dynamic_symbol_p test when generating GOT entries. (elf_xtensa_relocate_section): Use bfd_link_dll instead of bfd_link_pic. ld/ * testsuite/ld-xtensa/tlspie.dd: New file. * testsuite/ld-xtensa/tlspie.rd: New file. * testsuite/ld-xtensa/tlspie.sd: New file. * testsuite/ld-xtensa/tlspie.td: New file. * testsuite/ld-xtensa/xtensa-linux.exp (TLS PIE transitions): New test. --- diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index bf72c85ca4a..31e2d7448b0 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1116,7 +1116,7 @@ elf_xtensa_check_relocs (bfd *abfd, switch (r_type) { case R_XTENSA_TLSDESC_FN: - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) { tls_type = GOT_TLS_GD; is_got = true; @@ -1127,7 +1127,7 @@ elf_xtensa_check_relocs (bfd *abfd, break; case R_XTENSA_TLSDESC_ARG: - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) { tls_type = GOT_TLS_GD; is_got = true; @@ -1135,13 +1135,14 @@ elf_xtensa_check_relocs (bfd *abfd, else { tls_type = GOT_TLS_IE; - if (h && elf_xtensa_hash_entry (h) != htab->tlsbase) + if (h && elf_xtensa_hash_entry (h) != htab->tlsbase + && elf_xtensa_dynamic_symbol_p (h, info)) is_got = true; } break; case R_XTENSA_TLS_DTPOFF: - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) tls_type = GOT_TLS_GD; else tls_type = GOT_TLS_IE; @@ -1151,7 +1152,7 @@ elf_xtensa_check_relocs (bfd *abfd, tls_type = GOT_TLS_IE; if (bfd_link_pic (info)) info->flags |= DF_STATIC_TLS; - if (bfd_link_pic (info) || h) + if (bfd_link_dll (info) || elf_xtensa_dynamic_symbol_p (h, info)) is_got = true; break; @@ -2884,7 +2885,7 @@ elf_xtensa_relocate_section (bfd *output_bfd, case R_XTENSA_TLS_TPOFF: /* Switch to LE model for local symbols in an executable. */ - if (! bfd_link_pic (info) && ! dynamic_symbol) + if (! bfd_link_dll (info) && ! dynamic_symbol) { relocation = tpoff (info, relocation); break; @@ -2896,12 +2897,12 @@ elf_xtensa_relocate_section (bfd *output_bfd, { if (r_type == R_XTENSA_TLSDESC_FN) { - if (! bfd_link_pic (info) || (tls_type & GOT_TLS_IE) != 0) + if (! bfd_link_dll (info) || (tls_type & GOT_TLS_IE) != 0) r_type = R_XTENSA_NONE; } else if (r_type == R_XTENSA_TLSDESC_ARG) { - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) { if ((tls_type & GOT_TLS_IE) != 0) r_type = R_XTENSA_TLS_TPOFF; @@ -2975,7 +2976,7 @@ elf_xtensa_relocate_section (bfd *output_bfd, break; case R_XTENSA_TLS_DTPOFF: - if (! bfd_link_pic (info)) + if (! bfd_link_dll (info)) /* Switch from LD model to LE model. */ relocation = tpoff (info, relocation); else diff --git a/ld/testsuite/ld-xtensa/tlspie.dd b/ld/testsuite/ld-xtensa/tlspie.dd new file mode 100644 index 00000000000..d04fa98947f --- /dev/null +++ b/ld/testsuite/ld-xtensa/tlspie.dd @@ -0,0 +1,66 @@ +#source: tlsbin.s +#as: +#ld: -melf32xtensa +#objdump: -dRj.text +#target: xtensa*-*-linux* + +.*: +file format elf32-xtensa-.e + + +Disassembly of section \.text: +#... +[0-9a-f]+ <_start>: + [0-9a-f]+: [0-9a-f]+[ ]+entry a1, 32 +# GD -> IE because variable is not defined in executable + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a10, 1ec <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a10, a10, a8 +# GD -> IE because variable is not defined in executable where +# the variable is referenced through IE too + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a10, 1f4 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a10, a10, a8 +# GD -> LE with global variable defined in executable + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a10, 1fc <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a10, a10, a8 +# GD -> LE with local variable defined in executable + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a10, 204 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a10, a10, a8 +# GD -> LE with hidden variable defined in executable + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a10, 20c <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a10, a10, a8 +# LD -> LE + [0-9a-f]+: [0-9a-f]+[ ]+nop.* + [0-9a-f]+: [0-9a-f]+[ ]+nop.* + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a10 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a12, 218 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a12, a12, a10 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a13, 21c <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a13, a13, a10 +# LD -> LE against hidden variables + [0-9a-f]+: [0-9a-f]+[ ]+l32r a12, 220 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a12, a12, a10 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a13, 224 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a13, a13, a10 +# +# IE against global var + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a2 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a3, 228 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a3, a3, a2 +# IE -> LE against global var defined in exec + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a4 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a5, 22c <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a5, a5, a4 +# IE -> LE against local var + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a6 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a7, 230 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a7, a7, a6 +# IE -> LE against hidden var + [0-9a-f]+: [0-9a-f]+[ ]+rur.threadptr a8 + [0-9a-f]+: [0-9a-f]+[ ]+l32r a9, 234 <.*> .* + [0-9a-f]+: [0-9a-f]+[ ]+add.* a9, a9, a8 +# + [0-9a-f]+: [0-9a-f]+[ ]+retw.* diff --git a/ld/testsuite/ld-xtensa/tlspie.rd b/ld/testsuite/ld-xtensa/tlspie.rd new file mode 100644 index 00000000000..078f9e48e0c --- /dev/null +++ b/ld/testsuite/ld-xtensa/tlspie.rd @@ -0,0 +1,118 @@ +#source: tlsbin.s +#as: +#ld: -melf32xtensa +#readelf: -WSsrl +#target: xtensa*-*-linux* + +There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+: + +Section Headers: + +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al + +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 00 +0 +0 +0 + +\[[ 0-9]+\] .interp +.* + +\[[ 0-9]+\] .hash +.* + +\[[ 0-9]+\] .dynsym +.* + +\[[ 0-9]+\] .dynstr +.* + +\[[ 0-9]+\] .rela.dyn +.* + +\[[ 0-9]+\] .text +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +AX +0 +0 +4 + +\[[ 0-9]+\] .got.loc +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +A +0 +0 +4 + +\[[ 0-9]+\] .tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +WAT +0 +0 +4 + +\[[ 0-9]+\] .dynamic +DYNAMIC +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 08 +WA +4 +0 +4 + +\[[ 0-9]+\] .got +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +WA +0 +0 +4 + +\[[ 0-9]+\] .xtensa.info +NOTE +0+ .* + +\[[ 0-9]+\] .xt.lit +PROGBITS +0+ .* + +\[[ 0-9]+\] .xt.prop +PROGBITS +0+ .* + +\[[ 0-9]+\] .symtab +.* + +\[[ 0-9]+\] .strtab +.* + +\[[ 0-9]+\] .shstrtab +.* +Key to Flags: +#... + +Elf file type is DYN \(Position-Independent Executable file\) +Entry point 0x[0-9a-f]+ +There are [0-9]+ program headers, starting at offset [0-9]+ + +Program Headers: + +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align + +PHDR.* + +INTERP.* +.*Requesting program interpreter.* + +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x1000 + +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ RW +0x1000 + +DYNAMIC +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ RW +0x4 + +TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ R +0x4 + + Section to Segment mapping: + +Segment Sections... + +00 * + +01 +.interp * + +02 +.interp .hash .dynsym .dynstr .rela.dyn .text .got.loc * + +03 +.tdata .dynamic .got * + +04 +.dynamic * + +05 +.tdata * + +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym\. Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ R_XTENSA_TLS_TPOFF +0+ +sG1 \+ 0 +[0-9a-f]+ +[0-9a-f]+ R_XTENSA_TLS_TPOFF +0+ +sG2 \+ 0 +[0-9a-f]+ +[0-9a-f]+ R_XTENSA_TLS_TPOFF +0+ +sG2 \+ 0 + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size +Type +Bind +Vis +Ndx +Name + +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND * + +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2 + +[0-9]+: 0+[0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start + +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1 + +[0-9]+: 0+[0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata + +[0-9]+: 0+[0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end + +Symbol table '\.symtab' contains [0-9]+ entries: + +Num: +Value +Size +Type +Bind +Vis +Ndx +Name + +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND * + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +1 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +2 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +3 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +4 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +5 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +6 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +7 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +8 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +11 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +12 .* + +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +13 .* + +[0-9]+: [0-9a-f]+ +0 +FILE +LOCAL +DEFAULT +ABS .*tlsbin.o + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl1 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl2 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl3 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl4 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl5 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl6 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl7 + +[0-9]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl8 + +[0-9]+: 0+ +0 +FILE +LOCAL +DEFAULT +ABS * + +[0-9]+: 0+ +0 +TLS +LOCAL +DEFAULT +8 _TLS_MODULE_BASE_ + +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +ABS _DYNAMIC + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg8 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg3 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh3 + +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg4 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg5 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh7 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh8 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg1 + +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +6 _start + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh4 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh5 + +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg2 + +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh1 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg6 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg7 + +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata + +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh2 + +[0-9]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh6 diff --git a/ld/testsuite/ld-xtensa/tlspie.sd b/ld/testsuite/ld-xtensa/tlspie.sd new file mode 100644 index 00000000000..484db07e2a0 --- /dev/null +++ b/ld/testsuite/ld-xtensa/tlspie.sd @@ -0,0 +1,14 @@ +#source: tlsbin.s +#as: +#ld: -melf32xtensa +#objdump: -sj.text --stop-address=0x400238 +#target: xtensa*-*-linux* + +.*: +file format elf32-xtensa-.e + +Contents of section .text: + *[0-9a-f]+ 0+ 0+ 0+ 0+ .* + *[0-9a-f]+ 0+ 0*080* 0+ 0*280* .* + *[0-9a-f]+ 0+ 0*480* 0+ 0*080* .* + *[0-9a-f]+ 0*290* 0*2e0* 0*480* 0*4f0* .* + *[0-9a-f]+ 0+ 0*080* 0*280* 0*480* .* diff --git a/ld/testsuite/ld-xtensa/tlspie.td b/ld/testsuite/ld-xtensa/tlspie.td new file mode 100644 index 00000000000..efef45c9410 --- /dev/null +++ b/ld/testsuite/ld-xtensa/tlspie.td @@ -0,0 +1,14 @@ +#source: tlsbin.s +#ld: -melf32xtensa +#objdump: -sj.tdata +#target: xtensa*-*-linux* + +.*: +file format elf32-xtensa-.e + +Contents of section .tdata: + *[0-9a-f]+ 0*110* 0*120* 0*130* 0*140* .* + *[0-9a-f]+ 0*150* 0*160* 0*170* 0*180* .* + *[0-9a-f]+ 0*410* 0*420* 0*430* 0*440* .* + *[0-9a-f]+ 0*450* 0*460* 0*470* 0*480* .* + *[0-9a-f]+ 0*9d0* 0*9e0* 0*9f0* 0*a00* .* + *[0-9a-f]+ 0*a10* 0*a20* 0*a30* 0*a40* .* diff --git a/ld/testsuite/ld-xtensa/xtensa-linux.exp b/ld/testsuite/ld-xtensa/xtensa-linux.exp index 192d9b4b4ac..491a30f43e6 100644 --- a/ld/testsuite/ld-xtensa/xtensa-linux.exp +++ b/ld/testsuite/ld-xtensa/xtensa-linux.exp @@ -51,6 +51,14 @@ set xtensatests { {objdump "-sj.text --stop-address=0x400238" tlsbin.sd} {objdump -sj.tdata tlsbin.td}} "tlsbin"} + {"TLS PIE transitions" + "-pie -melf32xtensa tmpdir/libtlslib.so --hash-style=sysv" "" + "" {tlsbin.s} + {{readelf -WSsrl tlspie.rd} + {objdump "-dRj.text --start-address=0x238" tlspie.dd} + {objdump "-sj.text --stop-address=0x238" tlspie.sd} + {objdump -sj.tdata tlspie.td}} + "tlspie"} } run_ld_link_tests $xtensatests