mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-03 05:12:28 +08:00
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.
This commit is contained in:
@ -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
|
||||
|
66
ld/testsuite/ld-xtensa/tlspie.dd
Normal file
66
ld/testsuite/ld-xtensa/tlspie.dd
Normal file
@ -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.*
|
118
ld/testsuite/ld-xtensa/tlspie.rd
Normal file
118
ld/testsuite/ld-xtensa/tlspie.rd
Normal file
@ -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
|
14
ld/testsuite/ld-xtensa/tlspie.sd
Normal file
14
ld/testsuite/ld-xtensa/tlspie.sd
Normal file
@ -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* .*
|
14
ld/testsuite/ld-xtensa/tlspie.td
Normal file
14
ld/testsuite/ld-xtensa/tlspie.td
Normal file
@ -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* .*
|
@ -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
|
||||
|
Reference in New Issue
Block a user