aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfnn-loongarch.c
diff options
context:
space:
mode:
authormengqinggang <mengqinggang@loongson.cn>2024-10-10 16:23:30 +0800
committerliuzhensong <liuzhensong@loongson.cn>2024-10-15 14:26:17 +0800
commita104f0a3e62031d2a5aabfe9e82f55158647f444 (patch)
treed3bbe3b8cf84369c4ae025c380160e83f8d1359c /bfd/elfnn-loongarch.c
parent5c3d09c1855b948dd43b9f5f8b3d8aa254d75f43 (diff)
downloadbinutils-a104f0a3e62031d2a5aabfe9e82f55158647f444.zip
binutils-a104f0a3e62031d2a5aabfe9e82f55158647f444.tar.gz
binutils-a104f0a3e62031d2a5aabfe9e82f55158647f444.tar.bz2
LoongArch: Add more relaxation support for call36
Add relaxation support for call36 that jump to PLT entry. Add relaxation support for call36 with IFUNC symbol. Add relaxation support for call36 that jump to undefweak symbol. For undefweak symbol, it can always be relaxed if it have no PLT entry. Because we set the address of undefweak symbol without PLT entry to PC like relocate_section.
Diffstat (limited to 'bfd/elfnn-loongarch.c')
-rw-r--r--bfd/elfnn-loongarch.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index d683fd3..9c3cd67 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5435,7 +5435,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
+ r_symndx;
- if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
continue;
/* Only TLS instruction sequences that are accompanied by
@@ -5468,8 +5469,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
}
else
{
- /* Disable the relaxation for ifunc. */
- if (h != NULL && h->type == STT_GNU_IFUNC)
+ if (h != NULL && h->type == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
continue;
/* The GOT entry of tls symbols must in current execute file or
@@ -5486,6 +5487,20 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
&& GOT_TLS_GD_BOTH_P (tls_type))
symval += 2 * GOT_ENTRY_SIZE;
}
+ else if (h->plt.offset != MINUS_ONE)
+ {
+ sym_sec = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ symval = h->plt.offset;
+ }
+ /* Like loongarch_elf_relocate_section, set relocation(offset) to 0.
+ Undefweak for other relocations handing in the future. */
+ else if (h->root.type == bfd_link_hash_undefweak
+ && !h->root.linker_def
+ && r_type == R_LARCH_CALL36)
+ {
+ sym_sec = sec;
+ symval = rel->r_offset;
+ }
else if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section != NULL