[llvm] ab472c9 - [JITLink][ELF][AArch64] Implement R_AARCH64_LDST*_ABS_LO12_NC relocation types.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 7 17:32:19 PDT 2022
Author: Sunho Kim
Date: 2022-06-07T17:32:09-07:00
New Revision: ab472c9615447c8a036d198df7debd4fd9b2e8cc
URL: https://github.com/llvm/llvm-project/commit/ab472c9615447c8a036d198df7debd4fd9b2e8cc
DIFF: https://github.com/llvm/llvm-project/commit/ab472c9615447c8a036d198df7debd4fd9b2e8cc.diff
LOG: [JITLink][ELF][AArch64] Implement R_AARCH64_LDST*_ABS_LO12_NC relocation types.
Implement R_AARCH64_LDST*_ABS_LO12_NC relocaiton entries by reusing PageOffset21
generic relocation edge. The difference between MachO backend is that in ELF,
the shift value is explicitly given by relocation type. lld generates the
relocation type that matches with instruction bitwidth, so getting the shift
value implicitly from instruction bytes should be fine in typical use cases.
Added:
Modified:
llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s
Removed:
################################################################################
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
index 008358d661d4a..5a24a69f9fd08 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
@@ -16,6 +16,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/JITLink/aarch64.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/MathExtras.h"
#define DEBUG_TYPE "jitlink"
@@ -48,6 +49,11 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
ELFCall26 = Edge::FirstRelocation,
ELFAdrPage21,
ELFAddAbs12,
+ ELFLdSt8Abs12,
+ ELFLdSt16Abs12,
+ ELFLdSt32Abs12,
+ ELFLdSt64Abs12,
+ ELFLdSt128Abs12,
};
static Expected<ELFAArch64RelocationKind>
@@ -60,6 +66,16 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
return ELFAdrPage21;
case ELF::R_AARCH64_ADD_ABS_LO12_NC:
return ELFAddAbs12;
+ case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
+ return ELFLdSt8Abs12;
+ case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
+ return ELFLdSt16Abs12;
+ case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
+ return ELFLdSt32Abs12;
+ case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
+ return ELFLdSt64Abs12;
+ case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
+ return ELFLdSt128Abs12;
}
return make_error<JITLinkError>("Unsupported aarch64 relocation:" +
@@ -82,6 +98,7 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
Error addSingleRelocation(const typename ELFT::Rela &Rel,
const typename ELFT::Shdr &FixupSect,
Block &BlockToFix) {
+ using support::ulittle32_t;
using Base = ELFLinkGraphBuilder<ELFT>;
uint32_t SymbolIndex = Rel.getSymbol(false);
@@ -108,6 +125,10 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
+ // Get a pointer to the fixup content.
+ const void *FixupContent = BlockToFix.getContent().data() +
+ (FixupAddress - BlockToFix.getAddress());
+
Edge::Kind Kind = Edge::Invalid;
switch (*RelocKind) {
@@ -123,6 +144,61 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
Kind = aarch64::PageOffset12;
break;
}
+ case ELFLdSt8Abs12: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isLoadStoreImm12(Instr) ||
+ aarch64::getPageOffset12Shift(Instr) != 0)
+ return make_error<JITLinkError>(
+ "R_AARCH64_LDST8_ABS_LO12_NC target is not a "
+ "LDRB/STRB (imm12) instruction");
+
+ Kind = aarch64::PageOffset12;
+ break;
+ }
+ case ELFLdSt16Abs12: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isLoadStoreImm12(Instr) ||
+ aarch64::getPageOffset12Shift(Instr) != 1)
+ return make_error<JITLinkError>(
+ "R_AARCH64_LDST16_ABS_LO12_NC target is not a "
+ "LDRH/STRH (imm12) instruction");
+
+ Kind = aarch64::PageOffset12;
+ break;
+ }
+ case ELFLdSt32Abs12: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isLoadStoreImm12(Instr) ||
+ aarch64::getPageOffset12Shift(Instr) != 2)
+ return make_error<JITLinkError>(
+ "R_AARCH64_LDST32_ABS_LO12_NC target is not a "
+ "LDR/STR (imm12, 32 bit) instruction");
+
+ Kind = aarch64::PageOffset12;
+ break;
+ }
+ case ELFLdSt64Abs12: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isLoadStoreImm12(Instr) ||
+ aarch64::getPageOffset12Shift(Instr) != 3)
+ return make_error<JITLinkError>(
+ "R_AARCH64_LDST64_ABS_LO12_NC target is not a "
+ "LDR/STR (imm12, 64 bit) instruction");
+
+ Kind = aarch64::PageOffset12;
+ break;
+ }
+ case ELFLdSt128Abs12: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isLoadStoreImm12(Instr) ||
+ aarch64::getPageOffset12Shift(Instr) != 4)
+ return make_error<JITLinkError>(
+ "R_AARCH64_LDST128_ABS_LO12_NC target is not a "
+ "LDR/STR (imm12, 128 bit) instruction");
+
+ Kind = aarch64::PageOffset12;
+ break;
+ }
};
Edge GE(Kind, Offset, *GraphSymbol, Addend);
@@ -145,6 +221,16 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
return "ELFAdrPage21";
case ELFAddAbs12:
return "ELFAddAbs12";
+ case ELFLdSt8Abs12:
+ return "ELFLdSt8Abs12";
+ case ELFLdSt16Abs12:
+ return "ELFLdSt16Abs12";
+ case ELFLdSt32Abs12:
+ return "ELFLdSt32Abs12";
+ case ELFLdSt64Abs12:
+ return "ELFLdSt64Abs12";
+ case ELFLdSt128Abs12:
+ return "ELFLdSt128Abs12";
default:
return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
}
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s
index 5534fa9b769db..1a670c2648a8a 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s
@@ -48,6 +48,71 @@ test_add_abs_lo12:
add x0, x0, :lo12:named_data
.size test_add_abs_lo12, .-test_add_abs_lo12
+# Check R_AARCH64_LDST*_ABS_LO12_NC relocation of a local symbol
+#
+# The immediate value should be the symbol address right shifted according to its instruction bitwidth.
+#
+# jitlink-check: decode_operand(test_ldrb, 2) = named_data[11:0]
+# jitlink-check: decode_operand(test_ldrsb, 2) = (named_data + 0)[11:0]
+# jitlink-check: decode_operand(test_ldrh, 2) = (named_data + 0)[11:1]
+# jitlink-check: decode_operand(test_ldrsh, 2) = (named_data + 0)[11:1]
+# jitlink-check: decode_operand(test_ldr_32bit, 2) = (named_data + 0)[11:2]
+# jitlink-check: decode_operand(test_ldr_64bit, 2) = (named_data + 0)[11:3]
+# jitlink-check: decode_operand(test_strb, 2) = named_data[11:0]
+# jitlink-check: decode_operand(test_strh, 2) = (named_data + 0)[11:1]
+# jitlink-check: decode_operand(test_str_32bit, 2) = (named_data + 0)[11:2]
+# jitlink-check: decode_operand(test_str_64bit, 2) = (named_data + 0)[11:3]
+
+ .globl test_ldrb
+test_ldrb:
+ ldrb w0, [x1, :lo12:named_data]
+ .size test_ldrb, .-test_ldrb
+
+ .globl test_ldrsb
+test_ldrsb:
+ ldrsb w0, [x1, :lo12:named_data]
+ .size test_ldrsb, .-test_ldrsb
+
+ .globl test_ldrh
+test_ldrh:
+ ldrh w0, [x1, :lo12:named_data]
+ .size test_ldrh, .-test_ldrh
+
+ .globl test_ldrsh
+test_ldrsh:
+ ldrsh w0, [x1, :lo12:named_data]
+ .size test_ldrsh, .-test_ldrsh
+
+ .globl test_ldr_32bit
+test_ldr_32bit:
+ ldr w0, [x1, :lo12:named_data]
+ .size test_ldr_32bit, .-test_ldr_32bit
+
+ .globl test_ldr_64bit
+test_ldr_64bit:
+ ldr x0, [x1, :lo12:named_data]
+ .size test_ldr_64bit, .-test_ldr_64bit
+
+ .globl test_strb
+test_strb:
+ strb w0, [x1, :lo12:named_data]
+ .size test_strb, .-test_strb
+
+ .globl test_strh
+test_strh:
+ strh w0, [x1, :lo12:named_data]
+ .size test_strh, .-test_strh
+
+ .globl test_str_32bit
+test_str_32bit:
+ str w0, [x1, :lo12:named_data]
+ .size test_str_32bit, .-test_str_32bit
+
+ .globl test_str_64bit
+test_str_64bit:
+ str x0, [x1, :lo12:named_data]
+ .size test_str_64bit, .-test_str_64bit
+
.globl named_data
.p2align 4
.type named_data, at object
More information about the llvm-commits
mailing list