Index: llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h =================================================================== --- llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h +++ llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h @@ -25,6 +25,12 @@ ELFCall26 = Edge::FirstRelocation, ELFAdrPage21, ELFAddAbs12, + ELFLdSt8Abs12, + ELFLdSt16Abs12, + ELFLdSt32Abs12, + ELFLdSt64Abs12, + ELFLdSt128Abs12, + ELFDelta32 }; } // namespace ELF_aarch64_Edges Index: llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -55,6 +55,18 @@ return ELF_aarch64_Edges::ELFAdrPage21; case ELF::R_AARCH64_ADD_ABS_LO12_NC: return ELF_aarch64_Edges::ELFAddAbs12; + case ELF::R_AARCH64_LDST8_ABS_LO12_NC: + return ELF_aarch64_Edges::ELFLdSt8Abs12; + case ELF::R_AARCH64_LDST16_ABS_LO12_NC: + return ELF_aarch64_Edges::ELFLdSt16Abs12; + case ELF::R_AARCH64_LDST32_ABS_LO12_NC: + return ELF_aarch64_Edges::ELFLdSt32Abs12; + case ELF::R_AARCH64_LDST64_ABS_LO12_NC: + return ELF_aarch64_Edges::ELFLdSt64Abs12; + case ELF::R_AARCH64_LDST128_ABS_LO12_NC: + return ELF_aarch64_Edges::ELFLdSt128Abs12; + case ELF::R_AARCH64_PREL32: + return ELF_aarch64_Edges::ELFDelta32; } return make_error("Unsupported aarch64 relocation:" + @@ -77,6 +89,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSect, Block &BlockToFix) { + using namespace support; using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -104,6 +117,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) { @@ -119,6 +136,55 @@ 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 " + "byte alligend LD/ST (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 " + "half alligend LD/ST (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 " + "word alligend LD/ST (imm12) 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 " + "doubleword alligend LD/ST (imm12) 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 " + "quadword alligend LD/ST (imm12) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFDelta32: { + Kind = aarch64::Delta32; + break; + } }; Edge GE(Kind, Offset, *GraphSymbol, Addend); @@ -184,6 +250,16 @@ return "ELFAdrPage21"; case ELF_aarch64_Edges::ELFAddAbs12: return "ELFAddAbs12"; + case ELF_aarch64_Edges::ELFLdSt8Abs12: + return "ELFLdSt8Abs12"; + case ELF_aarch64_Edges::ELFLdSt16Abs12: + return "ELFLdSt16Abs12"; + case ELF_aarch64_Edges::ELFLdSt32Abs12: + return "ELFLdSt32Abs12"; + case ELF_aarch64_Edges::ELFLdSt64Abs12: + return "ELFLdSt64Abs12"; + case ELF_aarch64_Edges::ELFLdSt128Abs12: + return "ELFLdSt128Abs12"; default: return getGenericEdgeKindName(static_cast(R)); }