+2014-07-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/17154
+ * elf32-i386.c (elf_i386_plt_sym_val): Only match R_*_JUMP_SLOT
+ and R_*_IRELATIVE relocation offset with PLT entry.
+ * elf64-x86-64.c (elf_x86_64_plt_sym_val): Likewise.
+ (elf_x86_64_plt_sym_val_offset_plt_bnd): New.
+ (elf_x86_64_get_synthetic_symtab): Use it.
+
2014-07-15 H.J. Lu <hongjiu.lu@intel.com>
PR ld/17057
return TRUE;
}
-/* Return address for Ith PLT stub in section PLT, for relocation REL
- or (bfd_vma) -1 if it should not be included. */
+/* Return address in section PLT for the Ith GOTPLT relocation, for
+ relocation REL or (bfd_vma) -1 if it should not be included. */
static bfd_vma
-elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
- const arelent *rel ATTRIBUTE_UNUSED)
+elf_i386_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel)
{
- return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
+ bfd *abfd;
+ const struct elf_i386_backend_data *bed;
+ bfd_vma plt_offset;
+
+ /* Only match R_386_JUMP_SLOT and R_386_IRELATIVE. */
+ if (rel->howto->type != R_386_JUMP_SLOT
+ && rel->howto->type != R_386_IRELATIVE)
+ return (bfd_vma) -1;
+
+ abfd = plt->owner;
+ bed = get_elf_i386_backend_data (abfd);
+ plt_offset = bed->plt->plt_entry_size;
+ while (plt_offset < plt->size)
+ {
+ bfd_vma reloc_offset;
+ bfd_byte reloc_offset_raw[4];
+
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ reloc_offset_raw,
+ plt_offset + bed->plt->plt_reloc_offset,
+ sizeof (reloc_offset_raw)))
+ return (bfd_vma) -1;
+
+ reloc_offset = H_GET_32 (abfd, reloc_offset_raw);
+ if (reloc_offset == i * sizeof (Elf32_External_Rel))
+ return plt->vma + plt_offset;
+ plt_offset += bed->plt->plt_entry_size;
+ }
+
+ abort ();
}
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
return TRUE;
}
-/* Return address for Ith PLT stub in section PLT, for relocation REL
- or (bfd_vma) -1 if it should not be included. */
+/* Return address in section PLT for the Ith GOTPLT relocation, for
+ relocation REL or (bfd_vma) -1 if it should not be included. */
static bfd_vma
elf_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
- const arelent *rel ATTRIBUTE_UNUSED)
+ const arelent *rel)
{
- return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
+ bfd *abfd;
+ const struct elf_x86_64_backend_data *bed;
+ bfd_vma plt_offset;
+
+ /* Only match R_X86_64_JUMP_SLOT and R_X86_64_IRELATIVE. */
+ if (rel->howto->type != R_X86_64_JUMP_SLOT
+ && rel->howto->type != R_X86_64_IRELATIVE)
+ return (bfd_vma) -1;
+
+ abfd = plt->owner;
+ bed = get_elf_x86_64_backend_data (abfd);
+ plt_offset = bed->plt_entry_size;
+ while (plt_offset < plt->size)
+ {
+ bfd_vma reloc_index;
+ bfd_byte reloc_index_raw[4];
+
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ reloc_index_raw,
+ plt_offset + bed->plt_reloc_offset,
+ sizeof (reloc_index_raw)))
+ return (bfd_vma) -1;
+
+ reloc_index = H_GET_32 (abfd, reloc_index_raw);
+ if (reloc_index == i)
+ return plt->vma + plt_offset;
+ plt_offset += bed->plt_entry_size;
+ }
+
+ abort ();
+}
+
+/* Return offset in .plt.bnd section for the Ith GOTPLT relocation with
+ PLT section, or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_x86_64_plt_sym_val_offset_plt_bnd (bfd_vma i, const asection *plt)
+{
+ const struct elf_x86_64_backend_data *bed = &elf_x86_64_bnd_arch_bed;
+ bfd *abfd = plt->owner;
+ bfd_vma plt_offset = bed->plt_entry_size;
+ while (plt_offset < plt->size)
+ {
+ bfd_vma reloc_index;
+ bfd_byte reloc_index_raw[4];
+
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ reloc_index_raw,
+ plt_offset + bed->plt_reloc_offset,
+ sizeof (reloc_index_raw)))
+ return (bfd_vma) -1;
+
+ reloc_index = H_GET_32 (abfd, reloc_index_raw);
+ if (reloc_index == i)
+ {
+ /* This is the index in .plt section. */
+ long plt_index = plt_offset / bed->plt_entry_size;
+ /* Return the offset in .plt.bnd section. */
+ return (plt_index - 1) * sizeof (elf_x86_64_legacy_plt2_entry);
+ }
+ plt_offset += bed->plt_entry_size;
+ }
+
+ abort ();
}
/* Similar to _bfd_elf_get_synthetic_symtab, with .plt.bnd section
size_t size;
Elf_Internal_Shdr *hdr;
char *names;
- asection *plt;
- bfd_vma addr;
+ asection *plt, *plt_push;
+
+ plt_push = bfd_get_section_by_name (abfd, ".plt");
+ if (plt_push == NULL)
+ return 0;
plt = bfd_get_section_by_name (abfd, ".plt.bnd");
/* Use the generic ELF version if there is no .plt.bnd section. */
names = (char *) (s + count);
p = relplt->relocation;
n = 0;
- addr = 0;
for (i = 0; i < count; i++, p++)
{
+ bfd_vma offset;
size_t len;
+ if (p->howto->type != R_X86_64_JUMP_SLOT
+ && p->howto->type != R_X86_64_IRELATIVE)
+ continue;
+
+ offset = elf_x86_64_plt_sym_val_offset_plt_bnd (i, plt_push);
+
*s = **p->sym_ptr_ptr;
/* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
we are defining a symbol, ensure one of them is set. */
s->flags |= BSF_GLOBAL;
s->flags |= BSF_SYNTHETIC;
s->section = plt;
- s->value = addr;
+ s->value = offset;
s->name = names;
s->udata.p = NULL;
len = strlen ((*p->sym_ptr_ptr)->name);
memcpy (names, "@plt", sizeof ("@plt"));
names += sizeof ("@plt");
++s, ++n;
- addr += sizeof (elf_x86_64_legacy_plt2_entry);
}
return n;
+2014-07-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/17154
+ * ld-ifunc/pr17154-i386.d: New file.
+ * ld-ifunc/pr17154-x86-64.d: Likewise.
+ * ld-ifunc/pr17154-x86.s: Likewise.
+ * ld-x86-64/bnd-ifunc-2.d: Likewise.
+ * ld-x86-64/bnd-ifunc-2.s: Likewise.
+ * ld-x86-64/mpx.exp: Run bnd-ifunc-2.
+ * ld-x86-64/tlsdesc-nacl.pd: Updated.
+ * ld-x86-64/tlsdesc.pd: Likewise.
+
2014-07-15 H.J. Lu <hongjiu.lu@intel.com>
PR ld/17057
--- /dev/null
+#source: pr17154-x86.s
+#ld: -m elf_i386 -shared
+#as: --32
+#objdump: -dw
+#target: x86_64-*-* i?86-*-*
+
+#...
+0+1d0 <\*ABS\*@plt-0x10>:
+[ ]*[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\)
+[ ]*[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\)
+[ ]*[a-f0-9]+: 00 00 add %al,\(%eax\)
+ ...
+
+0+1e0 <\*ABS\*@plt>:
+[ ]*[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\)
+[ ]*[a-f0-9]+: 68 18 00 00 00 push \$0x18
+[ ]*[a-f0-9]+: e9 e0 ff ff ff jmp 1d0 <\*ABS\*@plt-0x10>
+
+0+1f0 <func1@plt>:
+[ ]*[a-f0-9]+: ff a3 10 00 00 00 jmp \*0x10\(%ebx\)
+[ ]*[a-f0-9]+: 68 00 00 00 00 push \$0x0
+[ ]*[a-f0-9]+: e9 d0 ff ff ff jmp 1d0 <\*ABS\*@plt-0x10>
+
+0+200 <func2@plt>:
+[ ]*[a-f0-9]+: ff a3 14 00 00 00 jmp \*0x14\(%ebx\)
+[ ]*[a-f0-9]+: 68 08 00 00 00 push \$0x8
+[ ]*[a-f0-9]+: e9 c0 ff ff ff jmp 1d0 <\*ABS\*@plt-0x10>
+
+0+210 <\*ABS\*@plt>:
+[ ]*[a-f0-9]+: ff a3 18 00 00 00 jmp \*0x18\(%ebx\)
+[ ]*[a-f0-9]+: 68 10 00 00 00 push \$0x10
+[ ]*[a-f0-9]+: e9 b0 ff ff ff jmp 1d0 <\*ABS\*@plt-0x10>
+
+Disassembly of section .text:
+
+0+220 <resolve1>:
+[ ]*[a-f0-9]+: e8 cb ff ff ff call 1f0 <func1@plt>
+
+0+225 <g1>:
+[ ]*[a-f0-9]+: e9 e6 ff ff ff jmp 210 <\*ABS\*@plt>
+
+0+22a <resolve2>:
+[ ]*[a-f0-9]+: e8 d1 ff ff ff call 200 <func2@plt>
+
+0+22f <g2>:
+[ ]*[a-f0-9]+: e9 ac ff ff ff jmp 1e0 <\*ABS\*@plt>
+#pass
--- /dev/null
+#source: pr17154-x86.s
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -dw
+#target: x86_64-*-*
+
+#...
+0+2d0 <\*ABS\*\+0x32a@plt-0x10>:
+[ ]*[a-f0-9]+: ff 35 5a 01 20 00 pushq 0x20015a\(%rip\) # 200430 <_GLOBAL_OFFSET_TABLE_\+0x8>
+[ ]*[a-f0-9]+: ff 25 5c 01 20 00 jmpq \*0x20015c\(%rip\) # 200438 <_GLOBAL_OFFSET_TABLE_\+0x10>
+[ ]*[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\)
+
+0+2e0 <\*ABS\*\+0x32a@plt>:
+[ ]*[a-f0-9]+: ff 25 5a 01 20 00 jmpq \*0x20015a\(%rip\) # 200440 <_GLOBAL_OFFSET_TABLE_\+0x18>
+[ ]*[a-f0-9]+: 68 03 00 00 00 pushq \$0x3
+[ ]*[a-f0-9]+: e9 e0 ff ff ff jmpq 2d0 <\*ABS\*\+0x32a@plt-0x10>
+
+0+2f0 <func1@plt>:
+[ ]*[a-f0-9]+: ff 25 52 01 20 00 jmpq \*0x200152\(%rip\) # 200448 <_GLOBAL_OFFSET_TABLE_\+0x20>
+[ ]*[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+[ ]*[a-f0-9]+: e9 d0 ff ff ff jmpq 2d0 <\*ABS\*\+0x32a@plt-0x10>
+
+0+300 <func2@plt>:
+[ ]*[a-f0-9]+: ff 25 4a 01 20 00 jmpq \*0x20014a\(%rip\) # 200450 <_GLOBAL_OFFSET_TABLE_\+0x28>
+[ ]*[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+[ ]*[a-f0-9]+: e9 c0 ff ff ff jmpq 2d0 <\*ABS\*\+0x32a@plt-0x10>
+
+0+310 <\*ABS\*\+0x320@plt>:
+[ ]*[a-f0-9]+: ff 25 42 01 20 00 jmpq \*0x200142\(%rip\) # 200458 <_GLOBAL_OFFSET_TABLE_\+0x30>
+[ ]*[a-f0-9]+: 68 02 00 00 00 pushq \$0x2
+[ ]*[a-f0-9]+: e9 b0 ff ff ff jmpq 2d0 <\*ABS\*\+0x32a@plt-0x10>
+
+Disassembly of section .text:
+
+0+320 <resolve1>:
+[ ]*[a-f0-9]+: e8 cb ff ff ff callq 2f0 <func1@plt>
+
+0+325 <g1>:
+[ ]*[a-f0-9]+: e9 e6 ff ff ff jmpq 310 <\*ABS\*\+0x320@plt>
+
+0+32a <resolve2>:
+[ ]*[a-f0-9]+: e8 d1 ff ff ff callq 300 <func2@plt>
+
+0+32f <g2>:
+[ ]*[a-f0-9]+: e9 ac ff ff ff jmpq 2e0 <\*ABS\*\+0x32a@plt>
+#pass
--- /dev/null
+ .text
+ .globl fct1
+ .type fct1, @gnu_indirect_function
+ .set fct1,resolve1
+ .hidden int_fct1
+ .globl int_fct1
+ .set int_fct1,fct1
+ .type resolve1, @function
+resolve1:
+ call func1@PLT
+ .globl g1
+ .type g1, @function
+g1:
+ jmp int_fct1@PLT
+
+ .globl fct2
+ .type fct2, @gnu_indirect_function
+ .set fct2,resolve2
+ .hidden int_fct2
+ .globl int_fct2
+ .set int_fct2,fct2
+ .type resolve2, @function
+resolve2:
+ call func2@PLT
+ .globl g2
+ .type g2, @function
+g2:
+ jmp int_fct2@PLT
--- /dev/null
+#as: --64 -madd-bnd-prefix
+#ld: -shared -melf_x86_64
+#objdump: -dw
+
+#...
+0+2d0 <.plt>:
+[ ]*[a-f0-9]+: ff 35 7a 01 20 00 pushq 0x20017a\(%rip\) # 200450 <_GLOBAL_OFFSET_TABLE_\+0x8>
+[ ]*[a-f0-9]+: f2 ff 25 7b 01 20 00 bnd jmpq \*0x20017b\(%rip\) # 200458 <_GLOBAL_OFFSET_TABLE_\+0x10>
+[ ]*[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+[ ]*[a-f0-9]+: 68 03 00 00 00 pushq \$0x3
+[ ]*[a-f0-9]+: f2 e9 e5 ff ff ff bnd jmpq 2d0 <\*ABS\*\+0x34c@plt-0x50>
+[ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+[ ]*[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+[ ]*[a-f0-9]+: f2 e9 d5 ff ff ff bnd jmpq 2d0 <\*ABS\*\+0x34c@plt-0x50>
+[ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+[ ]*[a-f0-9]+: 68 01 00 00 00 pushq \$0x1
+[ ]*[a-f0-9]+: f2 e9 c5 ff ff ff bnd jmpq 2d0 <\*ABS\*\+0x34c@plt-0x50>
+[ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+[ ]*[a-f0-9]+: 68 02 00 00 00 pushq \$0x2
+[ ]*[a-f0-9]+: f2 e9 b5 ff ff ff bnd jmpq 2d0 <\*ABS\*\+0x34c@plt-0x50>
+[ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .plt.bnd:
+
+0+320 <\*ABS\*\+0x34c@plt>:
+[ ]*[a-f0-9]+: f2 ff 25 39 01 20 00 bnd jmpq \*0x200139\(%rip\) # 200460 <_GLOBAL_OFFSET_TABLE_\+0x18>
+[ ]*[a-f0-9]+: 90 nop
+
+0+328 <func1@plt>:
+[ ]*[a-f0-9]+: f2 ff 25 39 01 20 00 bnd jmpq \*0x200139\(%rip\) # 200468 <_GLOBAL_OFFSET_TABLE_\+0x20>
+[ ]*[a-f0-9]+: 90 nop
+
+0+330 <func2@plt>:
+[ ]*[a-f0-9]+: f2 ff 25 39 01 20 00 bnd jmpq \*0x200139\(%rip\) # 200470 <_GLOBAL_OFFSET_TABLE_\+0x28>
+[ ]*[a-f0-9]+: 90 nop
+
+0+338 <\*ABS\*\+0x340@plt>:
+[ ]*[a-f0-9]+: f2 ff 25 39 01 20 00 bnd jmpq \*0x200139\(%rip\) # 200478 <_GLOBAL_OFFSET_TABLE_\+0x30>
+[ ]*[a-f0-9]+: 90 nop
+
+Disassembly of section .text:
+
+0+340 <resolve1>:
+[ ]*[a-f0-9]+: f2 e8 e2 ff ff ff bnd callq 328 <func1@plt>
+
+0+346 <g1>:
+[ ]*[a-f0-9]+: f2 e9 ec ff ff ff bnd jmpq 338 <\*ABS\*\+0x340@plt>
+
+0+34c <resolve2>:
+[ ]*[a-f0-9]+: f2 e8 de ff ff ff bnd callq 330 <func2@plt>
+
+0+352 <g2>:
+[ ]*[a-f0-9]+: f2 e9 c8 ff ff ff bnd jmpq 320 <\*ABS\*\+0x34c@plt>
+#pass
--- /dev/null
+ .text
+ .globl fct1
+ .type fct1, @gnu_indirect_function
+ .set fct1,resolve1
+ .hidden int_fct1
+ .globl int_fct1
+ .set int_fct1,fct1
+ .type resolve1, @function
+resolve1:
+ call func1@PLT
+ .globl g1
+ .type g1, @function
+g1:
+ jmp int_fct1@PLT
+
+ .globl fct2
+ .type fct2, @gnu_indirect_function
+ .set fct2,resolve2
+ .hidden int_fct2
+ .globl int_fct2
+ .set int_fct2,fct2
+ .type resolve2, @function
+resolve2:
+ call func2@PLT
+ .globl g2
+ .type g2, @function
+g2:
+ jmp int_fct2@PLT
run_dump_test "bnd-branch-1"
run_dump_test "bnd-ifunc-1"
+run_dump_test "bnd-ifunc-2"
run_dump_test "bnd-plt-1"
Disassembly of section .plt:
-[0-9a-f]+ <.*@plt-0x40>:
+[0-9a-f]+ <.plt>:
+[0-9a-f]+: ff 35 .. .. .. .. pushq 0x[0-9a-f]+\(%rip\) +# [0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x8>
+[0-9a-f]+: 4c 8b 1d .. .. .. .. mov 0x[0-9a-f]+\(%rip\),%r11 +# [0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x10>
+[0-9a-f]+: 41 83 e3 e0 and \$0xffffffe0,%r11d
+[0-9a-f]+: 0f 1f 84 00 00 00 00 *
+[0-9a-f]+: 00 *
+[0-9a-f]+: 66 90 xchg %ax,%ax
-
-[0-9a-f]+ <.*@plt>:
+[0-9a-f]+: ff 35 .. .. .. .. pushq 0x[0-9a-f]+\(%rip\) +# [0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x8>
+[0-9a-f]+: 4c 8b 1d .. .. .. .. mov 0x[0-9a-f]+\(%rip\),%r11 +# [0-9a-f]+ <_DYNAMIC\+0x190>
+[0-9a-f]+: 41 83 e3 e0 and \$0xffffffe0,%r11d
Disassembly of section .plt:
-[0-9a-f]+ <.*@plt-0x10>:
+[0-9a-f]+ <.plt>:
[0-9a-f]+: ff 35 .. .. 20 00 pushq .*\(%rip\) # 201358 <_GLOBAL_OFFSET_TABLE_\+0x8>
[0-9a-f]+: ff 25 .. .. 20 00 jmpq \*.*\(%rip\) # 201360 <_GLOBAL_OFFSET_TABLE_\+0x10>
[0-9a-f]+: 0f 1f 40 00 nopl 0x0\(%rax\)
-[0-9a-f]+ <.*@plt>:
[0-9a-f]+: ff 35 .. .. 20 00 pushq .*\(%rip\) # 201358 <_GLOBAL_OFFSET_TABLE_\+0x8>
[0-9a-f]+: ff 25 .. .. 20 00 jmpq \*.*\(%rip\) # 201348 <_DYNAMIC\+0x190>
[0-9a-f]+: 0f 1f 40 00 nopl 0x0\(%rax\)