mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
x86-64: Fix TLSDESC relaxation for x32
For x32, we must encode "lea x@TLSDESC(%rip), %reg" with a REX prefix even if it isn't required. Otherwise linker can’t safely perform GDesc -> IE/LE optimization. X32 TLSDESC sequences can be: 40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg ... 67 ff 10 call *x@TLSCALL(%eax) or the same sequence as LP64: 48 8d 05 00 00 00 00 lea foo@TLSDESC(%rip), %reg ... ff 10 call *foo@TLSCALL(%rax) We need to support both sequences for x32. For both GDesc -> IE/LE transitions, 67 ff 10 call *x@TLSCALL(%eax) should relaxed to 0f 1f 00 nopl (%rax) For GDesc -> LE transition, 40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg should relaxed to 40 c7 c0 fc ff ff ff rex movl $x@tpoff, %reg For GDesc -> IE transition, 40 8d 05 00 00 00 00 rex lea x@TLSDESC(%rip), %reg should relaxed to 40 8b 05 00 00 00 00 rex movl x@gottpoff(%rip), %eax bfd/ PR ld/25416 * elf64-x86-64.c (elf_x86_64_check_tls_transition): Support "rex leal x@tlsdesc(%rip), %reg" and "call *x@tlsdesc(%eax)" in X32 mode. (elf_x86_64_relocate_section): In x32 mode, for GDesc -> LE transition, relax "rex leal x@tlsdesc(%rip), %reg" to "rex movl $x@tpoff, %reg", for GDesc -> IE transition, relax "rex leal x@tlsdesc(%rip), %reg" to "rex movl x@gottpoff(%rip), %eax". For both transitions, relax "call *(%eax)" to "nopl (%rax)". gas/ PR ld/25416 * config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix for lea with R_X86_64_GOTPC32_TLSDESC relocation when generating x32 object. * testsuite/gas/i386/ilp32/x32-tls.d: Updated. * testsuite/gas/i386/ilp32/x32-tls.s: Add tests for lea with R_X86_64_GOTPC32_TLSDESC relocation. ld/ PR ld/25416 * testsuite/ld-x86-64/pr25416-1.s: New file * testsuite/ld-x86-64/pr25416-1a.d: Likewise. * testsuite/ld-x86-64/pr25416-1b.d: Likewise. * testsuite/ld-x86-64/pr25416-1.s: Likewise. * testsuite/ld-x86-64/pr25416-2.s: Likewise. * testsuite/ld-x86-64/pr25416-2a.d: Likewise. * testsuite/ld-x86-64/pr25416-2b.d: Likewise. * testsuite/ld-x86-64/pr25416-3.d: Likewise. * testsuite/ld-x86-64/pr25416-3.s: Likewise. * testsuite/ld-x86-64/pr25416-4.d: Likewise. * testsuite/ld-x86-64/pr25416-4.s: Likewise. * testsuite/ld-x86-64/pr25416-5a.c: Likewise. * testsuite/ld-x86-64/pr25416-5b.s: Likewise. * testsuite/ld-x86-64/pr25416-5c.s: Likewise. * testsuite/ld-x86-64/pr25416-5d.s: Likewise. * testsuite/ld-x86-64/pr25416-5e.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run PR ld/25416 tests.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2020-01-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/25416
|
||||||
|
* elf64-x86-64.c (elf_x86_64_check_tls_transition): Support
|
||||||
|
"rex leal x@tlsdesc(%rip), %reg" and "call *x@tlsdesc(%eax)" in
|
||||||
|
X32 mode.
|
||||||
|
(elf_x86_64_relocate_section): In x32 mode, for GDesc -> LE
|
||||||
|
transition, relax "rex leal x@tlsdesc(%rip), %reg" to
|
||||||
|
"rex movl $x@tpoff, %reg", for GDesc -> IE transition, relax
|
||||||
|
"rex leal x@tlsdesc(%rip), %reg" to
|
||||||
|
"rex movl x@gottpoff(%rip), %eax". For both transitions, relax
|
||||||
|
"call *(%eax)" to "nopl (%rax)".
|
||||||
|
|
||||||
2020-01-20 Alan Modra <amodra@gmail.com>
|
2020-01-20 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf64-ppc.c (LD_R11_0R3, CMPDI_R11_0, STD_R11_0R1, LD_R11_0R1),
|
* elf64-ppc.c (LD_R11_0R3, CMPDI_R11_0, STD_R11_0R1, LD_R11_0R1),
|
||||||
|
@ -1223,7 +1223,8 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|||||||
|
|
||||||
case R_X86_64_GOTPC32_TLSDESC:
|
case R_X86_64_GOTPC32_TLSDESC:
|
||||||
/* Check transition from GDesc access model:
|
/* Check transition from GDesc access model:
|
||||||
leaq x@tlsdesc(%rip), %rax
|
leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
|
||||||
|
rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
|
||||||
|
|
||||||
Make sure it's a leaq adding rip to a 32-bit offset
|
Make sure it's a leaq adding rip to a 32-bit offset
|
||||||
into any register, although it's probably almost always
|
into any register, although it's probably almost always
|
||||||
@ -1233,7 +1234,8 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
val = bfd_get_8 (abfd, contents + offset - 3);
|
val = bfd_get_8 (abfd, contents + offset - 3);
|
||||||
if ((val & 0xfb) != 0x48)
|
val &= 0xfb;
|
||||||
|
if (val != 0x48 && (ABI_64_P (abfd) || val != 0x40))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
|
if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
|
||||||
@ -1244,13 +1246,26 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|||||||
|
|
||||||
case R_X86_64_TLSDESC_CALL:
|
case R_X86_64_TLSDESC_CALL:
|
||||||
/* Check transition from GDesc access model:
|
/* Check transition from GDesc access model:
|
||||||
call *x@tlsdesc(%rax)
|
call *x@tlsdesc(%rax) <--- LP64 mode.
|
||||||
|
call *x@tlsdesc(%eax) <--- X32 mode.
|
||||||
*/
|
*/
|
||||||
if (offset + 2 <= sec->size)
|
if (offset + 2 <= sec->size)
|
||||||
{
|
{
|
||||||
/* Make sure that it's a call *x@tlsdesc(%rax). */
|
unsigned int prefix;
|
||||||
call = contents + offset;
|
call = contents + offset;
|
||||||
return call[0] == 0xff && call[1] == 0x10;
|
prefix = 0;
|
||||||
|
if (!ABI_64_P (abfd))
|
||||||
|
{
|
||||||
|
/* Check for call *x@tlsdesc(%eax). */
|
||||||
|
if (call[0] == 0x67)
|
||||||
|
{
|
||||||
|
prefix = 1;
|
||||||
|
if (offset + 3 > sec->size)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Make sure that it's a call *x@tlsdesc(%rax). */
|
||||||
|
return call[prefix] == 0xff && call[1 + prefix] == 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -3401,10 +3416,13 @@ corrupt_input:
|
|||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
leaq x@tlsdesc(%rip), %rax
|
leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
|
||||||
|
rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
|
||||||
|
|
||||||
Change it to:
|
Change it to:
|
||||||
movl $x@tpoff, %rax. */
|
movq $x@tpoff, %rax <--- LP64 mode.
|
||||||
|
rex movl $x@tpoff, %eax <--- X32 mode.
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int val, type;
|
unsigned int val, type;
|
||||||
|
|
||||||
@ -3412,7 +3430,8 @@ corrupt_input:
|
|||||||
goto corrupt_input;
|
goto corrupt_input;
|
||||||
type = bfd_get_8 (input_bfd, contents + roff - 3);
|
type = bfd_get_8 (input_bfd, contents + roff - 3);
|
||||||
val = bfd_get_8 (input_bfd, contents + roff - 1);
|
val = bfd_get_8 (input_bfd, contents + roff - 1);
|
||||||
bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
|
bfd_put_8 (output_bfd,
|
||||||
|
(type & 0x48) | ((type >> 2) & 1),
|
||||||
contents + roff - 3);
|
contents + roff - 3);
|
||||||
bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
|
bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
|
||||||
bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
|
bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
|
||||||
@ -3426,11 +3445,30 @@ corrupt_input:
|
|||||||
{
|
{
|
||||||
/* GDesc -> LE transition.
|
/* GDesc -> LE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
call *(%rax)
|
call *(%rax) <--- LP64 mode.
|
||||||
|
call *(%eax) <--- X32 mode.
|
||||||
Turn it into:
|
Turn it into:
|
||||||
xchg %ax,%ax. */
|
xchg %ax,%ax <-- LP64 mode.
|
||||||
|
nopl (%rax) <-- X32 mode.
|
||||||
|
*/
|
||||||
|
unsigned int prefix = 0;
|
||||||
|
if (!ABI_64_P (input_bfd))
|
||||||
|
{
|
||||||
|
/* Check for call *x@tlsdesc(%eax). */
|
||||||
|
if (contents[roff] == 0x67)
|
||||||
|
prefix = 1;
|
||||||
|
}
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
bfd_put_8 (output_bfd, 0x0f, contents + roff);
|
||||||
|
bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
|
||||||
|
bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
bfd_put_8 (output_bfd, 0x66, contents + roff);
|
bfd_put_8 (output_bfd, 0x66, contents + roff);
|
||||||
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (r_type == R_X86_64_GOTTPOFF)
|
else if (r_type == R_X86_64_GOTTPOFF)
|
||||||
@ -3741,13 +3779,18 @@ corrupt_input:
|
|||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally something like:
|
It's originally something like:
|
||||||
leaq x@tlsdesc(%rip), %rax
|
leaq x@tlsdesc(%rip), %rax <--- LP64 mode.
|
||||||
|
rex leal x@tlsdesc(%rip), %eax <--- X32 mode.
|
||||||
|
|
||||||
Change it to:
|
Change it to:
|
||||||
movq x@gottpoff(%rip), %rax # before xchg %ax,%ax. */
|
# before xchg %ax,%ax in LP64 mode.
|
||||||
|
movq x@gottpoff(%rip), %rax
|
||||||
|
# before nopl (%rax) in X32 mode.
|
||||||
|
rex movl x@gottpoff(%rip), %eax
|
||||||
|
*/
|
||||||
|
|
||||||
/* Now modify the instruction as appropriate. To
|
/* Now modify the instruction as appropriate. To
|
||||||
turn a leaq into a movq in the form we use it, it
|
turn a lea into a mov in the form we use it, it
|
||||||
suffices to change the second byte from 0x8d to
|
suffices to change the second byte from 0x8d to
|
||||||
0x8b. */
|
0x8b. */
|
||||||
if (roff < 2)
|
if (roff < 2)
|
||||||
@ -3768,13 +3811,32 @@ corrupt_input:
|
|||||||
{
|
{
|
||||||
/* GDesc -> IE transition.
|
/* GDesc -> IE transition.
|
||||||
It's originally:
|
It's originally:
|
||||||
call *(%rax)
|
call *(%rax) <--- LP64 mode.
|
||||||
|
call *(%eax) <--- X32 mode.
|
||||||
|
|
||||||
Change it to:
|
Change it to:
|
||||||
xchg %ax, %ax. */
|
xchg %ax, %ax <-- LP64 mode.
|
||||||
|
nopl (%rax) <-- X32 mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int prefix = 0;
|
||||||
|
if (!ABI_64_P (input_bfd))
|
||||||
|
{
|
||||||
|
/* Check for call *x@tlsdesc(%eax). */
|
||||||
|
if (contents[roff] == 0x67)
|
||||||
|
prefix = 1;
|
||||||
|
}
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
bfd_put_8 (output_bfd, 0x0f, contents + roff);
|
||||||
|
bfd_put_8 (output_bfd, 0x1f, contents + roff + 1);
|
||||||
|
bfd_put_8 (output_bfd, 0x00, contents + roff + 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
bfd_put_8 (output_bfd, 0x66, contents + roff);
|
bfd_put_8 (output_bfd, 0x66, contents + roff);
|
||||||
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
2020-01-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/25416
|
||||||
|
* config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix
|
||||||
|
for lea with R_X86_64_GOTPC32_TLSDESC relocation when generating
|
||||||
|
x32 object.
|
||||||
|
* testsuite/gas/i386/ilp32/x32-tls.d: Updated.
|
||||||
|
* testsuite/gas/i386/ilp32/x32-tls.s: Add tests for lea with
|
||||||
|
R_X86_64_GOTPC32_TLSDESC relocation.
|
||||||
|
|
||||||
2020-01-18 Nick Clifton <nickc@redhat.com>
|
2020-01-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
@ -8713,10 +8713,13 @@ output_insn (void)
|
|||||||
#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
|
#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
|
||||||
/* For x32, add a dummy REX_OPCODE prefix for mov/add with
|
/* For x32, add a dummy REX_OPCODE prefix for mov/add with
|
||||||
R_X86_64_GOTTPOFF relocation so that linker can safely
|
R_X86_64_GOTTPOFF relocation so that linker can safely
|
||||||
perform IE->LE optimization. */
|
perform IE->LE optimization. A dummy REX_OPCODE prefix
|
||||||
|
is also needed for lea with R_X86_64_GOTPC32_TLSDESC
|
||||||
|
relocation for GDesc -> IE/LE optimization. */
|
||||||
if (x86_elf_abi == X86_64_X32_ABI
|
if (x86_elf_abi == X86_64_X32_ABI
|
||||||
&& i.operands == 2
|
&& i.operands == 2
|
||||||
&& i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
|
&& (i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
|
||||||
|
|| i.reloc[0] == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
|
||||||
&& i.prefix[REX_PREFIX] == 0)
|
&& i.prefix[REX_PREFIX] == 0)
|
||||||
add_prefix (REX_OPCODE);
|
add_prefix (REX_OPCODE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,4 +10,6 @@ Disassembly of section .text:
|
|||||||
[ ]*[a-f0-9]+: 4c 8b 25 00 00 00 00 mov 0x0\(%rip\),%r12 # e <_start\+0xe>
|
[ ]*[a-f0-9]+: 4c 8b 25 00 00 00 00 mov 0x0\(%rip\),%r12 # e <_start\+0xe>
|
||||||
[ ]*[a-f0-9]+: 40 03 05 00 00 00 00 rex add 0x0\(%rip\),%eax # 15 <_start\+0x15>
|
[ ]*[a-f0-9]+: 40 03 05 00 00 00 00 rex add 0x0\(%rip\),%eax # 15 <_start\+0x15>
|
||||||
[ ]*[a-f0-9]+: 44 03 25 00 00 00 00 add 0x0\(%rip\),%r12d # 1c <_start\+0x1c>
|
[ ]*[a-f0-9]+: 44 03 25 00 00 00 00 add 0x0\(%rip\),%r12d # 1c <_start\+0x1c>
|
||||||
|
[ ]*[a-f0-9]+: 40 8d 05 00 00 00 00 rex lea 0x0\(%rip\),%eax # 23 <_start\+0x23>
|
||||||
|
[ ]*[a-f0-9]+: 44 8d 25 00 00 00 00 lea 0x0\(%rip\),%r12d # 2a <_start\+0x2a>
|
||||||
#pass
|
#pass
|
||||||
|
@ -4,6 +4,8 @@ _start:
|
|||||||
mov foo@gottpoff(%rip), %r12
|
mov foo@gottpoff(%rip), %r12
|
||||||
add foo@gottpoff(%rip), %eax
|
add foo@gottpoff(%rip), %eax
|
||||||
add foo@gottpoff(%rip), %r12d
|
add foo@gottpoff(%rip), %r12d
|
||||||
|
lea foo@tlsdesc(%rip), %eax
|
||||||
|
lea foo@tlsdesc(%rip), %r12d
|
||||||
.globl foo
|
.globl foo
|
||||||
.section .tdata,"awT",@progbits
|
.section .tdata,"awT",@progbits
|
||||||
.align 4
|
.align 4
|
||||||
|
21
ld/ChangeLog
21
ld/ChangeLog
@ -1,3 +1,24 @@
|
|||||||
|
2020-01-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/25416
|
||||||
|
* testsuite/ld-x86-64/pr25416-1.s: New file
|
||||||
|
* testsuite/ld-x86-64/pr25416-1a.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-1b.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-1.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-2.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-2a.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-2b.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-3.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-3.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-4.d: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-4.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-5a.c: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-5b.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-5c.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-5d.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/pr25416-5e.s: Likewise.
|
||||||
|
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/25416 tests.
|
||||||
|
|
||||||
2020-01-20 Alan Modra <amodra@gmail.com>
|
2020-01-20 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* testsuite/ld-powerpc/tlsexe.d: Match new __tls_get_addr stub.
|
* testsuite/ld-powerpc/tlsexe.d: Match new __tls_get_addr stub.
|
||||||
|
13
ld/testsuite/ld-x86-64/pr25416-1.s
Normal file
13
ld/testsuite/ld-x86-64/pr25416-1.s
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
lea foo@TLSDESC(%rip), %eax
|
||||||
|
call *foo@TLSCALL(%eax)
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
16
ld/testsuite/ld-x86-64/pr25416-1a.d
Normal file
16
ld/testsuite/ld-x86-64/pr25416-1a.d
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#name: X32 GDesc 1
|
||||||
|
#source: pr25416-1.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 -shared
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
#...
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 40 8d 05 ([0-9a-f]{2} ){4}[ \t]+rex lea 0x[a-f0-9]+\(%rip\),%eax[ \t]+# [a-f0-9]+ <_GLOBAL_OFFSET_TABLE_\+0x[a-f0-9]+>
|
||||||
|
+[a-f0-9]+: 67 ff 10 callq \*\(%eax\)
|
||||||
|
#pass
|
15
ld/testsuite/ld-x86-64/pr25416-1b.d
Normal file
15
ld/testsuite/ld-x86-64/pr25416-1b.d
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#name: X32 GDesc -> LE 1
|
||||||
|
#source: pr25416-1.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 40 c7 c0 ([0-9a-f]{2} ){4}[ \t]+rex mov \$0x[a-f0-9]+,%eax
|
||||||
|
+[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
|
||||||
|
#pass
|
13
ld/testsuite/ld-x86-64/pr25416-2.s
Normal file
13
ld/testsuite/ld-x86-64/pr25416-2.s
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
lea foo@TLSDESC(%rip), %rax
|
||||||
|
call *foo@TLSCALL(%rax)
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
16
ld/testsuite/ld-x86-64/pr25416-2a.d
Normal file
16
ld/testsuite/ld-x86-64/pr25416-2a.d
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#name: X32 GDesc 2
|
||||||
|
#source: pr25416-2.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 -shared
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
#...
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea 0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_GLOBAL_OFFSET_TABLE_\+0x[a-f0-9]+>
|
||||||
|
+[a-f0-9]+: ff 10 callq \*\(%rax\)
|
||||||
|
#pass
|
15
ld/testsuite/ld-x86-64/pr25416-2b.d
Normal file
15
ld/testsuite/ld-x86-64/pr25416-2b.d
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#name: X32 GDesc -> LE 2
|
||||||
|
#source: pr25416-2.s
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 48 c7 c0 ([0-9a-f]{2} ){4}[ \t]+mov \$0x[a-f0-9]+,%rax
|
||||||
|
+[a-f0-9]+: 66 90 xchg %ax,%ax
|
||||||
|
#pass
|
16
ld/testsuite/ld-x86-64/pr25416-3.d
Normal file
16
ld/testsuite/ld-x86-64/pr25416-3.d
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#name: X32 GDesc -> IE 1
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 -shared
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 40 8b 05 ([0-9a-f]{2} ){4}[ \t]+rex mov 0x[a-f0-9]+\(%rip\),%eax[ \t]+# [a-f0-9]+ <.got>
|
||||||
|
+[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
|
||||||
|
+[a-f0-9]+: 64 8b 0c 25 00 00 00 00 mov %fs:0x0,%ecx
|
||||||
|
+[a-f0-9]+: 40 03 0d ([0-9a-f]{2} ){4}[ \t]+rex add 0x[a-f0-9]+\(%rip\),%ecx[ \t]+# [a-f0-9]+ <.got>
|
||||||
|
#pass
|
15
ld/testsuite/ld-x86-64/pr25416-3.s
Normal file
15
ld/testsuite/ld-x86-64/pr25416-3.s
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
lea foo@TLSDESC(%rip), %eax
|
||||||
|
call *foo@TLSCALL(%eax)
|
||||||
|
movl %fs:0, %ecx
|
||||||
|
addl foo@gottpoff(%rip), %ecx
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
16
ld/testsuite/ld-x86-64/pr25416-4.d
Normal file
16
ld/testsuite/ld-x86-64/pr25416-4.d
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#name: X32 GDesc -> IE 2
|
||||||
|
#as: --x32
|
||||||
|
#ld: -melf32_x86_64 -shared
|
||||||
|
#objdump: -dw
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
[a-f0-9]+ <_start>:
|
||||||
|
+[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov 0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <.got>
|
||||||
|
+[a-f0-9]+: 66 90 xchg %ax,%ax
|
||||||
|
+[a-f0-9]+: 64 8b 0c 25 00 00 00 00 mov %fs:0x0,%ecx
|
||||||
|
+[a-f0-9]+: 40 03 0d ([0-9a-f]{2} ){4}[ \t]+rex add 0x[a-f0-9]+\(%rip\),%ecx[ \t]+# [a-f0-9]+ <.got>
|
||||||
|
#pass
|
15
ld/testsuite/ld-x86-64/pr25416-4.s
Normal file
15
ld/testsuite/ld-x86-64/pr25416-4.s
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
lea foo@TLSDESC(%rip), %rax
|
||||||
|
call *foo@TLSCALL(%rax)
|
||||||
|
movl %fs:0, %ecx
|
||||||
|
addl foo@gottpoff(%rip), %ecx
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
33
ld/testsuite/ld-x86-64/pr25416-5a.c
Normal file
33
ld/testsuite/ld-x86-64/pr25416-5a.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
__thread int bar = 301;
|
||||||
|
|
||||||
|
extern int *test1 (int);
|
||||||
|
extern int *test2 (int);
|
||||||
|
extern int *test3 (int);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int *p;
|
||||||
|
p = test1 (30);
|
||||||
|
if (*p != 30)
|
||||||
|
abort ();
|
||||||
|
*p = 40;
|
||||||
|
test1 (40);
|
||||||
|
p = test2 (301);
|
||||||
|
if (*p != 301)
|
||||||
|
abort ();
|
||||||
|
if (p != &bar)
|
||||||
|
abort ();
|
||||||
|
*p = 40;
|
||||||
|
test2 (40);
|
||||||
|
p = test3 (40);
|
||||||
|
if (*p != 40)
|
||||||
|
abort ();
|
||||||
|
*p = 50;
|
||||||
|
test3 (50);
|
||||||
|
puts ("PASS");
|
||||||
|
return 0;
|
||||||
|
}
|
52
ld/testsuite/ld-x86-64/pr25416-5b.s
Normal file
52
ld/testsuite/ld-x86-64/pr25416-5b.s
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.text
|
||||||
|
.p2align 4
|
||||||
|
.globl test1
|
||||||
|
.type test1, @function
|
||||||
|
test1:
|
||||||
|
.cfi_startproc
|
||||||
|
subl $8, %esp
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
lea foo@TLSDESC(%rip), %eax
|
||||||
|
call *foo@TLSCALL(%eax)
|
||||||
|
addl %fs:0, %eax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L5
|
||||||
|
addl $8, %esp
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
ret
|
||||||
|
.L5:
|
||||||
|
.cfi_restore_state
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test1, .-test1
|
||||||
|
.p2align 4
|
||||||
|
.globl test2
|
||||||
|
.type test2, @function
|
||||||
|
test2:
|
||||||
|
.cfi_startproc
|
||||||
|
subl $8, %esp
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
lea bar@TLSDESC(%rip), %eax
|
||||||
|
call *bar@TLSCALL(%eax)
|
||||||
|
addl %fs:0, %eax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L9
|
||||||
|
addl $8, %esp
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
ret
|
||||||
|
.L9:
|
||||||
|
.cfi_restore_state
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test2, .-test2
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.hidden foo
|
||||||
|
.globl foo
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
56
ld/testsuite/ld-x86-64/pr25416-5c.s
Normal file
56
ld/testsuite/ld-x86-64/pr25416-5c.s
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
.text
|
||||||
|
.p2align 4
|
||||||
|
.globl test1
|
||||||
|
.type test1, @function
|
||||||
|
test1:
|
||||||
|
.cfi_startproc
|
||||||
|
subq $8, %rsp
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
lea foo@TLSDESC(%rip), %rax
|
||||||
|
call *foo@TLSCALL(%rax)
|
||||||
|
addl %fs:0, %eax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L5
|
||||||
|
movl %eax, %r8d
|
||||||
|
addq $8, %rsp
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
movq %r8, %rax
|
||||||
|
ret
|
||||||
|
.L5:
|
||||||
|
.cfi_restore_state
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test1, .-test1
|
||||||
|
.p2align 4
|
||||||
|
.globl test2
|
||||||
|
.type test2, @function
|
||||||
|
test2:
|
||||||
|
.cfi_startproc
|
||||||
|
subq $8, %rsp
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
lea bar@TLSDESC(%rip), %rax
|
||||||
|
call *bar@TLSCALL(%rax)
|
||||||
|
addl %fs:0, %eax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L9
|
||||||
|
movl %eax, %r8d
|
||||||
|
addq $8, %rsp
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
movq %r8, %rax
|
||||||
|
ret
|
||||||
|
.L9:
|
||||||
|
.cfi_restore_state
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test2, .-test2
|
||||||
|
.section .tdata,"awT",@progbits
|
||||||
|
.align 4
|
||||||
|
.hidden foo
|
||||||
|
.globl foo
|
||||||
|
.type foo, @object
|
||||||
|
.size foo, 4
|
||||||
|
foo:
|
||||||
|
.long 30
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
19
ld/testsuite/ld-x86-64/pr25416-5d.s
Normal file
19
ld/testsuite/ld-x86-64/pr25416-5d.s
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.text
|
||||||
|
.p2align 4
|
||||||
|
.globl test3
|
||||||
|
.type test3, @function
|
||||||
|
test3:
|
||||||
|
.cfi_startproc
|
||||||
|
movl %fs:0, %eax
|
||||||
|
addq foo@gottpoff(%rip), %rax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L7
|
||||||
|
movl %eax, %eax
|
||||||
|
ret
|
||||||
|
.L7:
|
||||||
|
pushq %rax
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test3, .-test3
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
23
ld/testsuite/ld-x86-64/pr25416-5e.s
Normal file
23
ld/testsuite/ld-x86-64/pr25416-5e.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.text
|
||||||
|
.p2align 4
|
||||||
|
.globl test3
|
||||||
|
.type test3, @function
|
||||||
|
test3:
|
||||||
|
.cfi_startproc
|
||||||
|
subl $8, %esp
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
lea foo@TLSDESC(%rip), %eax
|
||||||
|
call *foo@TLSCALL(%eax)
|
||||||
|
addl %fs:0, %eax
|
||||||
|
cmpl %edi, (%eax)
|
||||||
|
jne .L5
|
||||||
|
addl $8, %esp
|
||||||
|
.cfi_remember_state
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
ret
|
||||||
|
.L5:
|
||||||
|
.cfi_restore_state
|
||||||
|
call abort@PLT
|
||||||
|
.cfi_endproc
|
||||||
|
.size test3, .-test3
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
@ -461,6 +461,12 @@ run_dump_test "pr24721-x32"
|
|||||||
run_dump_test "pr24905"
|
run_dump_test "pr24905"
|
||||||
run_dump_test "pr24905-x32"
|
run_dump_test "pr24905-x32"
|
||||||
run_dump_test "align-branch-1"
|
run_dump_test "align-branch-1"
|
||||||
|
run_dump_test "pr25416-1a"
|
||||||
|
run_dump_test "pr25416-2b"
|
||||||
|
run_dump_test "pr25416-2a"
|
||||||
|
run_dump_test "pr25416-2b"
|
||||||
|
run_dump_test "pr25416-3"
|
||||||
|
run_dump_test "pr25416-4"
|
||||||
|
|
||||||
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
|
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
|
||||||
return
|
return
|
||||||
@ -1302,6 +1308,51 @@ if { [isnative] && [check_compiler_available] } {
|
|||||||
]
|
]
|
||||||
|
|
||||||
if {[istarget "x86_64-*-linux*-gnux32"]} {
|
if {[istarget "x86_64-*-linux*-gnux32"]} {
|
||||||
|
run_cc_link_tests [list \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5b.o (GDesc -maddress-mode=short)" \
|
||||||
|
"" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5b.s } \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5b.so (GDesc -> IE -maddress-mode=short)" \
|
||||||
|
"-shared" \
|
||||||
|
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5b.s pr25416-5d.s } \
|
||||||
|
{} \
|
||||||
|
"pr25416-5b.so" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5c.o (GDesc -maddress-mode=long)" \
|
||||||
|
"" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5c.s } \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5c.so (GDesc -> IE -maddress-mode=long)" \
|
||||||
|
"-shared" \
|
||||||
|
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5c.s pr25416-5d.s } \
|
||||||
|
{} \
|
||||||
|
"pr25416-5c.so" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5d.so (GDesc -maddress-mode=short)" \
|
||||||
|
"-shared" \
|
||||||
|
"-fPIC -Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5b.s pr25416-5e.s } \
|
||||||
|
{} \
|
||||||
|
"pr25416-5d.so" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr25416-5d.o (IE -maddress-mode=short)" \
|
||||||
|
"" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5d.s } \
|
||||||
|
] \
|
||||||
|
]
|
||||||
|
|
||||||
run_ld_link_exec_tests [list \
|
run_ld_link_exec_tests [list \
|
||||||
[list \
|
[list \
|
||||||
"Run pr22001-1b" \
|
"Run pr22001-1b" \
|
||||||
@ -1321,6 +1372,67 @@ if { [isnative] && [check_compiler_available] } {
|
|||||||
"pass.out" \
|
"pass.out" \
|
||||||
"$NOPIE_CFLAGS" \
|
"$NOPIE_CFLAGS" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5a (GDesc -> IE -maddress-mode=short)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr25416-5b.so" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5a" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5b (GDesc -> LE -maddress-mode=short" \
|
||||||
|
"$NOPIE_LDFLAGS tmpdir/pr25416-5b.o tmpdir/pr25416-5d.o" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5b" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5c (GDesc -> IE -maddress-mode=long)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr25416-5c.so" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5c" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5d (GDesc -> LE -maddress-mode=long)" \
|
||||||
|
"$NOPIE_LDFLAGS tmpdir/pr25416-5c.o tmpdir/pr25416-5d.o" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5d" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5e (GDesc -maddress-mode=short)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/pr25416-5d.so" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5e" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5f (PIE GDesc -> LE -maddress-mode=short)" \
|
||||||
|
"-pie tmpdir/pr25416-5b.o tmpdir/pr25416-5d.o" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5f" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr25416-5g (PIE GDesc -> LE -maddress-mode=long)" \
|
||||||
|
"-pie tmpdir/pr25416-5c.o tmpdir/pr25416-5d.o" \
|
||||||
|
"-Wa,-mx86-used-note=yes" \
|
||||||
|
{ pr25416-5a.c } \
|
||||||
|
"pr25416-5g" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
run_cc_link_tests [list \
|
run_cc_link_tests [list \
|
||||||
|
Reference in New Issue
Block a user