diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2012-12-16 20:31:00 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2012-12-16 20:31:00 +0000 |
commit | 31feadad7e17aa2c48ff1e966284eb0d91083735 (patch) | |
tree | 62598f2b820f0b94621d7b11436f36ecfbaf3b92 /bfd | |
parent | 61c50ee9750554a573e542359ec2d69234478e48 (diff) | |
download | gdb-31feadad7e17aa2c48ff1e966284eb0d91083735.tar.gz |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 8 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 8 |
3 files changed, 18 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 87cc9d7c119..070acb49e6d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,13 @@ +2012-12-16 H.J. Lu <hongjiu.lu@intel.com> + + 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 <tromey@redhat.com> - * elf.c (elfcore_grok_note) <NT_FILE>: New case. + * elf.c (elfcore_grok_note) <NT_FILE>: New case. 2012-12-13 H.J. Lu <hongjiu.lu@intel.com> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index bb41302b8e6..a188cec2b88 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 ec38ddc1d19..283681c466b 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; |