aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-12-13 21:07:16 +0000
committerH.J. Lu <hjl.tools@gmail.com>2012-12-13 21:07:16 +0000
commit5ca5bb354599855357bd35d99dfa07a729f91095 (patch)
treec5d3a394c93f8220ec8ae744b1c20f534910c52d /bfd/elf64-x86-64.c
parente780d813de745dfe6f2403226fec488d30d372f5 (diff)
downloadgdb-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.c32
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)
{