diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-02-15 11:39:30 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-02-15 11:39:48 -0800 |
commit | 2a5684011edabf5804abb9e11253a9747587b284 (patch) | |
tree | 8ed51e47a385a573a949b36a10451b8fd89ef080 /ld/testsuite | |
parent | a5def14f1ca70e14d9433cb229c9369fa3051598 (diff) | |
download | gdb-2a5684011edabf5804abb9e11253a9747587b284.zip gdb-2a5684011edabf5804abb9e11253a9747587b284.tar.gz gdb-2a5684011edabf5804abb9e11253a9747587b284.tar.bz2 |
i386: Allow "lea foo@GOT, %reg" in PIC
"lea foo@GOT, %reg" is OK in PIC since it only loads the GOT offset
into register, which can be used later with a GOT base register to
get the value in the GOT entry.
bfd/
PR ld/21168
* elf32-i386.c (elf_i386_relocate_section): Allow
"lea foo@GOT, %reg" in PIC.
ld/
PR ld/21168
* testsuite/ld-i386/i386.exp: Run pr21168.
* testsuite/ld-i386/pr21168a.c: New file.
* testsuite/ld-i386/pr21168b.S: Likewise.
Diffstat (limited to 'ld/testsuite')
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr21168a.c | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr21168b.S | 29 |
3 files changed, 65 insertions, 0 deletions
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 7680ff5..c489227 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -835,6 +835,20 @@ if { [isnative] "-fPIC -O2 -g" \ { ifunc-1a.c ifunc-1b.S ifunc-1c.S ifunc-1d.S } \ ] \ + [list \ + "Build pr21168a.o" \ + "" \ + "" \ + { pr21168a.c } \ + ] \ + [list \ + "Build pr21168.so" \ + "-shared" \ + "" \ + { pr21168b.S } \ + "" \ + "pr21168.so" \ + ] \ ] run_ld_link_exec_tests [list \ @@ -856,6 +870,14 @@ if { [isnative] "ifunc-1b" \ "pass.out" \ ] \ + [list \ + "Run pr21168" \ + "tmpdir/pr21168a.o tmpdir/pr21168.so" \ + "" \ + { dummy.c } \ + "pr21168" \ + "pass.out" \ + ] \ ] } diff --git a/ld/testsuite/ld-i386/pr21168a.c b/ld/testsuite/ld-i386/pr21168a.c new file mode 100644 index 0000000..a6c0da1 --- /dev/null +++ b/ld/testsuite/ld-i386/pr21168a.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int foo = 1; + +extern int *bar (void); +extern int bar_ifunc (void); + +int +main (void) +{ + if (bar () == &foo && bar_ifunc () == 0xbadbeef) + printf ("PASS\n"); + return 0; +} diff --git a/ld/testsuite/ld-i386/pr21168b.S b/ld/testsuite/ld-i386/pr21168b.S new file mode 100644 index 0000000..a4ea5c9 --- /dev/null +++ b/ld/testsuite/ld-i386/pr21168b.S @@ -0,0 +1,29 @@ + .text + .globl bar + .type bar, @function +bar: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + lea foo@GOT, %ecx + mov (%eax,%ecx,1), %eax + ret + .globl bar_ifunc + .type bar_ifunc, @function +bar_ifunc: + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + lea ifunc@GOT, %ecx + mov (%eax,%ecx,1), %eax + ret + .type ifunc, @gnu_indirect_function +ifunc: + mov $0xbadbeef, %eax + ret + .section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat + .globl __x86.get_pc_thunk.ax + .hidden __x86.get_pc_thunk.ax + .type __x86.get_pc_thunk.ax, @function +__x86.get_pc_thunk.ax: + movl (%esp), %eax + ret + .section .note.GNU-stack,"",@progbits |