From: H.J. Lu Date: Sun, 16 Dec 2012 20:31:08 +0000 (+0000) Subject: Also check local IFUNC references X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=73bcf2338555a1d0b2e5e1eaaecd263498d19967;p=deliverable%2Fbinutils-gdb.git Also check local IFUNC references bfd/ PR ld/14968 * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Also check local IFUNC references. * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise. ld/testsuite/ PR ld/14968 * ld-ifunc/ifunc-18a-i386.d: New file. * ld-ifunc/ifunc-18a-x86-64.d: Likewise. * ld-ifunc/ifunc-18a.s: Likewise. * ld-ifunc/ifunc-18b-i386.d: Likewise. * ld-ifunc/ifunc-18b-x86-64.d: Likewise. * ld-ifunc/ifunc-18b.s: Likewise. * ld-ifunc/ifunc-19a-i386.d: Likewise. * ld-ifunc/ifunc-19a-x86-64.d: Likewise. * ld-ifunc/ifunc-19a.s: Likewise. * ld-ifunc/ifunc-19b-i386.d: Likewise. * ld-ifunc/ifunc-19b-x86-64.d: Likewise. * ld-ifunc/ifunc-19b.s: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 87cc9d7c11..070acb49e6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,13 @@ +2012-12-16 H.J. Lu + + PR ld/14968 + * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Also check + local IFUNC references. + * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise. + 2012-12-14 Tom Tromey - * elf.c (elfcore_grok_note) : New case. + * elf.c (elfcore_grok_note) : New case. 2012-12-13 H.J. Lu diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index bb41302b8e..a188cec2b8 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2072,11 +2072,12 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, /* STT_GNU_IFUNC symbol must go through PLT. */ if (h->type == STT_GNU_IFUNC) { - /* Check local STT_GNU_IFUNC calls. */ + /* All local STT_GNU_IFUNC references must be treate as local + calls via local PLT. */ if (h->ref_regular && SYMBOL_CALLS_LOCAL (info, h)) { - bfd_size_type pc_count = 0; + bfd_size_type pc_count = 0, count = 0; struct elf_dyn_relocs **pp; eh = (struct elf_i386_link_hash_entry *) h; @@ -2085,13 +2086,14 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, pc_count += p->pc_count; p->count -= p->pc_count; p->pc_count = 0; + count += p->count; if (p->count == 0) *pp = p->next; else pp = &p->next; } - if (pc_count) + if (pc_count || count) { h->needs_plt = 1; h->plt.refcount += 1; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index ec38ddc1d1..283681c466 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2140,11 +2140,12 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, /* STT_GNU_IFUNC symbol must go through PLT. */ if (h->type == STT_GNU_IFUNC) { - /* Check local STT_GNU_IFUNC calls. */ + /* All local STT_GNU_IFUNC references must be treate as local + calls via local PLT. */ if (h->ref_regular && SYMBOL_CALLS_LOCAL (info, h)) { - bfd_size_type pc_count = 0; + bfd_size_type pc_count = 0, count = 0; struct elf_dyn_relocs **pp; eh = (struct elf_x86_64_link_hash_entry *) h; @@ -2153,13 +2154,14 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, pc_count += p->pc_count; p->count -= p->pc_count; p->pc_count = 0; + count += p->count; if (p->count == 0) *pp = p->next; else pp = &p->next; } - if (pc_count) + if (pc_count || count) { h->needs_plt = 1; h->plt.refcount += 1; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 7ae40140df..7a2cb17f2a 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2012-12-16 H.J. Lu + + PR ld/14968 + * ld-ifunc/ifunc-18a-i386.d: New file. + * ld-ifunc/ifunc-18a-x86-64.d: Likewise. + * ld-ifunc/ifunc-18a.s: Likewise. + * ld-ifunc/ifunc-18b-i386.d: Likewise. + * ld-ifunc/ifunc-18b-x86-64.d: Likewise. + * ld-ifunc/ifunc-18b.s: Likewise. + * ld-ifunc/ifunc-19a-i386.d: Likewise. + * ld-ifunc/ifunc-19a-x86-64.d: Likewise. + * ld-ifunc/ifunc-19a.s: Likewise. + * ld-ifunc/ifunc-19b-i386.d: Likewise. + * ld-ifunc/ifunc-19b-x86-64.d: Likewise. + * ld-ifunc/ifunc-19b.s: Likewise. + 2012-12-15 Thomas Schwinge * ld-elf/elf.exp (stack exec, stack size): Run for any GNU target. diff --git a/ld/testsuite/ld-ifunc/ifunc-18a-i386.d b/ld/testsuite/ld-ifunc/ifunc-18a-i386.d new file mode 100644 index 0000000000..10490b112b --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18a-i386.d @@ -0,0 +1,15 @@ +#source: ifunc-18a.s +#source: ifunc-18b.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* + +Relocation section '.rel.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d new file mode 100644 index 0000000000..0d600eb382 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18a-x86-64.d @@ -0,0 +1,15 @@ +#source: ifunc-18a.s +#source: ifunc-18b.s +#as: --64 +#ld: -shared -melf_x86_64 -z nocombreloc +#readelf: -r --wide +#target: x86_64-*-* + +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* + +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18a.s b/ld/testsuite/ld-ifunc/ifunc-18a.s new file mode 100644 index 0000000000..c29c121c23 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18a.s @@ -0,0 +1,5 @@ + .section .data.rel,"aw",@progbits + .globl foo_ptrt + .type foo_ptr, @object +foo_ptr: + .dc.a foo diff --git a/ld/testsuite/ld-ifunc/ifunc-18b-i386.d b/ld/testsuite/ld-ifunc/ifunc-18b-i386.d new file mode 100644 index 0000000000..a5eda9495a --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18b-i386.d @@ -0,0 +1,15 @@ +#source: ifunc-18b.s +#source: ifunc-18a.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* + +Relocation section '.rel.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d new file mode 100644 index 0000000000..8dfebfb8e9 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18b-x86-64.d @@ -0,0 +1,15 @@ +#source: ifunc-18b.s +#source: ifunc-18a.s +#as: --64 +#ld: -shared -melf_x86_64 -z nocombreloc +#readelf: -r --wide +#target: x86_64-*-* + +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* + +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-18b.s b/ld/testsuite/ld-ifunc/ifunc-18b.s new file mode 100644 index 0000000000..fece413189 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-18b.s @@ -0,0 +1,15 @@ + .text + .type foo, %gnu_indirect_function + .hidden foo + .globl foo +foo: + ret + .size foo, .-foo + .globl bar +bar: + jmp foo1@PLT + ret + .size bar, .-bar + .hidden foo1 + .globl foo1 + foo1 = foo diff --git a/ld/testsuite/ld-ifunc/ifunc-19a-i386.d b/ld/testsuite/ld-ifunc/ifunc-19a-i386.d new file mode 100644 index 0000000000..8319bfc74c --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19a-i386.d @@ -0,0 +1,14 @@ +#source: ifunc-19a.s +#source: ifunc-19b.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* + +Relocation section '.rel.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-19a-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-19a-x86-64.d new file mode 100644 index 0000000000..fe576d2d33 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19a-x86-64.d @@ -0,0 +1,14 @@ +#source: ifunc-19a.s +#source: ifunc-19b.s +#as: --64 +#ld: -shared -melf_x86_64 -z nocombreloc +#readelf: -r --wide +#target: x86_64-*-* + +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* + +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-19a.s b/ld/testsuite/ld-ifunc/ifunc-19a.s new file mode 100644 index 0000000000..3a3d0cd668 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19a.s @@ -0,0 +1,5 @@ + .section .data.rel,"aw",@progbits + .globl foo_ptrt + .type foo_ptr, @object +foo_ptr: + .dc.a foo1 diff --git a/ld/testsuite/ld-ifunc/ifunc-19b-i386.d b/ld/testsuite/ld-ifunc/ifunc-19b-i386.d new file mode 100644 index 0000000000..5bb81706aa --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19b-i386.d @@ -0,0 +1,14 @@ +#source: ifunc-19b.s +#source: ifunc-19a.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +Relocation section '.rel.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* + +Relocation section '.rel.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]* diff --git a/ld/testsuite/ld-ifunc/ifunc-19b-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-19b-x86-64.d new file mode 100644 index 0000000000..35fa3285fd --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19b-x86-64.d @@ -0,0 +1,14 @@ +#source: ifunc-19b.s +#source: ifunc-19a.s +#as: --64 +#ld: -shared -melf_x86_64 -z nocombreloc +#readelf: -r --wide +#target: x86_64-*-* + +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* + +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-ifunc/ifunc-19b.s b/ld/testsuite/ld-ifunc/ifunc-19b.s new file mode 100644 index 0000000000..fece413189 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-19b.s @@ -0,0 +1,15 @@ + .text + .type foo, %gnu_indirect_function + .hidden foo + .globl foo +foo: + ret + .size foo, .-foo + .globl bar +bar: + jmp foo1@PLT + ret + .size bar, .-bar + .hidden foo1 + .globl foo1 + foo1 = foo