diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2016-06-11 20:44:24 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-06-11 21:24:01 -0700 |
commit | 74d7f0aa5b1e27da215349fb32337e1d83aca7d7 (patch) | |
tree | 87a0960c2945a4840eee0fa1be88e8c9db639f1c | |
parent | 0a41a307caca19383b05c8b558c25cf888c1c3f0 (diff) | |
download | gdb-74d7f0aa5b1e27da215349fb32337e1d83aca7d7.zip gdb-74d7f0aa5b1e27da215349fb32337e1d83aca7d7.tar.gz gdb-74d7f0aa5b1e27da215349fb32337e1d83aca7d7.tar.bz2 |
Subtract GOT base only with a base register
When relocating R_386_GOT32 in "op $0, bar@GOT", we shouldn't subtract
GOT base without a base register and we should disallow it without a
base register for PIC.
bfd/
PR ld/20244
* elf32-i386.c (elf_i386_relocate_section): When relocating
R_386_GOT32, return error without a base register for PIC and
subtract the .got.plt section address only with a base register.
ld/
PR ld/20244
* testsuite/ld-i386/i386.exp: Run pr20244-1a and pr20244-1b.
* testsuite/ld-i386/pr20244-1.s: New file.
* testsuite/ld-i386/pr20244-1a.d: Likewise.
* testsuite/ld-i386/pr20244-1b.d: Likewise.
* testsuite/ld-i386/pr20244-1c.d: Likewise.
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 36 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr20244-1.s | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr20244-1a.d | 26 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr20244-1b.d | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr20244-1c.d | 4 |
8 files changed, 109 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 67b9778..b9c3a73 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2016-06-11 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/20244 + * elf32-i386.c (elf_i386_relocate_section): When relocating + R_386_GOT32, return error without a base register for PIC and + subtract the .got.plt section address only with a base register. + 2016-06-10 Alan Modra <amodra@gmail.com> * elf-strtab.c (struct strtab_save): Use size_t for "size". diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 38c0520..7e2b2cb 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -4208,10 +4208,38 @@ r_386_got32: if (off >= (bfd_vma) -2) abort (); - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset; + relocation = (htab->elf.sgot->output_section->vma + + htab->elf.sgot->output_offset + off); + if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5) + { + 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. */ + const char *name; + + if (h == NULL) + name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, + NULL); + else + name = h->root.root.string; + + (*_bfd_error_handler) + (_("%B: direct GOT relocation R_386_GOT32 against `%s' without base register can not be used when making a shared object"), + input_bfd, name); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + } + else + { + /* Subtract the .got.plt section address only with a base + register. */ + relocation -= (htab->elf.sgotplt->output_section->vma + + htab->elf.sgotplt->output_offset); + } + break; case R_386_GOTOFF: diff --git a/ld/ChangeLog b/ld/ChangeLog index 234bf05..4a74c8f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2016-06-11 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/20244 + * testsuite/ld-i386/i386.exp: Run pr20244-1a and pr20244-1b. + * testsuite/ld-i386/pr20244-1.s: New file. + * testsuite/ld-i386/pr20244-1a.d: Likewise. + * testsuite/ld-i386/pr20244-1b.d: Likewise. + * testsuite/ld-i386/pr20244-1c.d: Likewise. + 2016-06-08 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/20221 diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index f6cbe43..a6efa53 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -400,6 +400,9 @@ run_dump_test "undefweaka" run_dump_test "undefweakb" run_dump_test "pr19539" run_dump_test "pr20117" +run_dump_test "pr20244-1a" +run_dump_test "pr20244-1b" +run_dump_test "pr20244-1c" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/pr20244-1.s b/ld/testsuite/ld-i386/pr20244-1.s new file mode 100644 index 0000000..f22ce62 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20244-1.s @@ -0,0 +1,17 @@ + .data + .type bar, @object +bar: + .byte 1 + .size bar, .-bar + .globl foo + .type foo, @object +foo: + .byte 1 + .size foo, .-foo + .text + .globl _start + .type _start, @function +_start: + movl $0, bar@GOT + cmpl $0, foo@GOT + movl $bar@GOT, %ecx diff --git a/ld/testsuite/ld-i386/pr20244-1a.d b/ld/testsuite/ld-i386/pr20244-1a.d new file mode 100644 index 0000000..46ae4be --- /dev/null +++ b/ld/testsuite/ld-i386/pr20244-1a.d @@ -0,0 +1,26 @@ +#source: pr20244-1.s +#as: --32 +#ld: -m elf_i386 +#objdump: --sym -dw +#notarget: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + +SYMBOL TABLE: +#... +0+80490a0 l O .data 00000001 bar +#... +0+8048074 g F .text 00000000 _start +#... +0+80490a1 g O .data 00000001 foo +#... + + + +Disassembly of section .text: + +0+8048074 <_start>: + +[a-f0-9]+: c7 05 8c 90 04 08 00 00 00 00 movl \$0x0,0x804908c + +[a-f0-9]+: 83 3d 90 90 04 08 00 cmpl \$0x0,0x8049090 + +[a-f0-9]+: b9 f8 ff ff ff mov \$0xfffffff8,%ecx +#pass diff --git a/ld/testsuite/ld-i386/pr20244-1b.d b/ld/testsuite/ld-i386/pr20244-1b.d new file mode 100644 index 0000000..d8ac4aa --- /dev/null +++ b/ld/testsuite/ld-i386/pr20244-1b.d @@ -0,0 +1,11 @@ +#source: pr20244-1.s +#as: --32 +#ld: -m elf_i386 +#objdump: -s -j .got +#notarget: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + +Contents of section .got: + 804908c a0900408 a1900408 +........ + +#pass diff --git a/ld/testsuite/ld-i386/pr20244-1c.d b/ld/testsuite/ld-i386/pr20244-1c.d new file mode 100644 index 0000000..c670507 --- /dev/null +++ b/ld/testsuite/ld-i386/pr20244-1c.d @@ -0,0 +1,4 @@ +#source: pr20244-1.s +#as: --32 +#ld: -pie -m elf_i386 +#error: direct GOT relocation R_386_GOT32 against `bar' without base register can not be used when making a shared object |