From: H.J. Lu Date: Sun, 12 Jun 2016 03:44:24 +0000 (-0700) Subject: Subtract GOT base only with a base register X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74d7f0aa5b1e27da215349fb32337e1d83aca7d7;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 67b9778130c..b9c3a73fd23 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2016-06-11 H.J. Lu + + 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 * elf-strtab.c (struct strtab_save): Use size_t for "size". diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 38c05207d0d..7e2b2cba0e4 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 234bf059615..4a74c8f7aa2 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2016-06-11 H.J. Lu + + 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 PR ld/20221 diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index f6cbe4313ce..a6efa53e6af 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 00000000000..f22ce62fbc7 --- /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 00000000000..46ae4beb470 --- /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 00000000000..d8ac4aaffda --- /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 00000000000..c670507ff30 --- /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