diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2012-12-13 21:07:16 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2012-12-13 21:07:16 +0000 |
commit | 5ca5bb354599855357bd35d99dfa07a729f91095 (patch) | |
tree | c5d3a394c93f8220ec8ae744b1c20f534910c52d /bfd/elf64-x86-64.c | |
parent | e780d813de745dfe6f2403226fec488d30d372f5 (diff) | |
download | gdb-5ca5bb354599855357bd35d99dfa07a729f91095.zip gdb-5ca5bb354599855357bd35d99dfa07a729f91095.tar.gz gdb-5ca5bb354599855357bd35d99dfa07a729f91095.tar.bz2 |
Check local IFUNC calls
bfd/
2012-12-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14956
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Check local
IFUNC calls.
* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
ld/testsuite/
2012-12-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14956
* ld-ifunc/ifunc-14-i386.d: Renamed to ...
* ld-ifunc/ifunc-14a-i386.d: This.
* ld-ifunc/ifunc-14-x86-64.d: Renamed to ...
* ld-ifunc/ifunc-14a-x86-64.d: This.
* ld-ifunc/ifunc-14b-i386.d: New file.
* ld-ifunc/ifunc-14b-x86-64.d: Likewise.
* ld-ifunc/ifunc-14c-i386.d: Likewise.
* ld-ifunc/ifunc-14c-x86-64.d: Likewise.
* ld-ifunc/ifunc-14d-i386.d: Likewise.
* ld-ifunc/ifunc-14d-x86-64.d: Likewise.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index d58384f..ec38ddc 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2134,10 +2134,39 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, { struct elf_x86_64_link_hash_table *htab; asection *s; + struct elf_x86_64_link_hash_entry *eh; + struct elf_dyn_relocs *p; /* STT_GNU_IFUNC symbol must go through PLT. */ if (h->type == STT_GNU_IFUNC) { + /* Check local STT_GNU_IFUNC calls. */ + if (h->ref_regular + && SYMBOL_CALLS_LOCAL (info, h)) + { + bfd_size_type pc_count = 0; + struct elf_dyn_relocs **pp; + + eh = (struct elf_x86_64_link_hash_entry *) h; + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + pc_count += p->pc_count; + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + + if (pc_count) + { + h->needs_plt = 1; + h->plt.refcount += 1; + h->non_got_ref = 1; + } + } + if (h->plt.refcount <= 0) { h->plt.offset = (bfd_vma) -1; @@ -2214,9 +2243,6 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, if (ELIMINATE_COPY_RELOCS) { - struct elf_x86_64_link_hash_entry * eh; - struct elf_dyn_relocs *p; - eh = (struct elf_x86_64_link_hash_entry *) h; for (p = eh->dyn_relocs; p != NULL; p = p->next) { |