diff options
author | mengqinggang <mengqinggang@loongson.cn> | 2023-07-11 11:21:18 +0800 |
---|---|---|
committer | liuzhensong <liuzhensong@loongson.cn> | 2023-07-24 11:22:42 +0800 |
commit | 3fa45fb168ceb04013d0dbd64d4a09d9cf284f63 (patch) | |
tree | a8ce8d0c9e67ede1b245b8321315f5150b91dfcc /bfd/elfnn-loongarch.c | |
parent | a38b0c05b6e9444d94e8a4dd090584a8dcc313ad (diff) | |
download | gdb-3fa45fb168ceb04013d0dbd64d4a09d9cf284f63.zip gdb-3fa45fb168ceb04013d0dbd64d4a09d9cf284f63.tar.gz gdb-3fa45fb168ceb04013d0dbd64d4a09d9cf284f63.tar.bz2 |
LoongArch: ld: Simplify inserting IRELATIVE relocations to .rela.dyn
In LoongArch, the R_LARCH_IRELATIVE relocations for local ifunc symbols are
in .rela.dyn. Before, this is done by loongarch_elf_finish_dynamic_sections.
But this function is called after elf_link_sort_relocs, it need to find a
null slot to insert IRELATIVE relocation.
Now, it is processed by elf_loongarch_output_arch_local_syms before
elf_link_sort_relocs, just need to call loongarch_elf_append_rela to
insert IRELATIVE relocation.
bfd/ChangeLog:
* elfnn-loongarch.c (elfNN_allocate_local_ifunc_dynrelocs): Return
type change to int.
(loongarch_elf_size_dynamic_sections): Delete (void *).
(loongarch_elf_finish_dynamic_symbol): Use loongarch_elf_append_rela
insert IRELATIVE relocation to .rela.dyn.
(elfNN_loongarch_finish_local_dynamic_symbol): Return type change to
int.
(loongarch_elf_finish_dynamic_sections): Delete process of local
ifunc symbols.
(elf_backend_output_arch_local_syms): New.
ld/ChangeLog:
* testsuite/ld-loongarch-elf/local-ifunc-reloc.d: Regenerated.
Diffstat (limited to 'bfd/elfnn-loongarch.c')
-rw-r--r-- | bfd/elfnn-loongarch.c | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index e9c408b..70a6662 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -1538,7 +1538,7 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Allocate space in .plt, .got and associated reloc sections for ifunc dynamic relocs. */ -static bool +static int elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf) { struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; @@ -1700,7 +1700,7 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd, /* Allocate .plt and .got entries, and space for local ifunc symbols. */ htab_traverse (htab->loc_hash_table, - (void *) elfNN_allocate_local_ifunc_dynrelocs, info); + elfNN_allocate_local_ifunc_dynrelocs, info); /* Don't allocate .got.plt section if there are no PLT. */ if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE @@ -4040,12 +4040,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, { struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - asection *rela_dyn = bfd_get_section_by_name (output_bfd, ".rela.dyn"); - struct bfd_link_order *lo = NULL; - Elf_Internal_Rela *slot = NULL, *last_slot = NULL; - - if (rela_dyn) - lo = rela_dyn->map_head.link_order; if (h->plt.offset != MINUS_ONE) { @@ -4055,7 +4049,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, uint32_t plt_entry[PLT_ENTRY_INSNS]; bfd_byte *loc; Elf_Internal_Rela rela; - asection *rela_sec = NULL; if (htab->elf.splt) { @@ -4113,26 +4106,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, + h->root.u.def.section->output_section->vma + h->root.u.def.section->output_offset); - /* Find the space after dyn sort. */ - while (slot == last_slot || slot->r_offset != 0) - { - if (slot != last_slot) - { - slot++; - continue; - } - - BFD_ASSERT (lo != NULL); - rela_sec = lo->u.indirect.section; - lo = lo->next; - - slot = (Elf_Internal_Rela *)rela_sec->contents; - last_slot = (Elf_Internal_Rela *)(rela_sec->contents + - rela_sec->size); - } - - bed->s->swap_reloca_out (output_bfd, &rela, (bfd_byte *)slot); - rela_sec->reloc_count++; + loongarch_elf_append_rela (output_bfd, relplt, &rela); } else { @@ -4299,7 +4273,7 @@ loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj, /* Finish up local dynamic symbol handling. We set the contents of various dynamic sections here. */ -static bool +static int elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf) { struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; @@ -4308,6 +4282,33 @@ elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf) return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL); } +/* Value of struct elf_backend_data->elf_backend_output_arch_local_syms, + this function is called before elf_link_sort_relocs. + So relocation R_LARCH_IRELATIVE for local ifunc can be append to + .rela.dyn (.rela.got) by loongarch_elf_append_rela. */ + +static bool +elf_loongarch_output_arch_local_syms + (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + void *flaginfo ATTRIBUTE_UNUSED, + int (*func) (void *, const char *, + Elf_Internal_Sym *, + asection *, + struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) +{ + struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); + if (htab == NULL) + return false; + + /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ + htab_traverse (htab->loc_hash_table, + elfNN_loongarch_finish_local_dynamic_symbol, + info); + + return true; +} + static bool loongarch_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) @@ -4386,10 +4387,6 @@ loongarch_elf_finish_dynamic_sections (bfd *output_bfd, elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; } - /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ - htab_traverse (htab->loc_hash_table, - (void *) elfNN_loongarch_finish_local_dynamic_symbol, info); - return true; } @@ -4654,6 +4651,8 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h) #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections #define elf_backend_relocate_section loongarch_elf_relocate_section #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol +#define elf_backend_output_arch_local_syms \ + elf_loongarch_output_arch_local_syms #define elf_backend_finish_dynamic_sections \ loongarch_elf_finish_dynamic_sections #define elf_backend_object_p loongarch_elf_object_p |