diff options
Diffstat (limited to 'lld/ELF/Arch/LoongArch.cpp')
-rw-r--r-- | lld/ELF/Arch/LoongArch.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index 9dc99e573d41..1c3e015efc16 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -165,7 +165,6 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) { result -= 0x10000'0000; else if (!negativeA && negativeB) result += 0x10000'0000; - return result; } @@ -444,10 +443,12 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, case R_LARCH_TLS_LE64_LO20: case R_LARCH_TLS_LE64_HI12: return R_TPREL; + case R_LARCH_ADD6: case R_LARCH_ADD8: case R_LARCH_ADD16: case R_LARCH_ADD32: case R_LARCH_ADD64: + case R_LARCH_SUB6: case R_LARCH_SUB8: case R_LARCH_SUB16: case R_LARCH_SUB32: @@ -457,6 +458,7 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, return R_RISCV_ADD; case R_LARCH_32_PCREL: case R_LARCH_64_PCREL: + case R_LARCH_PCREL20_S2: return R_PC; case R_LARCH_B16: case R_LARCH_B21: @@ -564,6 +566,12 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, write64le(loc, val); return; + case R_LARCH_PCREL20_S2: + checkInt(loc, val, 22, rel); + checkAlignment(loc, val, 4, rel); + write32le(loc, setJ20(read32le(loc), val >> 2)); + return; + case R_LARCH_B16: checkInt(loc, val, 18, rel); checkAlignment(loc, val, 4, rel); @@ -643,6 +651,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, write32le(loc, setK12(read32le(loc), extractBits(val, 63, 52))); return; + case R_LARCH_ADD6: + *loc = (*loc & 0xc0) | ((*loc + val) & 0x3f); + return; case R_LARCH_ADD8: *loc += val; return; @@ -655,6 +666,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_ADD64: write64le(loc, read64le(loc) + val); return; + case R_LARCH_SUB6: + *loc = (*loc & 0xc0) | ((*loc - val) & 0x3f); + return; case R_LARCH_SUB8: *loc -= val; return; |