[lld] [lld][LoongArch] Handle extreme code model relocs according to psABI v2.30 (PR #73387)

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 25 20:15:00 PST 2023


================
@@ -82,11 +82,29 @@ static uint64_t getLoongArchPage(uint64_t p) {
 static uint32_t lo12(uint32_t val) { return val & 0xfff; }
 
 // Calculate the adjusted page delta between dest and PC.
-uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
-  // Compensate all the sign-extensions is a bit complicated. Just use the same
-  // logic as bfd and mold. Note that this algorithm assumes those four
-  // instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same 4K-page.
-  uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
+uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) {
+  // Note that if the sequence being relocated is `pcalau12i + addi.d + lu32i.d
+  // + lu52i.d`, they must be adjancent so that we can infer the PC of
+  // `pcalau12i` when calculating the page delta for the other two instructions
+  // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit
+  // complicated. Just use psABI recommended algorithm.
+  uint64_t pcalau12i_pc;
+  switch (type) {
+  case R_LARCH_PCALA64_LO20:
+  case R_LARCH_GOT64_PC_LO20:
----------------
rui314 wrote:

As per https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc, `R_LARCH_GOT64_PC_LO20` is defined to be as follows:

```
(*(uint32_t *) PC) [24 ... 5] = (((GOT+G+0x8000'0000 + (((GOT+G) & 0x800) ? (0x1000-0x1'0000'0000) : 0)) & ~0xfff) - (PC & ~0xfff)) [51 ... 32]
```

The expression doesn't have `- 8`. Is this an error in the spec or a bug in this patch?

So is all the other relocs except `R_LARCH_PCALA64_LO20` and `R_LARCH_PCALA64_HI12`.

https://github.com/llvm/llvm-project/pull/73387


More information about the llvm-commits mailing list