forked from OSchip/llvm-project
[JITLink] Add RISCV label subtraction and addition relocations
This patch add RISCV label subtraction and addition relocations in JITLink Differential Revision: https://reviews.llvm.org/D116794
This commit is contained in:
parent
db04d3e30b
commit
dc18c5fa97
|
@ -89,8 +89,55 @@ enum EdgeKind_riscv : Edge::Kind {
|
||||||
///
|
///
|
||||||
/// Fixup expression:
|
/// Fixup expression:
|
||||||
/// Fixup <- (Target - Fixup + Addend)
|
/// 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
|
/// Returns a string name for the given riscv edge. For debugging purposes
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "llvm/ExecutionEngine/JITLink/riscv.h"
|
#include "llvm/ExecutionEngine/JITLink/riscv.h"
|
||||||
#include "llvm/Object/ELF.h"
|
#include "llvm/Object/ELF.h"
|
||||||
#include "llvm/Object/ELFObjectFile.h"
|
#include "llvm/Object/ELFObjectFile.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
|
||||||
#define DEBUG_TYPE "jitlink"
|
#define DEBUG_TYPE "jitlink"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -294,6 +295,70 @@ private:
|
||||||
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
|
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
|
||||||
break;
|
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 Error::success();
|
||||||
}
|
}
|
||||||
|
@ -328,6 +393,22 @@ private:
|
||||||
return EdgeKind_riscv::R_RISCV_GOT_HI20;
|
return EdgeKind_riscv::R_RISCV_GOT_HI20;
|
||||||
case ELF::R_RISCV_CALL_PLT:
|
case ELF::R_RISCV_CALL_PLT:
|
||||||
return EdgeKind_riscv::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:" +
|
return make_error<JITLinkError>("Unsupported riscv relocation:" +
|
||||||
|
|
|
@ -38,6 +38,22 @@ const char *getEdgeKindName(Edge::Kind K) {
|
||||||
return "R_RISCV_PCREL_LO12_S";
|
return "R_RISCV_PCREL_LO12_S";
|
||||||
case R_RISCV_CALL:
|
case R_RISCV_CALL:
|
||||||
return "R_RISCV_CALL";
|
return "R_RISCV_CALL";
|
||||||
|
case R_RISCV_ADD64:
|
||||||
|
return "R_RISCV_ADD64";
|
||||||
|
case R_RISCV_ADD32:
|
||||||
|
return "R_RISCV_ADD32";
|
||||||
|
case R_RISCV_ADD16:
|
||||||
|
return "R_RISCV_ADD16";
|
||||||
|
case R_RISCV_ADD8:
|
||||||
|
return "R_RISCV_ADD8";
|
||||||
|
case R_RISCV_SUB64:
|
||||||
|
return "R_RISCV_SUB64";
|
||||||
|
case R_RISCV_SUB32:
|
||||||
|
return "R_RISCV_SUB32";
|
||||||
|
case R_RISCV_SUB16:
|
||||||
|
return "R_RISCV_SUB16";
|
||||||
|
case R_RISCV_SUB8:
|
||||||
|
return "R_RISCV_SUB8";
|
||||||
}
|
}
|
||||||
return getGenericEdgeKindName(K);
|
return getGenericEdgeKindName(K);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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
|
Loading…
Reference in New Issue