0005-riscv-Resolve-symbols-directly-for-symbols-with-STO_.patch 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. From 66e355177a3c5f637852e47290878e06a7f95c32 Mon Sep 17 00:00:00 2001
  2. From: Hsiangkai Wang <kai.wang@sifive.com>
  3. Date: Tue, 18 Jan 2022 12:31:59 +0800
  4. Subject: [PATCH 05/19] riscv: Resolve symbols directly for symbols with
  5. STO_RISCV_VARIANT_CC.
  6. In some cases, we do not want to go through the resolver for function
  7. calls. For example, functions with vector arguments will use vector
  8. registers to pass arguments. In the resolver, we do not save/restore the
  9. vector argument registers for lazy binding efficiency. To avoid ruining
  10. the vector arguments, functions with vector arguments will not go
  11. through the resolver.
  12. To achieve the goal, we will annotate the function symbols with
  13. STO_RISCV_VARIANT_CC flag and add DT_RISCV_VARIANT_CC tag in the dynamic
  14. section. In the first pass on PLT relocations, we do not set up to call
  15. _dl_runtime_resolve. Instead, we resolve the functions directly.
  16. Signed-off-by: Hsiangkai Wang <kai.wang@sifive.com>
  17. Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
  18. ---
  19. elf/elf.h | 7 +++++++
  20. manual/platform.texi | 6 ++++++
  21. sysdeps/riscv/dl-dtprocnum.h | 21 +++++++++++++++++++++
  22. sysdeps/riscv/dl-machine.h | 26 ++++++++++++++++++++++++++
  23. 4 files changed, 60 insertions(+)
  24. create mode 100644 sysdeps/riscv/dl-dtprocnum.h
  25. diff --git a/elf/elf.h b/elf/elf.h
  26. index 7d1571043d..27009bdbc0 100644
  27. --- a/elf/elf.h
  28. +++ b/elf/elf.h
  29. @@ -3925,6 +3925,13 @@ enum
  30. #define R_TILEGX_NUM 130
  31. +/* RISC-V specific values for the Dyn d_tag field. */
  32. +#define DT_RISCV_VARIANT_CC (DT_LOPROC + 1)
  33. +#define DT_RISCV_NUM 2
  34. +
  35. +/* RISC-V specific values for the st_other field. */
  36. +#define STO_RISCV_VARIANT_CC 0x80
  37. +
  38. /* RISC-V ELF Flags */
  39. #define EF_RISCV_RVC 0x0001
  40. #define EF_RISCV_FLOAT_ABI 0x0006
  41. diff --git a/manual/platform.texi b/manual/platform.texi
  42. index d5fdc5bd05..a1a740f381 100644
  43. --- a/manual/platform.texi
  44. +++ b/manual/platform.texi
  45. @@ -121,6 +121,12 @@ when it is not allowed, the priority is set to medium.
  46. @node RISC-V
  47. @appendixsec RISC-V-specific Facilities
  48. +Functions that are lazily bound must be compatible with the standard calling
  49. +convention. When a function is annotated with STO_RISCV_VARIANT_CC, it means
  50. +this function is not compatible with the standard calling convention. The
  51. +dynamic linker will directly resolve it instead of using the lazy binding
  52. +mechanism.
  53. +
  54. Cache management facilities specific to RISC-V systems that implement the Linux
  55. ABI are declared in @file{sys/cachectl.h}.
  56. diff --git a/sysdeps/riscv/dl-dtprocnum.h b/sysdeps/riscv/dl-dtprocnum.h
  57. new file mode 100644
  58. index 0000000000..f189fd700a
  59. --- /dev/null
  60. +++ b/sysdeps/riscv/dl-dtprocnum.h
  61. @@ -0,0 +1,21 @@
  62. +/* Configuration of lookup functions. RISC-V version.
  63. + Copyright (C) 2019-2021 Free Software Foundation, Inc.
  64. + This file is part of the GNU C Library.
  65. +
  66. + The GNU C Library is free software; you can redistribute it and/or
  67. + modify it under the terms of the GNU Lesser General Public
  68. + License as published by the Free Software Foundation; either
  69. + version 2.1 of the License, or (at your option) any later version.
  70. +
  71. + The GNU C Library is distributed in the hope that it will be useful,
  72. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  73. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  74. + Lesser General Public License for more details.
  75. +
  76. + You should have received a copy of the GNU Lesser General Public
  77. + License along with the GNU C Library. If not, see
  78. + <https://www.gnu.org/licenses/>. */
  79. +
  80. +/* Number of extra dynamic section entries for this architecture. By
  81. + default there are none. */
  82. +#define DT_THISPROCNUM DT_RISCV_NUM
  83. diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
  84. index dfedc9801d..11523ae627 100644
  85. --- a/sysdeps/riscv/dl-machine.h
  86. +++ b/sysdeps/riscv/dl-machine.h
  87. @@ -53,6 +53,9 @@
  88. || (__WORDSIZE == 64 && (type) == R_RISCV_TLS_TPREL64))) \
  89. | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY)))
  90. +//* Translate a processor specific dynamic tag to the index in l_info array. */
  91. +#define DT_RISCV(x) (DT_RISCV_##x - DT_LOPROC + DT_NUM)
  92. +
  93. /* Return nonzero iff ELF header is compatible with the running host. */
  94. static inline int __attribute_used__
  95. elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
  96. @@ -281,6 +284,29 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
  97. /* Check for unexpected PLT reloc type. */
  98. if (__glibc_likely (r_type == R_RISCV_JUMP_SLOT))
  99. {
  100. + if (__glibc_unlikely (map->l_info[DT_RISCV (VARIANT_CC)] != NULL))
  101. + {
  102. + /* Check the symbol table for variant CC symbols. */
  103. + const Elf_Symndx symndx = ELFW(R_SYM) (reloc->r_info);
  104. + const ElfW(Sym) *symtab =
  105. + (const void *)D_PTR (map, l_info[DT_SYMTAB]);
  106. + const ElfW(Sym) *sym = &symtab[symndx];
  107. + if (__glibc_unlikely (sym->st_other & STO_RISCV_VARIANT_CC))
  108. + {
  109. + /* Avoid lazy resolution of variant CC symbols. */
  110. + const struct r_found_version *version = NULL;
  111. + if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
  112. + {
  113. + const ElfW(Half) *vernum =
  114. + (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
  115. + version = &map->l_versions[vernum[symndx] & 0x7fff];
  116. + }
  117. + elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
  118. + skip_ifunc);
  119. + return;
  120. + }
  121. + }
  122. +
  123. if (__glibc_unlikely (map->l_mach.plt == 0))
  124. {
  125. if (l_addr)
  126. --
  127. 2.25.1