aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-02-15 11:39:30 -0800
committerH.J. Lu <hjl.tools@gmail.com>2017-02-15 11:39:48 -0800
commit2a5684011edabf5804abb9e11253a9747587b284 (patch)
tree8ed51e47a385a573a949b36a10451b8fd89ef080 /bfd/elf32-i386.c
parenta5def14f1ca70e14d9433cb229c9369fa3051598 (diff)
downloadgdb-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 'bfd/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 3bee4ca..e6e70d8 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4074,7 +4074,9 @@ elf_i386_relocate_section (bfd *output_bfd,
- gotplt->output_section->vma
- gotplt->output_offset);
- if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5)
+ if (rel->r_offset > 1
+ && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
+ && *(contents + rel->r_offset - 2) != 0x8d)
{
if (bfd_link_pic (info))
goto disallow_got32;
@@ -4345,13 +4347,15 @@ r_386_got32:
relocation = (htab->elf.sgot->output_section->vma
+ htab->elf.sgot->output_offset + off);
- if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5)
+ if (rel->r_offset > 1
+ && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
+ && *(contents + rel->r_offset - 2) != 0x8d)
{
if (bfd_link_pic (info))
{
/* For PIC, disallow R_386_GOT32 without a base
- register since we don't know what the GOT base
- is. */
+ register, except for "lea foo@GOT, %reg", since
+ we don't know what the GOT base is. */
const char *name;
disallow_got32: