mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
riscv: Resolve symbols directly for symbols with STO_RISCV_VARIANT_CC.
In some cases, we do not want to go through the resolver for function calls. For example, functions with vector arguments will use vector registers to pass arguments. In the resolver, we do not save/restore the vector argument registers for lazy binding efficiency. To avoid ruining the vector arguments, functions with vector arguments will not go through the resolver. To achieve the goal, we will annotate the function symbols with STO_RISCV_VARIANT_CC flag and add DT_RISCV_VARIANT_CC tag in the dynamic section. In the first pass on PLT relocations, we do not set up to call _dl_runtime_resolve. Instead, we resolve the functions directly. Signed-off-by: Hsiangkai Wang <kai.wang@sifive.com> Signed-off-by: Vincent Chen <vincent.chen@sifive.com> Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com> Acked-by: Palmer Dabbelt <palmer@rivosinc.com> Link: https://inbox.sourceware.org/libc-alpha/20230314162512.35802-1-kito.cheng@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
committed by
Palmer Dabbelt
parent
2fa7fd1af7
commit
117e8b341c
@ -53,6 +53,9 @@
|
||||
|| (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64))) \
|
||||
| (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
|
||||
|
||||
//* Translate a processor specific dynamic tag to the index in l_info array. */
|
||||
#define DT_RISCV(x) (DT_RISCV_##x - DT_LOPROC + DT_NUM)
|
||||
|
||||
/* Return nonzero iff ELF header is compatible with the running host. */
|
||||
static inline int __attribute_used__
|
||||
elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
|
||||
@ -281,6 +284,29 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||
/* Check for unexpected PLT reloc type. */
|
||||
if (__glibc_likely (r_type == R_RISCV_JUMP_SLOT))
|
||||
{
|
||||
if (__glibc_unlikely (map->l_info[DT_RISCV (VARIANT_CC)] != NULL))
|
||||
{
|
||||
/* Check the symbol table for variant CC symbols. */
|
||||
const Elf_Symndx symndx = ELFW(R_SYM) (reloc->r_info);
|
||||
const ElfW(Sym) *symtab =
|
||||
(const void *)D_PTR (map, l_info[DT_SYMTAB]);
|
||||
const ElfW(Sym) *sym = &symtab[symndx];
|
||||
if (__glibc_unlikely (sym->st_other & STO_RISCV_VARIANT_CC))
|
||||
{
|
||||
/* Avoid lazy resolution of variant CC symbols. */
|
||||
const struct r_found_version *version = NULL;
|
||||
if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
version = &map->l_versions[vernum[symndx] & 0x7fff];
|
||||
}
|
||||
elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
|
||||
skip_ifunc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (__glibc_unlikely (map->l_mach.plt == 0))
|
||||
{
|
||||
if (l_addr)
|
||||
|
Reference in New Issue
Block a user