bfd/
* elf64-x86-64.c (elf64_x86_64_relocate_section): Change TLSGD sequence and its transitions. ld/testsuite/ * ld-x86-64/tlspic1.s: Change TLSGD sequences. * ld-x86-64/tlsbinpic.s: Likewise. * ld-x86-64/tlspic.dd: Adjust.
This commit is contained in:
parent
a45bb67df2
commit
abcf1d5247
6 changed files with 99 additions and 52 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elf64-x86-64.c (elf64_x86_64_relocate_section): Change TLSGD
|
||||||
|
sequence and its transitions.
|
||||||
|
|
||||||
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* elf32-i386.c (elf_i386_relocate_section): Resolve R_386_TLS_LDO_32
|
* elf32-i386.c (elf_i386_relocate_section): Resolve R_386_TLS_LDO_32
|
||||||
|
|
|
@ -2224,31 +2224,32 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
static unsigned char tlsgd[7]
|
static unsigned char tlsgd[8]
|
||||||
= { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
|
= { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
|
||||||
|
|
||||||
/* GD->LE transition.
|
/* GD->LE transition.
|
||||||
.long 0x66666666; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
callq __tls_get_addr@plt
|
.word 0x6666; rex64; call __tls_get_addr@plt
|
||||||
Change it into:
|
Change it into:
|
||||||
movq %fs:0, %rax
|
movq %fs:0, %rax
|
||||||
leaq foo@tpoff(%rax), %rax */
|
leaq foo@tpoff(%rax), %rax */
|
||||||
BFD_ASSERT (rel->r_offset >= 7);
|
BFD_ASSERT (rel->r_offset >= 4);
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 4; i++)
|
||||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||||
contents + rel->r_offset - 7 + i)
|
contents + rel->r_offset - 4 + i)
|
||||||
== tlsgd[i]);
|
== tlsgd[i]);
|
||||||
BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
|
BFD_ASSERT (rel->r_offset + 12 <= input_section->_raw_size);
|
||||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
for (i = 0; i < 4; i++)
|
||||||
contents + rel->r_offset + 4)
|
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||||
== 0xe8);
|
contents + rel->r_offset + 4 + i)
|
||||||
|
== tlsgd[i+4]);
|
||||||
BFD_ASSERT (rel + 1 < relend);
|
BFD_ASSERT (rel + 1 < relend);
|
||||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||||
memcpy (contents + rel->r_offset - 7,
|
memcpy (contents + rel->r_offset - 4,
|
||||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
||||||
16);
|
16);
|
||||||
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
||||||
contents + rel->r_offset + 5);
|
contents + rel->r_offset + 8);
|
||||||
/* Skip R_X86_64_PLT32. */
|
/* Skip R_X86_64_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -2397,27 +2398,28 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
static unsigned char tlsgd[7]
|
static unsigned char tlsgd[8]
|
||||||
= { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
|
= { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
|
||||||
|
|
||||||
/* GD->IE transition.
|
/* GD->IE transition.
|
||||||
.long 0x66666666; leaq foo@tlsgd(%rip), %rdi
|
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
|
||||||
callq __tls_get_addr@plt
|
.word 0x6666; rex64; call __tls_get_addr@plt
|
||||||
Change it into:
|
Change it into:
|
||||||
movq %fs:0, %rax
|
movq %fs:0, %rax
|
||||||
addq foo@gottpoff(%rip), %rax */
|
addq foo@gottpoff(%rip), %rax */
|
||||||
BFD_ASSERT (rel->r_offset >= 7);
|
BFD_ASSERT (rel->r_offset >= 4);
|
||||||
for (i = 0; i < 7; i++)
|
for (i = 0; i < 4; i++)
|
||||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||||
contents + rel->r_offset - 7 + i)
|
contents + rel->r_offset - 4 + i)
|
||||||
== tlsgd[i]);
|
== tlsgd[i]);
|
||||||
BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
|
BFD_ASSERT (rel->r_offset + 12 <= input_section->_raw_size);
|
||||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
for (i = 0; i < 4; i++)
|
||||||
contents + rel->r_offset + 4)
|
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||||
== 0xe8);
|
contents + rel->r_offset + 4 + i)
|
||||||
|
== tlsgd[i+4]);
|
||||||
BFD_ASSERT (rel + 1 < relend);
|
BFD_ASSERT (rel + 1 < relend);
|
||||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||||
memcpy (contents + rel->r_offset - 7,
|
memcpy (contents + rel->r_offset - 4,
|
||||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
||||||
16);
|
16);
|
||||||
|
|
||||||
|
@ -2426,9 +2428,9 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
- rel->r_offset
|
- rel->r_offset
|
||||||
- input_section->output_section->vma
|
- input_section->output_section->vma
|
||||||
- input_section->output_offset
|
- input_section->output_offset
|
||||||
- 9);
|
- 12);
|
||||||
bfd_put_32 (output_bfd, relocation,
|
bfd_put_32 (output_bfd, relocation,
|
||||||
contents + rel->r_offset + 5);
|
contents + rel->r_offset + 8);
|
||||||
/* Skip R_X86_64_PLT32. */
|
/* Skip R_X86_64_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* ld-x86-64/tlspic1.s: Change TLSGD sequences.
|
||||||
|
* ld-x86-64/tlsbinpic.s: Likewise.
|
||||||
|
* ld-x86-64/tlspic.dd: Adjust.
|
||||||
|
|
||||||
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
2002-10-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* ld-i386/i386.exp: Add tlsg test.
|
* ld-i386/i386.exp: Add tlsg test.
|
||||||
|
|
|
@ -40,33 +40,43 @@ fn2:
|
||||||
movq %rsp, %rbp
|
movq %rsp, %rbp
|
||||||
|
|
||||||
/* GD -> IE because variable is not defined in executable */
|
/* GD -> IE because variable is not defined in executable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sG1@tlsgd(%rip), %rdi
|
leaq sG1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> IE because variable is not defined in executable where
|
/* GD -> IE because variable is not defined in executable where
|
||||||
the variable is referenced through IE too */
|
the variable is referenced through IE too */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sG2@tlsgd(%rip), %rdi
|
leaq sG2@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> LE with global variable defined in executable */
|
/* GD -> LE with global variable defined in executable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sg1@tlsgd(%rip), %rdi
|
leaq sg1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> LE with local variable defined in executable */
|
/* GD -> LE with local variable defined in executable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sl1@tlsgd(%rip), %rdi
|
leaq sl1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> LE with hidden variable defined in executable */
|
/* GD -> LE with hidden variable defined in executable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sh1@tlsgd(%rip), %rdi
|
leaq sh1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,12 @@ Disassembly of section .text:
|
||||||
+1006: 90[ ]+nop *
|
+1006: 90[ ]+nop *
|
||||||
+1007: 90[ ]+nop *
|
+1007: 90[ ]+nop *
|
||||||
# GD
|
# GD
|
||||||
+1008: 66 66 66 66 48 8d 3d[ ]+lea 1053165\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
|
+1008: 66 48 8d 3d f0 11 10[ ]+lea 1053168\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
|
||||||
+100f: ed 11 10 00 *
|
+100f: 00 *
|
||||||
# -> R_X86_64_DTPMOD64 sg1
|
# -> R_X86_64_DTPMOD64 sg1
|
||||||
+1013: e8 68 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
+1010: 66[ ]+data16
|
||||||
|
+1011: 66[ ]+data16
|
||||||
|
+1012: 48 e8 68 f6 ff ff[ ]+rex64 callq [0-9a-f]+ <.*>
|
||||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||||
+1018: 90[ ]+nop *
|
+1018: 90[ ]+nop *
|
||||||
+1019: 90[ ]+nop *
|
+1019: 90[ ]+nop *
|
||||||
|
@ -36,10 +38,12 @@ Disassembly of section .text:
|
||||||
+102e: 90[ ]+nop *
|
+102e: 90[ ]+nop *
|
||||||
+102f: 90[ ]+nop *
|
+102f: 90[ ]+nop *
|
||||||
# GD against local variable
|
# GD against local variable
|
||||||
+1030: 66 66 66 66 48 8d 3d[ ]+lea 1053045\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
|
+1030: 66 48 8d 3d 78 11 10[ ]+lea 1053048\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
|
||||||
+1037: 75 11 10 00 *
|
+1037: 00 *
|
||||||
# -> R_X86_64_DTPMOD64 [0 0x2000000000000000]
|
# -> R_X86_64_DTPMOD64 [0 0x2000000000000000]
|
||||||
+103b: e8 40 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
+1038: 66[ ]+data16
|
||||||
|
+1039: 66[ ]+data16
|
||||||
|
+103a: 48 e8 40 f6 ff ff[ ]+rex64 callq [0-9a-f]+ <.*>
|
||||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||||
+1040: 90[ ]+nop *
|
+1040: 90[ ]+nop *
|
||||||
+1041: 90[ ]+nop *
|
+1041: 90[ ]+nop *
|
||||||
|
@ -55,10 +59,12 @@ Disassembly of section .text:
|
||||||
+1056: 90[ ]+nop *
|
+1056: 90[ ]+nop *
|
||||||
+1057: 90[ ]+nop *
|
+1057: 90[ ]+nop *
|
||||||
# GD against hidden and local variable
|
# GD against hidden and local variable
|
||||||
+1058: 66 66 66 66 48 8d 3d[ ]+lea 1053125\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
|
+1058: 66 48 8d 3d c8 11 10[ ]+lea 1053128\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
|
||||||
+105f: c5 11 10 00 *
|
+105f: 00 *
|
||||||
# -> R_X86_64_DTPMOD64 [0 0x4000000000000000]
|
# -> R_X86_64_DTPMOD64 [0 0x4000000000000000]
|
||||||
+1063: e8 18 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
+1060: 66[ ]+data16
|
||||||
|
+1061: 66[ ]+data16
|
||||||
|
+1062: 48 e8 18 f6 ff ff[ ]+rex64 callq [0-9a-f]+ <.*>
|
||||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||||
+1068: 90[ ]+nop *
|
+1068: 90[ ]+nop *
|
||||||
+1069: 90[ ]+nop *
|
+1069: 90[ ]+nop *
|
||||||
|
@ -74,10 +80,12 @@ Disassembly of section .text:
|
||||||
+107e: 90[ ]+nop *
|
+107e: 90[ ]+nop *
|
||||||
+107f: 90[ ]+nop *
|
+107f: 90[ ]+nop *
|
||||||
# GD against hidden but not local variable
|
# GD against hidden but not local variable
|
||||||
+1080: 66 66 66 66 48 8d 3d[ ]+lea 1053013\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
|
+1080: 66 48 8d 3d 58 11 10[ ]+lea 1053016\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
|
||||||
+1087: 55 11 10 00 *
|
+1087: 00 *
|
||||||
# -> R_X86_64_DTPMOD64 [0 0x6000000000000000]
|
# -> R_X86_64_DTPMOD64 [0 0x6000000000000000]
|
||||||
+108b: e8 f0 f5 ff ff[ ]+callq [0-9a-f]+ <.*>
|
+1088: 66[ ]+data16
|
||||||
|
+1089: 66[ ]+data16
|
||||||
|
+108a: 48 e8 f0 f5 ff ff[ ]+rex64 callq [0-9a-f]+ <.*>
|
||||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||||
+1090: 90[ ]+nop *
|
+1090: 90[ ]+nop *
|
||||||
+1091: 90[ ]+nop *
|
+1091: 90[ ]+nop *
|
||||||
|
|
|
@ -41,52 +41,68 @@ fn1:
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD */
|
/* GD */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sg1@tlsgd(%rip), %rdi
|
leaq sg1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> IE because variable is referenced through IE too */
|
/* GD -> IE because variable is referenced through IE too */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sg2@tlsgd(%rip), %rdi
|
leaq sg2@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD against local variable */
|
/* GD against local variable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sl1@tlsgd(%rip), %rdi
|
leaq sl1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> IE against local variable referenced through IE too */
|
/* GD -> IE against local variable referenced through IE too */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sl2@tlsgd(%rip), %rdi
|
leaq sl2@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD against hidden and local variable */
|
/* GD against hidden and local variable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sh1@tlsgd(%rip), %rdi
|
leaq sh1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> IE against hidden and local variable referenced through
|
/* GD -> IE against hidden and local variable referenced through
|
||||||
IE too */
|
IE too */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sh2@tlsgd(%rip), %rdi
|
leaq sh2@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD against hidden but not local variable */
|
/* GD against hidden but not local variable */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sH1@tlsgd(%rip), %rdi
|
leaq sH1@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
/* GD -> IE against hidden but not local variable referenced through
|
/* GD -> IE against hidden but not local variable referenced through
|
||||||
IE too */
|
IE too */
|
||||||
.long 0x66666666
|
.byte 0x66
|
||||||
leaq sH2@tlsgd(%rip), %rdi
|
leaq sH2@tlsgd(%rip), %rdi
|
||||||
|
.word 0x6666
|
||||||
|
rex64
|
||||||
call __tls_get_addr@plt
|
call __tls_get_addr@plt
|
||||||
nop;nop;nop;nop
|
nop;nop;nop;nop
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue