From 3fa45fb168ceb04013d0dbd64d4a09d9cf284f63 Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Tue, 11 Jul 2023 11:21:18 +0800 Subject: [PATCH] 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. --- bfd/elfnn-loongarch.c | 67 +++++++++---------- .../ld-loongarch-elf/local-ifunc-reloc.d | 2 +- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index e9c408b2dff..70a666283af 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 diff --git a/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d index 29f2d3f36d3..bf73d9f2875 100644 --- a/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d +++ b/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d @@ -6,5 +6,5 @@ DYNAMIC RELOCATION RECORDS OFFSET +TYPE +VALUE -[[:xdigit:]]+ R_LARCH_IRELATIVE +\*ABS\*\+0x[[:xdigit:]]+ [[:xdigit:]]+ R_LARCH_64 +test +[[:xdigit:]]+ R_LARCH_IRELATIVE +\*ABS\*\+0x[[:xdigit:]]+ -- 2.30.2