mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 13:56:22 +08:00
bfd/
2007-08-14 H.J. Lu <hongjiu.lu@intel.com> PR ld/4918 * elf32-i386.c (elf_i386_relocate_section): Allow R_386_PC32 on ___tls_get_addr for GD->LE/LD->LE transitions when not building shared library. * elf64-x86-64.c (elf64_x86_64_relocate_section): Allow R_X86_64_PC32 on __tls_get_addr for GD->LE/LD->LE transitions when not building shared library. ld/testsuite/ 2007-08-14 H.J. Lu <hongjiu.lu@intel.com> PR ld/4918 * ld-i386/i386.exp (i386tests): Add tlsgd1 and tlsld1 tests. * ld-x86-64/x86-64.exp (x86_64tests): Likewise. * ld-i386/tlsgd1.dd: New file. * ld-i386/tlsgd1.s: Likewise. * ld-i386/tlsld1.dd: Likewise. * ld-i386/tlsld1.s: Likewise. * ld-x86-64/tlsgd1.dd: Likewise. * ld-x86-64/tlsgd1.s: Likewise. * ld-x86-64/tlsld1.dd: Likewise. * ld-x86-64/tlsld1.s: Likewise.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2007-08-14 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/4918
|
||||||
|
* elf32-i386.c (elf_i386_relocate_section): Allow R_386_PC32
|
||||||
|
on ___tls_get_addr for GD->LE/LD->LE transitions when not
|
||||||
|
building shared library.
|
||||||
|
|
||||||
|
* elf64-x86-64.c (elf64_x86_64_relocate_section): Allow
|
||||||
|
R_X86_64_PC32 on __tls_get_addr for GD->LE/LD->LE transitions
|
||||||
|
when not building shared library.
|
||||||
|
|
||||||
2007-08-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2007-08-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): LOADBASE is now
|
* elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): LOADBASE is now
|
||||||
|
@ -2652,6 +2652,8 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
unsigned int val, type;
|
unsigned int val, type;
|
||||||
bfd_vma roff;
|
bfd_vma roff;
|
||||||
|
unsigned long tls_r_symndx;
|
||||||
|
struct elf_link_hash_entry *tls_h;
|
||||||
|
|
||||||
/* GD->LE transition. */
|
/* GD->LE transition. */
|
||||||
BFD_ASSERT (rel->r_offset >= 2);
|
BFD_ASSERT (rel->r_offset >= 2);
|
||||||
@ -2662,7 +2664,16 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
contents + rel->r_offset + 4)
|
contents + rel->r_offset + 4)
|
||||||
== 0xe8);
|
== 0xe8);
|
||||||
BFD_ASSERT (rel + 1 < relend);
|
BFD_ASSERT (rel + 1 < relend);
|
||||||
BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
|
tls_r_symndx = ELF32_R_SYM (rel[1].r_info);
|
||||||
|
BFD_ASSERT (tls_r_symndx >= symtab_hdr->sh_info);
|
||||||
|
tls_h = sym_hashes[tls_r_symndx - symtab_hdr->sh_info];
|
||||||
|
BFD_ASSERT (tls_h != NULL
|
||||||
|
&& tls_h->root.root.string != NULL
|
||||||
|
&& strcmp (tls_h->root.root.string,
|
||||||
|
"___tls_get_addr") == 0);
|
||||||
|
BFD_ASSERT ((! info->shared
|
||||||
|
&& ELF32_R_TYPE (rel[1].r_info) == R_386_PC32)
|
||||||
|
|| ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
|
||||||
roff = rel->r_offset + 5;
|
roff = rel->r_offset + 5;
|
||||||
val = bfd_get_8 (input_bfd,
|
val = bfd_get_8 (input_bfd,
|
||||||
contents + rel->r_offset - 1);
|
contents + rel->r_offset - 1);
|
||||||
@ -2707,7 +2718,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
}
|
}
|
||||||
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
||||||
contents + roff);
|
contents + roff);
|
||||||
/* Skip R_386_PLT32. */
|
/* Skip R_386_PC32/R_386_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3191,6 +3202,8 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
if (! info->shared)
|
if (! info->shared)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
unsigned long tls_r_symndx;
|
||||||
|
struct elf_link_hash_entry *tls_h;
|
||||||
|
|
||||||
/* LD->LE transition:
|
/* LD->LE transition:
|
||||||
Ensure it is:
|
Ensure it is:
|
||||||
@ -3206,10 +3219,18 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
|
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
|
||||||
== 0xe8);
|
== 0xe8);
|
||||||
BFD_ASSERT (rel + 1 < relend);
|
BFD_ASSERT (rel + 1 < relend);
|
||||||
BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
|
tls_r_symndx = ELF32_R_SYM (rel[1].r_info);
|
||||||
|
BFD_ASSERT (tls_r_symndx >= symtab_hdr->sh_info);
|
||||||
|
tls_h = sym_hashes[tls_r_symndx - symtab_hdr->sh_info];
|
||||||
|
BFD_ASSERT (tls_h != NULL
|
||||||
|
&& tls_h->root.root.string != NULL
|
||||||
|
&& strcmp (tls_h->root.root.string,
|
||||||
|
"___tls_get_addr") == 0);
|
||||||
|
BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
|
||||||
|
|| ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
|
||||||
memcpy (contents + rel->r_offset - 2,
|
memcpy (contents + rel->r_offset - 2,
|
||||||
"\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
|
"\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
|
||||||
/* Skip R_386_PLT32. */
|
/* Skip R_386_PC32/R_386_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2527,10 +2527,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
static unsigned char tlsgd[8]
|
static unsigned char tlsgd[8]
|
||||||
= { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
|
= { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
|
||||||
|
unsigned long tls_r_symndx;
|
||||||
|
struct elf_link_hash_entry *tls_h;
|
||||||
|
|
||||||
/* GD->LE transition.
|
/* GD->LE transition.
|
||||||
.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
|
||||||
Change it into:
|
Change it into:
|
||||||
movq %fs:0, %rax
|
movq %fs:0, %rax
|
||||||
leaq foo@tpoff(%rax), %rax */
|
leaq foo@tpoff(%rax), %rax */
|
||||||
@ -2545,13 +2547,22 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||||||
contents + rel->r_offset + 4 + i)
|
contents + rel->r_offset + 4 + i)
|
||||||
== tlsgd[i+4]);
|
== 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);
|
tls_r_symndx = ELF64_R_SYM (rel[1].r_info);
|
||||||
|
BFD_ASSERT (tls_r_symndx >= symtab_hdr->sh_info);
|
||||||
|
tls_h = sym_hashes[tls_r_symndx - symtab_hdr->sh_info];
|
||||||
|
BFD_ASSERT (tls_h != NULL
|
||||||
|
&& tls_h->root.root.string != NULL
|
||||||
|
&& strcmp (tls_h->root.root.string,
|
||||||
|
"__tls_get_addr") == 0);
|
||||||
|
BFD_ASSERT ((! info->shared
|
||||||
|
&& ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32)
|
||||||
|
|| ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||||
memcpy (contents + rel->r_offset - 4,
|
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 + 8);
|
contents + rel->r_offset + 8);
|
||||||
/* Skip R_X86_64_PLT32. */
|
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2919,9 +2930,12 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||||||
case R_X86_64_TLSLD:
|
case R_X86_64_TLSLD:
|
||||||
if (! info->shared)
|
if (! info->shared)
|
||||||
{
|
{
|
||||||
|
unsigned long tls_r_symndx;
|
||||||
|
struct elf_link_hash_entry *tls_h;
|
||||||
|
|
||||||
/* LD->LE transition:
|
/* LD->LE transition:
|
||||||
Ensure it is:
|
Ensure it is:
|
||||||
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr@plt.
|
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
|
||||||
We change it into:
|
We change it into:
|
||||||
.word 0x6666; .byte 0x66; movl %fs:0, %rax. */
|
.word 0x6666; .byte 0x66; movl %fs:0, %rax. */
|
||||||
BFD_ASSERT (rel->r_offset >= 3);
|
BFD_ASSERT (rel->r_offset >= 3);
|
||||||
@ -2935,10 +2949,18 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
|
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
|
||||||
== 0xe8);
|
== 0xe8);
|
||||||
BFD_ASSERT (rel + 1 < relend);
|
BFD_ASSERT (rel + 1 < relend);
|
||||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
tls_r_symndx = ELF64_R_SYM (rel[1].r_info);
|
||||||
|
BFD_ASSERT (tls_r_symndx >= symtab_hdr->sh_info);
|
||||||
|
tls_h = sym_hashes[tls_r_symndx - symtab_hdr->sh_info];
|
||||||
|
BFD_ASSERT (tls_h != NULL
|
||||||
|
&& tls_h->root.root.string != NULL
|
||||||
|
&& strcmp (tls_h->root.root.string,
|
||||||
|
"__tls_get_addr") == 0);
|
||||||
|
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32
|
||||||
|
|| ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||||
memcpy (contents + rel->r_offset - 3,
|
memcpy (contents + rel->r_offset - 3,
|
||||||
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
|
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
|
||||||
/* Skip R_X86_64_PLT32. */
|
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
|
||||||
rel++;
|
rel++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
2007-08-14 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/4918
|
||||||
|
* ld-i386/i386.exp (i386tests): Add tlsgd1 and tlsld1 tests.
|
||||||
|
* ld-x86-64/x86-64.exp (x86_64tests): Likewise.
|
||||||
|
|
||||||
|
* ld-i386/tlsgd1.dd: New file.
|
||||||
|
* ld-i386/tlsgd1.s: Likewise.
|
||||||
|
* ld-i386/tlsld1.dd: Likewise.
|
||||||
|
* ld-i386/tlsld1.s: Likewise.
|
||||||
|
* ld-x86-64/tlsgd1.dd: Likewise.
|
||||||
|
* ld-x86-64/tlsgd1.s: Likewise.
|
||||||
|
* ld-x86-64/tlsld1.dd: Likewise.
|
||||||
|
* ld-x86-64/tlsld1.s: Likewise.
|
||||||
|
|
||||||
2007-08-13 Richard Sandiford <richard@codesourcery.com>
|
2007-08-13 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
* ld-mips-elf/vxworks-forced-local-1.d,
|
* ld-mips-elf/vxworks-forced-local-1.d,
|
||||||
|
@ -109,6 +109,12 @@ set i386tests {
|
|||||||
{emit-relocs.s} {{readelf --relocs emit-relocs.d}} "emit-relocs.so"}
|
{emit-relocs.s} {{readelf --relocs emit-relocs.d}} "emit-relocs.so"}
|
||||||
{"-z combreloc relocation sections" "-shared -melf_i386 -z combreloc"
|
{"-z combreloc relocation sections" "-shared -melf_i386 -z combreloc"
|
||||||
"--32" {combreloc.s} {{readelf -r combreloc.d}} "combreloc.so"}
|
"--32" {combreloc.s} {{readelf -r combreloc.d}} "combreloc.so"}
|
||||||
|
{"TLS GD->LE transition" "-melf_i386"
|
||||||
|
"--32" {tlsgd1.s}
|
||||||
|
{{objdump -dwr tlsgd1.dd}} "tlsgd1"}
|
||||||
|
{"TLS LD->LE transition" "-melf_i386"
|
||||||
|
"--32" {tlsld1.s}
|
||||||
|
{{objdump -dwr tlsld1.dd}} "tlsld1"}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_ld_link_tests $i386tests
|
run_ld_link_tests $i386tests
|
||||||
|
14
ld/testsuite/ld-i386/tlsgd1.dd
Normal file
14
ld/testsuite/ld-i386/tlsgd1.dd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#source: tlsgd1.s
|
||||||
|
#as: --32
|
||||||
|
#ld: -melf_i386 tmpdir/tlsgd1
|
||||||
|
#objdump: -drw
|
||||||
|
#target: i?86-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
|
||||||
|
[ ]*[a-f0-9]+: 81 e8 04 00 00 00 sub \$0x4,%eax
|
||||||
|
#pass
|
12
ld/testsuite/ld-i386/tlsgd1.s
Normal file
12
ld/testsuite/ld-i386/tlsgd1.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
leal foo@TLSGD(,%ebx,1), %eax
|
||||||
|
call ___tls_get_addr
|
||||||
|
.globl foo
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 100
|
15
ld/testsuite/ld-i386/tlsld1.dd
Normal file
15
ld/testsuite/ld-i386/tlsld1.dd
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#source: tlsld1.s
|
||||||
|
#as: --32
|
||||||
|
#ld: -melf_i386 tmpdir/tlsld1
|
||||||
|
#objdump: -drw
|
||||||
|
#target: i?86-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 65 a1 00 00 00 00 mov %gs:0x0,%eax
|
||||||
|
[ ]*[a-f0-9]+: 90 nop
|
||||||
|
[ ]*[a-f0-9]+: 8d 74 26 00 lea 0x0\(%esi\),%esi
|
||||||
|
#pass
|
12
ld/testsuite/ld-i386/tlsld1.s
Normal file
12
ld/testsuite/ld-i386/tlsld1.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
leal foo@TLSLDM(%ebx), %eax
|
||||||
|
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/tlsgd1.dd
Normal file
14
ld/testsuite/ld-x86-64/tlsgd1.dd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#source: tlsgd1.s
|
||||||
|
#as: --64
|
||||||
|
#ld: -melf_x86_64 tmpdir/tlsgd1
|
||||||
|
#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 8d 80 fc ff ff ff lea -0x4\(%rax\),%rax
|
||||||
|
#pass
|
15
ld/testsuite/ld-x86-64/tlsgd1.s
Normal file
15
ld/testsuite/ld-x86-64/tlsgd1.s
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
.byte 0x66
|
||||||
|
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
|
13
ld/testsuite/ld-x86-64/tlsld1.dd
Normal file
13
ld/testsuite/ld-x86-64/tlsld1.dd
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#source: tlsld1.s
|
||||||
|
#as: --64
|
||||||
|
#ld: -melf_x86_64 tmpdir/tlsld1
|
||||||
|
#objdump: -drw
|
||||||
|
#target: x86_64-*-linux*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
[ ]*[a-f0-9]+: 66 66 66 64 48 8b 04 25 00 00 00 00 mov %fs:0x0,%rax
|
||||||
|
#pass
|
12
ld/testsuite/ld-x86-64/tlsld1.s
Normal file
12
ld/testsuite/ld-x86-64/tlsld1.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
|
@ -66,6 +66,12 @@ set x86_64tests {
|
|||||||
{"TLS in debug sections" "-melf_x86_64"
|
{"TLS in debug sections" "-melf_x86_64"
|
||||||
"--64" {tlsg.s}
|
"--64" {tlsg.s}
|
||||||
{{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}
|
{{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}
|
||||||
|
{"TLS GD->LE transition" "-melf_x86_64"
|
||||||
|
"--64" {tlsgd1.s}
|
||||||
|
{{objdump -dwr tlsgd1.dd}} "tlsgd1"}
|
||||||
|
{"TLS LD->LE transition" "-melf_x86_64"
|
||||||
|
"--64" {tlsld1.s}
|
||||||
|
{{objdump -dwr tlsld1.dd}} "tlsld1"}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_ld_link_tests $x86_64tests
|
run_ld_link_tests $x86_64tests
|
||||||
|
Reference in New Issue
Block a user