diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-02-14 03:50:40 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-02-14 03:50:55 -0800 |
commit | 451875b4f976a527395e9303224c7881b65e12ed (patch) | |
tree | 15ebc416aa1dd49b234ad02dfdf8a9ebe4f92f11 /ld/testsuite | |
parent | f98b2e334fcca666afaee3c6546b9fc91a4963d4 (diff) | |
download | gdb-451875b4f976a527395e9303224c7881b65e12ed.zip gdb-451875b4f976a527395e9303224c7881b65e12ed.tar.gz gdb-451875b4f976a527395e9303224c7881b65e12ed.tar.bz2 |
x86-64: Use PLT address for PC-relative reloc
Since PLT in PDE and PC-relative PLT in PIE can be used as function
address, there is no need for dynamic PC-relative relocation against
a dynamic function definition in PIE. Linker should resolve PC-relative
reference to its PLT address.
NB: i386 has non-PIC PLT and PIC PLT. Only non-PIC PLT in PDE can
be used as function address. PIC PLT in PIE can't be used as
function address.
bfd/
PR ld/22842
* elf32-i386.c (elf_i386_check_relocs): Pass FALSE for non
PC-relative PLT to NEED_DYNAMIC_RELOCATION_P.
* elf64-x86-64.c (elf_x86_64_check_relocs): Create PLT for
R_X86_64_PC32 reloc against dynamic function in data section.
Pass TRUE for PC-relative PLT to NEED_DYNAMIC_RELOCATION_P.
(elf_x86_64_relocate_section): Use PLT for R_X86_64_PC32 reloc
against dynamic function in data section.
* elfxx-x86.c (elf_x86_allocate_dynrelocs): Use PLT in PIE as
function address only if pcrel_plt is true.
(_bfd_x86_elf_link_hash_table_create): Set pcrel_plt.
* elfxx-x86.h (NEED_DYNAMIC_RELOCATION_P): Add PCREL_PLT for
PC-relative PLT. If PLT is PC-relative, don't generate dynamic
PC-relative relocation against a function definition in data
secton in PIE. Remove the obsolete comments.
(elf_x86_link_hash_table): Add pcrel_plt.
ld/
PR ld/22842
* testsuite/ld-i386/i386.exp: Run PR ld/22842 tests.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-i386/pr22842a.c: New file.
* testsuite/ld-i386/pr22842b.S: Likewise.
* testsuite/ld-x86-64/pr22842a.c: Likewise.
* testsuite/ld-x86-64/pr22842a.rd: Likewise.
* testsuite/ld-x86-64/pr22842b.S: Likewise.
* testsuite/ld-x86-64/pr22842b.rd: Likewise.
Diffstat (limited to 'ld/testsuite')
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr22842a.c | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr22842b.S | 41 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr22842a.c | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr22842a.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr22842b.S | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr22842b.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/x86-64.exp | 25 |
8 files changed, 150 insertions, 0 deletions
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index e4ec07d..ba2cce8 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -1273,6 +1273,14 @@ if { [isnative] {} \ "pr21997-1.so" \ ] \ + [list \ + "Build pr22842.so" \ + "-shared" \ + "-fPIC" \ + { pr22842a.c } \ + {} \ + "pr22842.so" \ + ] \ ] run_ld_link_exec_tests [list \ @@ -1371,6 +1379,14 @@ if { [isnative] "pr21997-1-pie-2" \ "pass.out" \ ] \ + [list \ + "Build pr22842" \ + "-pie -Wl,--no-as-needed tmpdir/pr22842.so" \ + "" \ + { pr22842b.S } \ + "pr22842" \ + "pass.out" \ + ] \ ] if { [at_least_gcc_version 5 0] } { diff --git a/ld/testsuite/ld-i386/pr22842a.c b/ld/testsuite/ld-i386/pr22842a.c new file mode 100644 index 0000000..52489bb --- /dev/null +++ b/ld/testsuite/ld-i386/pr22842a.c @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <stdlib.h> + +void +test (void) +{ + static int count; + if (count) + printf("PASS\n"); + count++; +} + +void +foo (void (*bar) (void)) +{ + if (bar != test) + abort (); + bar (); + test (); +} diff --git a/ld/testsuite/ld-i386/pr22842b.S b/ld/testsuite/ld-i386/pr22842b.S new file mode 100644 index 0000000..d959a5f --- /dev/null +++ b/ld/testsuite/ld-i386/pr22842b.S @@ -0,0 +1,41 @@ + .text + .globl main + .type main, @function +main: + leal 4(%esp), %ecx + andl $-16, %esp + pushl -4(%ecx) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %ecx + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + movl bar@GOT(%ebx), %eax + addl (%eax), %eax + pushl %eax + call foo@PLT + addl $16, %esp + leal -8(%ebp), %esp + xorl %eax, %eax + popl %ecx + popl %ebx + popl %ebp + leal -4(%ecx), %esp + ret + .size main, .-main + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: + movl (%esp), %ebx + ret + + .data + .p2align 2 +bar: + .long test - . + + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr22842a.c b/ld/testsuite/ld-x86-64/pr22842a.c new file mode 100644 index 0000000..52489bb --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22842a.c @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <stdlib.h> + +void +test (void) +{ + static int count; + if (count) + printf("PASS\n"); + count++; +} + +void +foo (void (*bar) (void)) +{ + if (bar != test) + abort (); + bar (); + test (); +} diff --git a/ld/testsuite/ld-x86-64/pr22842a.rd b/ld/testsuite/ld-x86-64/pr22842a.rd new file mode 100644 index 0000000..d78ea2f --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22842a.rd @@ -0,0 +1,4 @@ +#failif +#... +[0-9a-f ]+R_X86_64_NONE.* +#... diff --git a/ld/testsuite/ld-x86-64/pr22842b.S b/ld/testsuite/ld-x86-64/pr22842b.S new file mode 100644 index 0000000..f0659cd --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22842b.S @@ -0,0 +1,20 @@ + .text + .globl main + .type main,@function +main: + pushq %rax + movslq bar(%rip), %rax + leaq bar(%rip), %rdi + addq %rax, %rdi + + callq foo + xorl %eax, %eax + popq %rcx + retq + + .data + .p2align 2 +bar: + .long test - . + + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr22842b.rd b/ld/testsuite/ld-x86-64/pr22842b.rd new file mode 100644 index 0000000..f1036d5 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22842b.rd @@ -0,0 +1,4 @@ +#failif +#... +[0-9a-f ]+R_X86_64_PC32 +[0-9a-f]+ +test \+ 0 +#... diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 8442663..2a46266 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -1190,6 +1190,23 @@ if { [isnative] && [which $CC] != 0 } { {{readelf -drW pr22791-2.rd}} \ "pr22791-2" \ ] \ + [list \ + "Build pr22842.so" \ + "-shared" \ + "-fPIC" \ + { pr22842a.c } \ + {} \ + "pr22842.so" \ + ] \ + [list \ + "Build pr22842" \ + "-pie -Wl,--no-as-needed tmpdir/pr22842.so" \ + "" \ + { pr22842b.S } \ + {{readelf -rW pr22842a.rd} \ + {readelf -rW pr22842b.rd}} \ + "pr22842" \ + ] \ ] if {[istarget "x86_64-*-linux*-gnux32"]} { @@ -1524,6 +1541,14 @@ if { [isnative] && [which $CC] != 0 } { "pass.out" \ "$NOPIE_CFLAGS" \ ] \ + [list \ + "Build pr22842" \ + "-pie -Wl,--no-as-needed tmpdir/pr22842.so" \ + "" \ + { pr22842b.S } \ + "pr22842" \ + "pass.out" \ + ] \ ] # Run-time tests which require working ifunc attribute support. |