diff options
Diffstat (limited to 'lld/ELF/Arch/RISCV.cpp')
-rw-r--r-- | lld/ELF/Arch/RISCV.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index ca4178b18e76..dad23fff91c1 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -24,8 +24,10 @@ class RISCV final : public TargetInfo { public: RISCV(); uint32_t calcEFlags() const override; + int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override; void writeGotHeader(uint8_t *buf) const override; void writeGotPlt(uint8_t *buf, const Symbol &s) const override; + void writeIgotPlt(uint8_t *buf, const Symbol &s) const override; void writePltHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, const Symbol &sym, uint64_t pltEntryAddr) const override; @@ -133,6 +135,28 @@ uint32_t RISCV::calcEFlags() const { return target; } +int64_t RISCV::getImplicitAddend(const uint8_t *buf, RelType type) const { + switch (type) { + default: + internalLinkerError(getErrorLocation(buf), + "cannot read addend for relocation " + toString(type)); + return 0; + case R_RISCV_32: + case R_RISCV_TLS_DTPMOD32: + case R_RISCV_TLS_DTPREL32: + return SignExtend64<32>(read32le(buf)); + case R_RISCV_64: + return read64le(buf); + case R_RISCV_RELATIVE: + case R_RISCV_IRELATIVE: + return config->is64 ? read64le(buf) : read32le(buf); + case R_RISCV_NONE: + case R_RISCV_JUMP_SLOT: + // These relocations are defined as not having an implicit addend. + return 0; + } +} + void RISCV::writeGotHeader(uint8_t *buf) const { if (config->is64) write64le(buf, mainPart->dynamic->getVA()); @@ -147,6 +171,15 @@ void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const { write32le(buf, in.plt->getVA()); } +void RISCV::writeIgotPlt(uint8_t *buf, const Symbol &s) const { + if (config->writeAddends) { + if (config->is64) + write64le(buf, s.getVA()); + else + write32le(buf, s.getVA()); + } +} + void RISCV::writePltHeader(uint8_t *buf) const { // 1: auipc t2, %pcrel_hi(.got.plt) // sub t1, t1, t3 |