diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2011-01-07 03:34:23 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2011-01-07 03:34:23 +0000 |
commit | 7be867377db57e62bc2dc7f0756b484bdac30fda (patch) | |
tree | 78a1bba1c9fc89d1f39c78fb3e74d09a0fa6d97c /bfd/elf-ifunc.c | |
parent | fb03cb59c1bb68a7a589d2b5a9ade2dc9d5515c0 (diff) | |
download | gdb-7be867377db57e62bc2dc7f0756b484bdac30fda.zip gdb-7be867377db57e62bc2dc7f0756b484bdac30fda.tar.gz gdb-7be867377db57e62bc2dc7f0756b484bdac30fda.tar.bz2 |
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.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c index 17b23c2..81429b8 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, |