///
/// Fixup expression:
/// Fixup <- (Target - Fixup + Addend)
- R_RISCV_CALL_PLT
+ R_RISCV_CALL_PLT,
+ /// 64 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target - *{8}Fixup + Addend)
+ R_RISCV_ADD64,
+
+ /// 32 bits label addition
+ ///
+ /// Fixup expression:
+ /// Fixup <- (Target - *{4}Fixup + Addend)
+ R_RISCV_ADD32,
+
+ /// 16 bits label addition
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{2}Fixup + Addend)
+ R_RISCV_ADD16,
+
+ /// 8 bits label addition
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{1}Fixup + Addend)
+ R_RISCV_ADD8,
+
+ /// 64 bits label subtraction
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{8}Fixup - Addend)
+ R_RISCV_SUB64,
+
+ /// 32 bits label subtraction
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{4}Fixup - Addend)
+ R_RISCV_SUB32,
+
+ /// 16 bits label subtraction
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{2}Fixup - Addend)
+ R_RISCV_SUB16,
+
+ /// 8 bits label subtraction
+ ///
+ /// Fixup expression
+ /// Fixup <- (Target - *{1}Fixup - Addend)
+ R_RISCV_SUB8
};
/// Returns a string name for the given riscv edge. For debugging purposes
#include "llvm/ExecutionEngine/JITLink/riscv.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/Endian.h"
#define DEBUG_TYPE "jitlink"
using namespace llvm;
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
break;
}
+ case R_RISCV_ADD64: {
+ int64_t Value = (E.getTarget().getAddress() +
+ support::endian::read64le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) +
+ E.getAddend())
+ .getValue();
+ *(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
+ break;
+ }
+ case R_RISCV_ADD32: {
+ int64_t Value = (E.getTarget().getAddress() +
+ support::endian::read32le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) +
+ E.getAddend())
+ .getValue();
+ *(little32_t *)FixupPtr = static_cast<uint32_t>(Value);
+ break;
+ }
+ case R_RISCV_ADD16: {
+ int64_t Value = (E.getTarget().getAddress() +
+ support::endian::read16le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) +
+ E.getAddend())
+ .getValue();
+ *(little16_t *)FixupPtr = static_cast<uint32_t>(Value);
+ break;
+ }
+ case R_RISCV_ADD8: {
+ int64_t Value =
+ (E.getTarget().getAddress() +
+ *(reinterpret_cast<const uint8_t *>(FixupAddress.getValue())) +
+ E.getAddend())
+ .getValue();
+ *FixupPtr = static_cast<uint8_t>(Value);
+ break;
+ }
+ case R_RISCV_SUB64: {
+ int64_t Value = support::endian::read64le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) -
+ E.getTarget().getAddress().getValue() - E.getAddend();
+ *(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
+ break;
+ }
+ case R_RISCV_SUB32: {
+ int64_t Value = support::endian::read32le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) -
+ E.getTarget().getAddress().getValue() - E.getAddend();
+ *(little32_t *)FixupPtr = static_cast<uint32_t>(Value);
+ break;
+ }
+ case R_RISCV_SUB16: {
+ int64_t Value = support::endian::read16le(reinterpret_cast<const void *>(
+ FixupAddress.getValue())) -
+ E.getTarget().getAddress().getValue() - E.getAddend();
+ *(little16_t *)FixupPtr = static_cast<uint32_t>(Value);
+ break;
+ }
+ case R_RISCV_SUB8: {
+ int64_t Value =
+ *(reinterpret_cast<const uint8_t *>(FixupAddress.getValue())) -
+ E.getTarget().getAddress().getValue() - E.getAddend();
+ *FixupPtr = static_cast<uint8_t>(Value);
+ break;
+ }
}
return Error::success();
}
return EdgeKind_riscv::R_RISCV_GOT_HI20;
case ELF::R_RISCV_CALL_PLT:
return EdgeKind_riscv::R_RISCV_CALL_PLT;
+ case ELF::R_RISCV_ADD64:
+ return EdgeKind_riscv::R_RISCV_ADD64;
+ case ELF::R_RISCV_ADD32:
+ return EdgeKind_riscv::R_RISCV_ADD32;
+ case ELF::R_RISCV_ADD16:
+ return EdgeKind_riscv::R_RISCV_ADD16;
+ case ELF::R_RISCV_ADD8:
+ return EdgeKind_riscv::R_RISCV_ADD8;
+ case ELF::R_RISCV_SUB64:
+ return EdgeKind_riscv::R_RISCV_SUB64;
+ case ELF::R_RISCV_SUB32:
+ return EdgeKind_riscv::R_RISCV_SUB32;
+ case ELF::R_RISCV_SUB16:
+ return EdgeKind_riscv::R_RISCV_SUB16;
+ case ELF::R_RISCV_SUB8:
+ return EdgeKind_riscv::R_RISCV_SUB8;
}
return make_error<JITLinkError>("Unsupported riscv relocation:" +
--- /dev/null
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t/riscv64_reloc_add.o %s
+# RUN: llvm-mc -triple=riscv32 -filetype=obj -o %t/riscv32_reloc_add.o %s
+# RUN: llvm-jitlink -noexec -check %s %t/riscv64_reloc_add.o
+# RUN: llvm-jitlink -noexec -check %s %t/riscv32_reloc_add.o
+
+# jitlink-check: *{8}(named_data) = 0x8
+# jitlink-check: *{4}(named_data+8) = 0x8
+# jitlink-check: *{2}(named_data+12) = 0x8
+# jitlink-check: *{1}(named_data+14) = 0x8
+
+.global main
+main:
+.L0:
+# Referencing named_data symbol to avoid the following .rodata section be skipped.
+# This instruction will be expand to two instructions (auipc + ld).
+ lw a0, named_data
+.L1:
+
+.section ".rodata","",@progbits
+.type named_data,@object
+named_data:
+.dword .L1 - .L0
+.word .L1 - .L0
+.half .L1 - .L0
+.byte .L1 - .L0
+.size named_data, 15