mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 01:50:24 +08:00
Support TLS x32 GD->IE, GD->LE and LD->LE transitions.
bfd/ 2011-03-12 H.J. Lu <hongjiu.lu@intel.com> * elf64-x86-64.c (elf_x86_64_check_tls_transition): Supprt TLS x32 GD->IE and GD->LE transitions. (elf_x86_64_relocate_section): Supprt TLS x32 GD->IE, GD->LE and LD->LE transitions. ld/testsuite/ 2011-03-12 H.J. Lu <hongjiu.lu@intel.com> * ld-x86-64/tlsgd4.dd: New. * ld-x86-64/tlsgd4.s: Likewise. * ld-x86-64/tlsgd5.dd: Likewise. * ld-x86-64/tlsgd5a.s: Likewise. * ld-x86-64/tlsgd5b.s: Likewise. * ld-x86-64/tlsgd6.dd: Likewise. * ld-x86-64/tlsgd6a.s: Likewise. * ld-x86-64/tlsgd6b.s: Likewise. * ld-x86-64/tlsld2.dd: Likewise. * ld-x86-64/tlsld2.s: Likewise. * ld-x86-64/x86-64.exp (x86_64tests): Add tlsgd4, libtlsgd5.so, tlsgd5, libtlsgd6.so, tlsgd6 and tlsld2.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2011-03-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* elf64-x86-64.c (elf_x86_64_check_tls_transition): Supprt TLS
|
||||||
|
x32 GD->IE and GD->LE transitions.
|
||||||
|
(elf_x86_64_relocate_section): Supprt TLS x32 GD->IE, GD->LE
|
||||||
|
and LD->LE transitions.
|
||||||
|
|
||||||
2011-03-10 Alan Modra <amodra@gmail.com>
|
2011-03-10 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf64-ppc.c (ppc64_elf_relocate_section): Provide section/offset
|
* elf64-ppc.c (ppc64_elf_relocate_section): Provide section/offset
|
||||||
|
@ -865,18 +865,34 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|||||||
|
|
||||||
if (r_type == R_X86_64_TLSGD)
|
if (r_type == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
/* Check transition from GD access model. Only
|
/* Check transition from GD access model. For 64bit, only
|
||||||
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
.word 0x6666; rex64; call __tls_get_addr
|
.word 0x6666; rex64; call __tls_get_addr
|
||||||
|
can transit to different access model. For 32bit, only
|
||||||
|
leaq foo@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666; rex64; call __tls_get_addr
|
||||||
can transit to different access model. */
|
can transit to different access model. */
|
||||||
|
|
||||||
static x86_64_opcode32 leaq = { { 0x66, 0x48, 0x8d, 0x3d } },
|
static x86_64_opcode32 call = { { 0x66, 0x66, 0x48, 0xe8 } };
|
||||||
call = { { 0x66, 0x66, 0x48, 0xe8 } };
|
if ((offset + 12) > sec->size
|
||||||
if (offset < 4
|
|
||||||
|| (offset + 12) > sec->size
|
|
||||||
|| bfd_get_32 (abfd, contents + offset - 4) != leaq.i
|
|
||||||
|| bfd_get_32 (abfd, contents + offset + 4) != call.i)
|
|| bfd_get_32 (abfd, contents + offset + 4) != call.i)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (ABI_64_P (abfd))
|
||||||
|
{
|
||||||
|
static x86_64_opcode32 leaq = { { 0x66, 0x48, 0x8d, 0x3d } };
|
||||||
|
if (offset < 4
|
||||||
|
|| bfd_get_32 (abfd, contents + offset - 4) != leaq.i)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static x86_64_opcode16 lea = { { 0x8d, 0x3d } };
|
||||||
|
if (offset < 3
|
||||||
|
|| bfd_get_8 (abfd, contents + offset - 3) != 0x48
|
||||||
|
|| bfd_get_16 (abfd, contents + offset - 2) != lea.i)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3434,15 +3450,26 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
/* GD->LE transition.
|
/* GD->LE transition. For 64bit, change
|
||||||
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
.word 0x6666; rex64; call __tls_get_addr
|
.word 0x6666; rex64; call __tls_get_addr
|
||||||
Change it into:
|
into:
|
||||||
movq %fs:0, %rax
|
movq %fs:0, %rax
|
||||||
|
leaq foo@tpoff(%rax), %rax
|
||||||
|
For 32bit, change
|
||||||
|
leaq foo@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666; rex64; call __tls_get_addr
|
||||||
|
into:
|
||||||
|
movl %fs:0, %eax
|
||||||
leaq foo@tpoff(%rax), %rax */
|
leaq foo@tpoff(%rax), %rax */
|
||||||
memcpy (contents + roff - 4,
|
if (ABI_64_P (output_bfd))
|
||||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
memcpy (contents + roff - 4,
|
||||||
16);
|
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
||||||
|
16);
|
||||||
|
else
|
||||||
|
memcpy (contents + roff - 3,
|
||||||
|
"\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
||||||
|
15);
|
||||||
bfd_put_32 (output_bfd,
|
bfd_put_32 (output_bfd,
|
||||||
elf_x86_64_tpoff (info, relocation),
|
elf_x86_64_tpoff (info, relocation),
|
||||||
contents + roff + 8);
|
contents + roff + 8);
|
||||||
@ -3670,15 +3697,26 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
/* GD->IE transition.
|
/* GD->IE transition. For 64bit, change
|
||||||
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
.word 0x6666; rex64; call __tls_get_addr@plt
|
.word 0x6666; rex64; call __tls_get_addr@plt
|
||||||
Change it into:
|
into:
|
||||||
movq %fs:0, %rax
|
movq %fs:0, %rax
|
||||||
|
addq foo@gottpoff(%rip), %rax
|
||||||
|
For 32bit, change
|
||||||
|
leaq foo@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666; rex64; call __tls_get_addr@plt
|
||||||
|
into:
|
||||||
|
movl %fs:0, %eax
|
||||||
addq foo@gottpoff(%rip), %rax */
|
addq foo@gottpoff(%rip), %rax */
|
||||||
memcpy (contents + roff - 4,
|
if (ABI_64_P (output_bfd))
|
||||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
memcpy (contents + roff - 4,
|
||||||
16);
|
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
||||||
|
16);
|
||||||
|
else
|
||||||
|
memcpy (contents + roff - 3,
|
||||||
|
"\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
||||||
|
15);
|
||||||
|
|
||||||
relocation = (htab->elf.sgot->output_section->vma
|
relocation = (htab->elf.sgot->output_section->vma
|
||||||
+ htab->elf.sgot->output_offset + off
|
+ htab->elf.sgot->output_offset + off
|
||||||
@ -3747,12 +3785,18 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
/* LD->LE transition:
|
/* LD->LE transition:
|
||||||
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
|
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
|
||||||
We change it into:
|
For 64bit, we change it into:
|
||||||
.word 0x6666; .byte 0x66; movl %fs:0, %rax. */
|
.word 0x6666; .byte 0x66; movq %fs:0, %rax.
|
||||||
|
For 32bit, we change it into:
|
||||||
|
nopl 0x0(%rax); movl %fs:0, %eax. */
|
||||||
|
|
||||||
BFD_ASSERT (r_type == R_X86_64_TPOFF32);
|
BFD_ASSERT (r_type == R_X86_64_TPOFF32);
|
||||||
memcpy (contents + rel->r_offset - 3,
|
if (ABI_64_P (output_bfd))
|
||||||
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
|
memcpy (contents + rel->r_offset - 3,
|
||||||
|
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
|
||||||
|
else
|
||||||
|
memcpy (contents + rel->r_offset - 3,
|
||||||
|
"\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
|
||||||
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
|
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
2011-03-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* ld-x86-64/tlsgd4.dd: New.
|
||||||
|
* ld-x86-64/tlsgd4.s: Likewise.
|
||||||
|
* ld-x86-64/tlsgd5.dd: Likewise.
|
||||||
|
* ld-x86-64/tlsgd5a.s: Likewise.
|
||||||
|
* ld-x86-64/tlsgd5b.s: Likewise.
|
||||||
|
* ld-x86-64/tlsgd6.dd: Likewise.
|
||||||
|
* ld-x86-64/tlsgd6a.s: Likewise.
|
||||||
|
* ld-x86-64/tlsgd6b.s: Likewise.
|
||||||
|
* ld-x86-64/tlsld2.dd: Likewise.
|
||||||
|
* ld-x86-64/tlsld2.s: Likewise.
|
||||||
|
|
||||||
|
* ld-x86-64/x86-64.exp (x86_64tests): Add tlsgd4, libtlsgd5.so,
|
||||||
|
tlsgd5, libtlsgd6.so, tlsgd6 and tlsld2.
|
||||||
|
|
||||||
2011-03-03 H.J. Lu <hongjiu.lu@intel.com>
|
2011-03-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* ld-x86-64/tlsie4.dd: New.
|
* ld-x86-64/tlsie4.dd: New.
|
||||||
|
10
ld/testsuite/ld-x86-64/tlsgd4.dd
Normal file
10
ld/testsuite/ld-x86-64/tlsgd4.dd
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#target: x86_64-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 64 8b 04 25 00 00 00 00 mov %fs:0x0,%eax
|
||||||
|
[ ]*[a-f0-9]+: 48 8d 80 fc ff ff ff lea -0x4\(%rax\),%rax
|
||||||
|
#pass
|
14
ld/testsuite/ld-x86-64/tlsgd4.s
Normal file
14
ld/testsuite/ld-x86-64/tlsgd4.s
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
leaq foo@TLSGD(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
|
call __tls_get_addr
|
||||||
|
.globl foo
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 100
|
14
ld/testsuite/ld-x86-64/tlsgd5.dd
Normal file
14
ld/testsuite/ld-x86-64/tlsgd5.dd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#source: tlsgd5a.s
|
||||||
|
#as: --64
|
||||||
|
#ld: -melf_x86_64 tmpdir/tlsgd5
|
||||||
|
#objdump: -drw
|
||||||
|
#target: x86_64-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 64 48 8b 04 25 00 00 00 00 mov %fs:0x0,%rax
|
||||||
|
[ ]*[a-f0-9]+: 48 03 05 00 01 20 00 add 0x200100\(%rip\),%rax # 600368 <_DYNAMIC\+0x100>
|
||||||
|
#pass
|
8
ld/testsuite/ld-x86-64/tlsgd5a.s
Normal file
8
ld/testsuite/ld-x86-64/tlsgd5a.s
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
.byte 0x66
|
||||||
|
leaq foo@TLSGD(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
|
call __tls_get_addr
|
7
ld/testsuite/ld-x86-64/tlsgd5b.s
Normal file
7
ld/testsuite/ld-x86-64/tlsgd5b.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.globl foo
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 100
|
14
ld/testsuite/ld-x86-64/tlsgd6.dd
Normal file
14
ld/testsuite/ld-x86-64/tlsgd6.dd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#source: tlsgd6a.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 tmpdir/tlsgd6
|
||||||
|
#objdump: -drw
|
||||||
|
#target: x86_64-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 64 8b 04 25 00 00 00 00 mov %fs:0x0,%eax
|
||||||
|
[ ]*[a-f0-9]+: 48 03 05 81 00 20 00 add 0x200081\(%rip\),%rax # 60022c <_DYNAMIC\+0x80>
|
||||||
|
#pass
|
7
ld/testsuite/ld-x86-64/tlsgd6a.s
Normal file
7
ld/testsuite/ld-x86-64/tlsgd6a.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
leaq foo@TLSGD(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
|
call __tls_get_addr
|
7
ld/testsuite/ld-x86-64/tlsgd6b.s
Normal file
7
ld/testsuite/ld-x86-64/tlsgd6b.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.globl foo
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 100
|
14
ld/testsuite/ld-x86-64/tlsld2.dd
Normal file
14
ld/testsuite/ld-x86-64/tlsld2.dd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#source: tlsld2.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 tmpdir/tlsld2
|
||||||
|
#objdump: -drw
|
||||||
|
#target: x86_64-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
|
||||||
|
[ ]*[a-f0-9]+: 64 8b 04 25 00 00 00 00 mov %fs:0x0,%eax
|
||||||
|
#pass
|
12
ld/testsuite/ld-x86-64/tlsld2.s
Normal file
12
ld/testsuite/ld-x86-64/tlsld2.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
leaq foo@TLSLD(%rip), %rdi
|
||||||
|
call __tls_get_addr
|
||||||
|
.globl foo
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 100
|
@ -90,6 +90,22 @@ set x86_64tests {
|
|||||||
{"TLS X32 IE->LE transition" "-melf32_x86_64"
|
{"TLS X32 IE->LE transition" "-melf32_x86_64"
|
||||||
"--x32" {tlsie4.s}
|
"--x32" {tlsie4.s}
|
||||||
{{objdump -dwr tlsie4.dd}} "tlsie4"}
|
{{objdump -dwr tlsie4.dd}} "tlsie4"}
|
||||||
|
{"TLS X32 GD->LE transition" "-melf32_x86_64"
|
||||||
|
"--x32" {tlsgd4.s}
|
||||||
|
{{objdump -dwr tlsgd4.dd}} "tlsgd4"}
|
||||||
|
{"Helper TLS GD->IE transition DSO" "-shared -melf_x86_64"
|
||||||
|
"--64" {tlsgd5b.s} {} "libtlsgd5.so"}
|
||||||
|
{"TLS GD->IE transition" "-melf_x86_64 tmpdir/libtlsgd5.so"
|
||||||
|
"--64" {tlsgd5a.s}
|
||||||
|
{{objdump -dwr tlsgd5.dd}} "tlsgd5"}
|
||||||
|
{"Helper TLS X32 GD->IE transition DSO" "-shared -melf32_x86_64"
|
||||||
|
"--x32" {tlsgd6b.s} {} "libtlsgd6.so"}
|
||||||
|
{"TLS X32 GD->IE transition" "-melf32_x86_64 tmpdir/libtlsgd6.so"
|
||||||
|
"--x32" {tlsgd6a.s}
|
||||||
|
{{objdump -dwr tlsgd6.dd}} "tlsgd6"}
|
||||||
|
{"TLS X32 LD->LE transition" "-melf32_x86_64"
|
||||||
|
"--x32" {tlsld2.s}
|
||||||
|
{{objdump -dwr tlsld2.dd}} "tlsld2"}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_ld_link_tests $x86_64tests
|
run_ld_link_tests $x86_64tests
|
||||||
|
Reference in New Issue
Block a user