Index: llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ 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 @@ ELFCall26 = Edge::FirstRelocation, ELFAdrPage21, ELFAddAbs12, + ELFLdSt8Abs12, + ELFLdSt16Abs12, + ELFLdSt32Abs12, + ELFLdSt64Abs12, + ELFLdSt128Abs12, }; static Expected @@ -60,6 +66,16 @@ 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("Unsupported aarch64 relocation:" + @@ -82,6 +98,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSect, Block &BlockToFix) { + using support::ulittle32_t; using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -108,6 +125,10 @@ 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 @@ Kind = aarch64::PageOffset12; break; } + case ELFLdSt8Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 0) + return make_error( + "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( + "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( + "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( + "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( + "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 @@ 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(R)); } Index: llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s =================================================================== --- llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s +++ llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s @@ -48,6 +48,71 @@ 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,@object