diff options
author | mengqinggang <mengqinggang@loongson.cn> | 2024-10-10 16:23:30 +0800 |
---|---|---|
committer | liuzhensong <liuzhensong@loongson.cn> | 2024-10-15 14:26:17 +0800 |
commit | a104f0a3e62031d2a5aabfe9e82f55158647f444 (patch) | |
tree | d3bbe3b8cf84369c4ae025c380160e83f8d1359c /bfd/elfnn-loongarch.c | |
parent | 5c3d09c1855b948dd43b9f5f8b3d8aa254d75f43 (diff) | |
download | binutils-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.c | 21 |
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 |