[Git][ghc/ghc][wip/supersven/riscv64-ncg] 3 commits: Linker: Add local labels to the GOT

Sven Tennie (@supersven) gitlab at gitlab.haskell.org
Fri Mar 1 09:35:20 UTC 2024



Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC


Commits:
c0eb04d3 by Sven Tennie at 2024-03-01T10:01:58+01:00
Linker: Add local labels to the GOT

- - - - -
b5050132 by Sven Tennie at 2024-03-01T10:05:17+01:00
Linker: uint32_t addend

This seems to be a good representation:
- We're dealing with negative values as well (e.g. negative PC offset)
- We cannot deal with more than 20 + 12 = 32 bits

- - - - -
77b14c9a by Sven Tennie at 2024-03-01T10:12:03+01:00
Linker: Rework debug traces

- - - - -


2 changed files:

- rts/linker/elf_got.c
- rts/linker/elf_reloc_riscv64.c


Changes:

=====================================
rts/linker/elf_got.c
=====================================
@@ -9,22 +9,35 @@
  * Check if we need a global offset table slot for a
  * given symbol
  */
-bool
-needGotSlot(Elf_Sym * symbol) {
-    /* using global here should give an upper bound */
-    /* I don't believe we need to relocate STB_LOCAL
-     * symbols via the GOT; however I'm unsure about
-     * STB_WEAK.
-     *
-     * Any more restrictive filter here would result
-     * in a smaller GOT, which is preferable.
-     */
-    return ELF_ST_BIND(symbol->st_info) == STB_GLOBAL
-        || ELF_ST_BIND(symbol->st_info) == STB_WEAK
-        // Section symbols exist primarily for relocation
-        // and as such may need a GOT slot.
-        || ELF_ST_TYPE(symbol->st_info) == STT_SECTION;
-
+bool needGotSlot(Elf_Sym *symbol) {
+  /* using global here should give an upper bound */
+  /* I don't believe we need to relocate STB_LOCAL
+   * symbols via the GOT; however I'm unsure about
+   * STB_WEAK.
+   *
+   * Any more restrictive filter here would result
+   * in a smaller GOT, which is preferable.
+   */
+  return ELF_ST_BIND(symbol->st_info) == STB_GLOBAL ||
+         ELF_ST_BIND(symbol->st_info) == STB_WEAK
+         // Section symbols exist primarily for relocation
+         // and as such may need a GOT slot.
+         || ELF_ST_TYPE(symbol->st_info) == STT_SECTION
+#if defined(riscv64_HOST_ARCH)
+         // RISCV relies much on relocations and relaxations, leaving most of
+         // the addressing mode heavy lifting to the linker. We're using LA to
+         // load local label addresses (e.g. to access `*_closure`.) This
+         // implies (in the medany memory model) relocation via the GOT unless
+         // the instruction gets relaxed to e.g. direct or PC-relative
+         // addressing. So, for now, we've got the special case to add GOT
+         // symbols for all local labels here. This could be optimized by e.g.
+         // adding symbols to GOT on demand: I.e. if we spot a symbol related
+         // relocation which cannot be relaxed to direct or PC-relative
+         // addressing, then add it to GOT (otherwise not.)
+         || (ELF_ST_BIND(symbol->st_info) == STB_LOCAL &&
+             ELF_ST_TYPE(symbol->st_info) == STT_NOTYPE && symbol->st_name != 0)
+#endif
+      ;
 }
 
 bool


=====================================
rts/linker/elf_reloc_riscv64.c
=====================================
@@ -73,8 +73,8 @@ char *relocationTypeToString(Elf64_Xword type) {
 
 typedef uint64_t addr_t;
 
-int64_t decodeAddendRISCV64(Section *section, Elf_Rel *rel) STG_NORETURN;
-bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int64_t addend);
+int32_t decodeAddendRISCV64(Section *section, Elf_Rel *rel) STG_NORETURN;
+bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int32_t addend);
 
 /* regular instructions are 32bit */
 typedef uint32_t inst_t;
@@ -83,7 +83,7 @@ typedef uint32_t inst_t;
 typedef uint16_t cinst_t;
 
 // TODO: Decide which functions should be static and/or inlined.
-int64_t decodeAddendRISCV64(Section *section STG_UNUSED,
+int32_t decodeAddendRISCV64(Section *section STG_UNUSED,
                             Elf_Rel *rel STG_UNUSED) {
   debugBelch("decodeAddendRISCV64: Relocations with explicit addend are not "
              "supported.");
@@ -146,10 +146,11 @@ uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
          (extractBits(imm, 4, 0) << 7);
 }
 
-void setUType(inst_t *loc, uint32_t val) {
+void setUType(inst_t *loc, int32_t val) {
   const unsigned bits = 32;
-  uint64_t hi = val + 0x800;
+  uint32_t hi = val + 0x800;
   checkInt(loc, SignExtend64(hi, bits) >> 12, 20);
+  debugBelch("setUType: hi 0x%x val 0x%x\n", hi, val);
   write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000));
 }
 
@@ -227,16 +228,15 @@ void setCJType(cinst_t *loc, uint32_t val) {
   write16le(loc, insn);
 }
 
-bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int64_t addend) {
+bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int32_t addend) {
   addr_t P = (addr_t)((uint8_t *)section->start + rel->r_offset);
-  IF_DEBUG(
-      linker,
-      debugBelch(
-          "Relocation type %s 0x%lx (%lu) symbol 0x%lx addend 0x%lx (%lu / "
-          "%ld) P 0x%lx\n",
-          relocationTypeToString(rel->r_info), ELF64_R_TYPE(rel->r_info),
-          ELF64_R_TYPE(rel->r_info), ELF64_R_SYM(rel->r_info), addend, addend,
-          addend, P));
+  IF_DEBUG(linker,
+           debugBelch(
+               "Relocation type %s 0x%lx (%lu) symbol 0x%lx addend 0x%x (%u / "
+               "%d) P 0x%lx\n",
+               relocationTypeToString(rel->r_info), ELF64_R_TYPE(rel->r_info),
+               ELF64_R_TYPE(rel->r_info), ELF64_R_SYM(rel->r_info), addend,
+               addend, addend, P));
   switch (ELF64_R_TYPE(rel->r_info)) {
   case R_RISCV_32_PCREL:
   case R_RISCV_32:
@@ -352,7 +352,7 @@ bool encodeAddendRISCV64(Section *section, Elf_Rel *rel, int64_t addend) {
  * @param addend  The existing addend. Either explicit or implicit.
  * @return The new computed addend.
  */
-int64_t computeAddend(Section *section, Elf_Rel *rel, ElfSymbol *symbol,
+int32_t computeAddend(Section *section, Elf_Rel *rel, ElfSymbol *symbol,
                       int64_t addend, ObjectCode *oc) {
 
   /* Position where something is relocated */
@@ -438,8 +438,11 @@ int64_t computeAddend(Section *section, Elf_Rel *rel, ElfSymbol *symbol,
                        relocationTypeToString(rel->r_info), P, S, symbol->name,
                        relocationTypeToString(rel_prime->r_info), P_prime,
                        symbol_prime->addr, symbol_prime->name));
-          return computeAddend(targetSection, (Elf_Rel *)rel_prime,
-                               symbol_prime, addend_prime, oc);
+          int32_t result = computeAddend(targetSection, (Elf_Rel *)rel_prime,
+                                         symbol_prime, addend_prime, oc);
+          IF_DEBUG(linker,
+            debugBelch("Result of computeAddend: 0x%x (%d)\n", result, result));
+          return result;
         }
       }
     }
@@ -462,10 +465,9 @@ int64_t computeAddend(Section *section, Elf_Rel *rel, ElfSymbol *symbol,
         abort(/* could not find or make stub */);
       }
     }
-    IF_DEBUG(
-        linker,
-        debugBelch("S = 0x%lx  A = 0x%lx  P = 0x%lx  (S + A) - P = 0x%lx \n", S,
-                   A, P, (S + A) - P));
+    IF_DEBUG(linker, debugBelch("R_RISCV_CALL_PLT: S = 0x%lx A = 0x%lx P = "
+                                "0x%lx (S + A) - P = 0x%lx \n",
+                                S, A, P, (S + A) - P));
     return (S + A) - P;
   }
   case R_RISCV_ADD8:
@@ -504,9 +506,11 @@ int64_t computeAddend(Section *section, Elf_Rel *rel, ElfSymbol *symbol,
     return 0;
   case R_RISCV_32_PCREL:
     return S + A - P;
-  case R_RISCV_GOT_HI20:
-    // reduced G + GOT to GOT_S - This might be wrong!
+  case R_RISCV_GOT_HI20: {
+    // Ensure that the GOT entry is set up.
+    CHECK(0x0 != GOT_S);
     return GOT_S + A - P;
+  }
   default:
     debugBelch("Unimplemented relocation: 0x%lx\n (%lu)",
                ELF64_R_TYPE(rel->r_info), ELF64_R_TYPE(rel->r_info));



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c36bf10472d3243b25c4480dad55b9c7c7fb865c...77b14c9a1db2bf15b4a46443f7c5eb5e70257cd1

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c36bf10472d3243b25c4480dad55b9c7c7fb865c...77b14c9a1db2bf15b4a46443f7c5eb5e70257cd1
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240301/f95d4441/attachment-0001.html>


More information about the ghc-commits mailing list