diff options
author | Hsiangkai Wang <kai.wang@sifive.com> | 2023-03-15 00:25:12 +0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2023-04-28 07:02:42 -0700 |
commit | 117e8b341c5c0ace8d65feeef136fececb3fdc9c (patch) | |
tree | 38aa30211c5aee3e6a1f15d3fec86bf18508608c /sysdeps/riscv | |
parent | 2fa7fd1af733e323fa90d059e2ba60ec965d2cbb (diff) | |
download | glibc-117e8b341c5c0ace8d65feeef136fececb3fdc9c.zip glibc-117e8b341c5c0ace8d65feeef136fececb3fdc9c.tar.gz glibc-117e8b341c5c0ace8d65feeef136fececb3fdc9c.tar.bz2 |
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>
Diffstat (limited to 'sysdeps/riscv')
-rw-r--r-- | sysdeps/riscv/dl-dtprocnum.h | 21 | ||||
-rw-r--r-- | sysdeps/riscv/dl-machine.h | 26 |
2 files changed, 47 insertions, 0 deletions
diff --git a/sysdeps/riscv/dl-dtprocnum.h b/sysdeps/riscv/dl-dtprocnum.h new file mode 100644 index 0000000..281c5aa --- /dev/null +++ b/sysdeps/riscv/dl-dtprocnum.h @@ -0,0 +1,21 @@ +/* Configuration of lookup functions. RISC-V version. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +/* Number of extra dynamic section entries for this architecture. By + default there are none. */ +#define DT_THISPROCNUM DT_RISCV_NUM diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index c0c9bd9..0e6c0bb 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -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) |