summaryrefslogtreecommitdiff
path: root/bfd/elf-ifunc.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2011-01-07 03:34:20 +0000
committerH.J. Lu <hjl.tools@gmail.com>2011-01-07 03:34:20 +0000
commit7228e01ef15d5319f1bba4ab07e104711e28b196 (patch)
tree37fb30d8ac698b35a073e1f24a2042622f12f9c3 /bfd/elf-ifunc.c
parente2e7e866cdb3f74e66495524cddd14bd14e63ddc (diff)
downloadbinutils-redhat-7228e01ef15d5319f1bba4ab07e104711e28b196.tar.gz
Optimize _bfd_elf_allocate_ifunc_dyn_relocs.
2011-01-06 H.J. Lu <hongjiu.lu@intel.com> * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Optimized.
Diffstat (limited to 'bfd/elf-ifunc.c')
-rw-r--r--bfd/elf-ifunc.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c
index 17b23c2ffc..81429b8433 100644
--- a/bfd/elf-ifunc.c
+++ b/bfd/elf-ifunc.c
@@ -194,25 +194,20 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
where it is marked with regular reference, but not non-GOT
reference. It may happen if we didn't see STT_GNU_IFUNC
symbol at the time when checking relocations. */
- bfd_size_type count = 0;
-
if (info->shared
&& !h->non_got_ref
&& h->ref_regular)
- {
- for (p = *head; p != NULL; p = p->next)
- count += p->count;
- if (count != 0)
- h->non_got_ref = 1;
- }
+ for (p = *head; p != NULL; p = p->next)
+ if (p->count)
+ {
+ h->non_got_ref = 1;
+ goto keep;
+ }
- if (count == 0)
- {
- h->got = htab->init_got_offset;
- h->plt = htab->init_plt_offset;
- *head = NULL;
- return TRUE;
- }
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return TRUE;
}
/* Return and discard space for dynamic relocations against it if
@@ -228,6 +223,7 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
return TRUE;
}
+keep:
bed = get_elf_backend_data (info->output_bfd);
if (bed->rela_plts_and_copies_p)
sizeof_reloc = bed->s->sizeof_rela;
@@ -277,10 +273,20 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
*head = NULL;
/* Finally, allocate space. */
- for (p = *head; p != NULL; p = p->next)
- htab->irelifunc->size += p->count * sizeof_reloc;
+ p = *head;
+ if (p != NULL)
+ {
+ bfd_size_type count = 0;
+ do
+ {
+ count += p->count;
+ p = p->next;
+ }
+ while (p != NULL);
+ htab->irelifunc->size += count * sizeof_reloc;
+ }
- /* For STT_GNU_IFUNC symbol, .got.plt has the real function addres
+ /* For STT_GNU_IFUNC symbol, .got.plt has the real function address
and .got has the PLT entry adddress. We will load the GOT entry
with the PLT entry in finish_dynamic_symbol if it is used. For
branch, it uses .got.plt. For symbol value,