summaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/ExecutionEngine
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r--llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp5
-rw-r--r--llvm/lib/ExecutionEngine/Interpreter/Interpreter.h2
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.cpp117
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp564
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h53
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp317
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp72
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp26
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLink.cpp11
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp45
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp493
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp7
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/aarch64.cpp52
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/riscv.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp1
-rw-r--r--llvm/lib/ExecutionEngine/MCJIT/MCJIT.h3
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp1
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Core.cpp76
-rw-r--r--llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp7
-rw-r--r--llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp11
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp88
-rw-r--r--llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp3
-rw-r--r--llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp11
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp8
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp16
-rw-r--r--llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp1
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LLJIT.cpp56
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Layer.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp429
-rw-r--r--llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp152
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp11
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp14
-rw-r--r--llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp171
-rw-r--r--llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp252
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Speculation.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp8
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp3
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp9
-rw-r--r--llvm/lib/ExecutionEngine/SectionMemoryManager.cpp2
51 files changed, 1927 insertions, 1218 deletions
diff --git a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
index 1fb37ce7c57c..29a623ebe449 100644
--- a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
+++ b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
@@ -13,6 +13,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include <mutex>
@@ -70,7 +71,7 @@ LLVM_ATTRIBUTE_USED void requiredSymbolDefinitionsFromOrcTargetProcess() {
}
struct RegisteredObjectInfo {
- RegisteredObjectInfo() {}
+ RegisteredObjectInfo() = default;
RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry,
OwningBinary<ObjectFile> Obj)
@@ -96,7 +97,7 @@ class GDBJITRegistrationListener : public JITEventListener {
public:
/// Instantiates the JIT service.
- GDBJITRegistrationListener() {}
+ GDBJITRegistrationListener() = default;
/// Unregisters each object that was previously registered and releases all
/// internal resources.
diff --git a/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h b/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
index fd7fa21df196..3dfe736dc5be 100644
--- a/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -37,7 +37,7 @@ class AllocaHolder {
std::vector<void *> Allocations;
public:
- AllocaHolder() {}
+ AllocaHolder() = default;
// Make this type move-only.
AllocaHolder(AllocaHolder &&) = default;
diff --git a/llvm/lib/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.cpp b/llvm/lib/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.cpp
new file mode 100644
index 000000000000..0fc366bf505f
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.cpp
@@ -0,0 +1,117 @@
+//===-------- JITLink_DWARFRecordSectionSplitter.cpp - JITLink-------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
+#include "llvm/Support/BinaryStreamReader.h"
+
+#define DEBUG_TYPE "jitlink"
+
+namespace llvm {
+namespace jitlink {
+
+DWARFRecordSectionSplitter::DWARFRecordSectionSplitter(StringRef SectionName)
+ : SectionName(SectionName) {}
+
+Error DWARFRecordSectionSplitter::operator()(LinkGraph &G) {
+ auto *Section = G.findSectionByName(SectionName);
+
+ if (!Section) {
+ LLVM_DEBUG({
+ dbgs() << "DWARFRecordSectionSplitter: No " << SectionName
+ << " section. Nothing to do\n";
+ });
+ return Error::success();
+ }
+
+ LLVM_DEBUG({
+ dbgs() << "DWARFRecordSectionSplitter: Processing " << SectionName
+ << "...\n";
+ });
+
+ DenseMap<Block *, LinkGraph::SplitBlockCache> Caches;
+
+ {
+ // Pre-build the split caches.
+ for (auto *B : Section->blocks())
+ Caches[B] = LinkGraph::SplitBlockCache::value_type();
+ for (auto *Sym : Section->symbols())
+ Caches[&Sym->getBlock()]->push_back(Sym);
+ for (auto *B : Section->blocks())
+ llvm::sort(*Caches[B], [](const Symbol *LHS, const Symbol *RHS) {
+ return LHS->getOffset() > RHS->getOffset();
+ });
+ }
+
+ // Iterate over blocks (we do this by iterating over Caches entries rather
+ // than Section->blocks() as we will be inserting new blocks along the way,
+ // which would invalidate iterators in the latter sequence.
+ for (auto &KV : Caches) {
+ auto &B = *KV.first;
+ auto &BCache = KV.second;
+ if (auto Err = processBlock(G, B, BCache))
+ return Err;
+ }
+
+ return Error::success();
+}
+
+Error DWARFRecordSectionSplitter::processBlock(
+ LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache) {
+ LLVM_DEBUG(dbgs() << " Processing block at " << B.getAddress() << "\n");
+
+ // Section should not contain zero-fill blocks.
+ if (B.isZeroFill())
+ return make_error<JITLinkError>("Unexpected zero-fill block in " +
+ SectionName + " section");
+
+ if (B.getSize() == 0) {
+ LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
+ return Error::success();
+ }
+
+ BinaryStreamReader BlockReader(
+ StringRef(B.getContent().data(), B.getContent().size()),
+ G.getEndianness());
+
+ while (true) {
+ uint64_t RecordStartOffset = BlockReader.getOffset();
+
+ LLVM_DEBUG({
+ dbgs() << " Processing CFI record at "
+ << formatv("{0:x16}", B.getAddress()) << "\n";
+ });
+
+ uint32_t Length;
+ if (auto Err = BlockReader.readInteger(Length))
+ return Err;
+ if (Length != 0xffffffff) {
+ if (auto Err = BlockReader.skip(Length))
+ return Err;
+ } else {
+ uint64_t ExtendedLength;
+ if (auto Err = BlockReader.readInteger(ExtendedLength))
+ return Err;
+ if (auto Err = BlockReader.skip(ExtendedLength))
+ return Err;
+ }
+
+ // If this was the last block then there's nothing to split
+ if (BlockReader.empty()) {
+ LLVM_DEBUG(dbgs() << " Extracted " << B << "\n");
+ return Error::success();
+ }
+
+ uint64_t BlockSize = BlockReader.getOffset() - RecordStartOffset;
+ auto &NewBlock = G.splitBlock(B, BlockSize);
+ (void)NewBlock;
+ LLVM_DEBUG(dbgs() << " Extracted " << NewBlock << "\n");
+ }
+}
+
+} // namespace jitlink
+} // namespace llvm
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
index 2ae193595fc0..b1492cd74508 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
@@ -10,6 +10,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -18,109 +19,13 @@
namespace llvm {
namespace jitlink {
-EHFrameSplitter::EHFrameSplitter(StringRef EHFrameSectionName)
- : EHFrameSectionName(EHFrameSectionName) {}
-
-Error EHFrameSplitter::operator()(LinkGraph &G) {
- auto *EHFrame = G.findSectionByName(EHFrameSectionName);
-
- if (!EHFrame) {
- LLVM_DEBUG({
- dbgs() << "EHFrameSplitter: No " << EHFrameSectionName
- << " section. Nothing to do\n";
- });
- return Error::success();
- }
-
- LLVM_DEBUG({
- dbgs() << "EHFrameSplitter: Processing " << EHFrameSectionName << "...\n";
- });
-
- DenseMap<Block *, LinkGraph::SplitBlockCache> Caches;
-
- {
- // Pre-build the split caches.
- for (auto *B : EHFrame->blocks())
- Caches[B] = LinkGraph::SplitBlockCache::value_type();
- for (auto *Sym : EHFrame->symbols())
- Caches[&Sym->getBlock()]->push_back(Sym);
- for (auto *B : EHFrame->blocks())
- llvm::sort(*Caches[B], [](const Symbol *LHS, const Symbol *RHS) {
- return LHS->getOffset() > RHS->getOffset();
- });
- }
-
- // Iterate over blocks (we do this by iterating over Caches entries rather
- // than EHFrame->blocks() as we will be inserting new blocks along the way,
- // which would invalidate iterators in the latter sequence.
- for (auto &KV : Caches) {
- auto &B = *KV.first;
- auto &BCache = KV.second;
- if (auto Err = processBlock(G, B, BCache))
- return Err;
- }
-
- return Error::success();
-}
-
-Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B,
- LinkGraph::SplitBlockCache &Cache) {
- LLVM_DEBUG(dbgs() << " Processing block at " << B.getAddress() << "\n");
-
- // eh-frame should not contain zero-fill blocks.
- if (B.isZeroFill())
- return make_error<JITLinkError>("Unexpected zero-fill block in " +
- EHFrameSectionName + " section");
-
- if (B.getSize() == 0) {
- LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
- return Error::success();
- }
-
- BinaryStreamReader BlockReader(
- StringRef(B.getContent().data(), B.getContent().size()),
- G.getEndianness());
-
- while (true) {
- uint64_t RecordStartOffset = BlockReader.getOffset();
-
- LLVM_DEBUG({
- dbgs() << " Processing CFI record at "
- << formatv("{0:x16}", B.getAddress()) << "\n";
- });
-
- uint32_t Length;
- if (auto Err = BlockReader.readInteger(Length))
- return Err;
- if (Length != 0xffffffff) {
- if (auto Err = BlockReader.skip(Length))
- return Err;
- } else {
- uint64_t ExtendedLength;
- if (auto Err = BlockReader.readInteger(ExtendedLength))
- return Err;
- if (auto Err = BlockReader.skip(ExtendedLength))
- return Err;
- }
-
- // If this was the last block then there's nothing to split
- if (BlockReader.empty()) {
- LLVM_DEBUG(dbgs() << " Extracted " << B << "\n");
- return Error::success();
- }
-
- uint64_t BlockSize = BlockReader.getOffset() - RecordStartOffset;
- auto &NewBlock = G.splitBlock(B, BlockSize);
- (void)NewBlock;
- LLVM_DEBUG(dbgs() << " Extracted " << NewBlock << "\n");
- }
-}
-
EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName,
- unsigned PointerSize, Edge::Kind Delta64,
- Edge::Kind Delta32, Edge::Kind NegDelta32)
+ unsigned PointerSize, Edge::Kind Pointer32,
+ Edge::Kind Pointer64, Edge::Kind Delta32,
+ Edge::Kind Delta64, Edge::Kind NegDelta32)
: EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
- Delta64(Delta64), Delta32(Delta32), NegDelta32(NegDelta32) {}
+ Pointer32(Pointer32), Pointer64(Pointer64), Delta32(Delta32),
+ Delta64(Delta64), NegDelta32(NegDelta32) {}
Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
auto *EHFrame = G.findSectionByName(EHFrameSectionName);
@@ -147,7 +52,16 @@ Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
// Build a map of all blocks and symbols in the text sections. We will use
// these for finding / building edge targets when processing FDEs.
for (auto &Sec : G.sections()) {
- PC.AddrToSyms.addSymbols(Sec.symbols());
+ // Just record the most-canonical symbol (for eh-frame purposes) at each
+ // address.
+ for (auto *Sym : Sec.symbols()) {
+ auto &CurSym = PC.AddrToSym[Sym->getAddress()];
+ if (!CurSym || (std::make_tuple(Sym->getLinkage(), Sym->getScope(),
+ !Sym->hasName(), Sym->getName()) <
+ std::make_tuple(CurSym->getLinkage(), CurSym->getScope(),
+ !CurSym->hasName(), CurSym->getName())))
+ CurSym = Sym;
+ }
if (auto Err = PC.AddrToBlock.addBlocks(Sec.blocks(),
BlockAddressMap::includeNonNull))
return Err;
@@ -172,10 +86,7 @@ Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
- LLVM_DEBUG({
- dbgs() << " Processing block at " << formatv("{0:x16}", B.getAddress())
- << "\n";
- });
+ LLVM_DEBUG(dbgs() << " Processing block at " << B.getAddress() << "\n");
// eh-frame should not contain zero-fill blocks.
if (B.isZeroFill())
@@ -209,7 +120,7 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
LLVM_DEBUG({
dbgs() << " Processing CFI record at "
- << formatv("{0:x16}", B.getAddress() + RecordStartOffset) << "\n";
+ << (B.getAddress() + RecordStartOffset) << "\n";
});
// Get the record length.
@@ -244,7 +155,7 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
if (CIEDelta == 0) {
if (auto Err = processCIE(PC, B, RecordStartOffset,
CIEDeltaFieldOffset + RecordRemaining,
- CIEDeltaFieldOffset))
+ CIEDeltaFieldOffset, BlockEdges))
return Err;
} else {
if (auto Err = processFDE(PC, B, RecordStartOffset,
@@ -263,7 +174,8 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
size_t RecordOffset, size_t RecordLength,
- size_t CIEDeltaFieldOffset) {
+ size_t CIEDeltaFieldOffset,
+ const BlockEdgeMap &BlockEdges) {
LLVM_DEBUG(dbgs() << " Record is CIE\n");
@@ -301,10 +213,6 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
uint64_t CodeAlignmentFactor = 0;
if (auto Err = RecordReader.readULEB128(CodeAlignmentFactor))
return Err;
- if (CodeAlignmentFactor != 1)
- return make_error<JITLinkError>("Unsupported CIE code alignment factor " +
- Twine(CodeAlignmentFactor) +
- " (expected 1)");
}
// Read and validate the data alignment factor.
@@ -312,76 +220,65 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
int64_t DataAlignmentFactor = 0;
if (auto Err = RecordReader.readSLEB128(DataAlignmentFactor))
return Err;
- if (DataAlignmentFactor != -8)
- return make_error<JITLinkError>("Unsupported CIE data alignment factor " +
- Twine(DataAlignmentFactor) +
- " (expected -8)");
}
// Skip the return address register field.
if (auto Err = RecordReader.skip(1))
return Err;
- uint64_t AugmentationDataLength = 0;
- if (auto Err = RecordReader.readULEB128(AugmentationDataLength))
- return Err;
+ if (AugInfo->AugmentationDataPresent) {
- uint32_t AugmentationDataStartOffset = RecordReader.getOffset();
+ CIEInfo.AugmentationDataPresent = true;
- uint8_t *NextField = &AugInfo->Fields[0];
- while (uint8_t Field = *NextField++) {
- switch (Field) {
- case 'L': {
- CIEInfo.FDEsHaveLSDAField = true;
- uint8_t LSDAPointerEncoding;
- if (auto Err = RecordReader.readInteger(LSDAPointerEncoding))
- return Err;
- if (!isSupportedPointerEncoding(LSDAPointerEncoding))
- return make_error<JITLinkError>(
- "Unsupported LSDA pointer encoding " +
- formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CIESymbol.getAddress()));
- CIEInfo.LSDAPointerEncoding = LSDAPointerEncoding;
- break;
- }
- case 'P': {
- uint8_t PersonalityPointerEncoding = 0;
- if (auto Err = RecordReader.readInteger(PersonalityPointerEncoding))
- return Err;
- if (PersonalityPointerEncoding !=
- (dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
- dwarf::DW_EH_PE_sdata4))
- return make_error<JITLinkError>(
- "Unspported personality pointer "
- "encoding " +
- formatv("{0:x2}", PersonalityPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CIESymbol.getAddress()));
- uint32_t PersonalityPointerAddress;
- if (auto Err = RecordReader.readInteger(PersonalityPointerAddress))
- return Err;
- break;
- }
- case 'R': {
- uint8_t FDEPointerEncoding;
- if (auto Err = RecordReader.readInteger(FDEPointerEncoding))
- return Err;
- if (!isSupportedPointerEncoding(FDEPointerEncoding))
- return make_error<JITLinkError>(
- "Unsupported FDE pointer encoding " +
- formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " +
- formatv("{0:x16}", CIESymbol.getAddress()));
- CIEInfo.FDEPointerEncoding = FDEPointerEncoding;
- break;
- }
- default:
- llvm_unreachable("Invalid augmentation string field");
+ uint64_t AugmentationDataLength = 0;
+ if (auto Err = RecordReader.readULEB128(AugmentationDataLength))
+ return Err;
+
+ uint32_t AugmentationDataStartOffset = RecordReader.getOffset();
+
+ uint8_t *NextField = &AugInfo->Fields[0];
+ while (uint8_t Field = *NextField++) {
+ switch (Field) {
+ case 'L':
+ CIEInfo.LSDAPresent = true;
+ if (auto PE = readPointerEncoding(RecordReader, B, "LSDA"))
+ CIEInfo.LSDAEncoding = *PE;
+ else
+ return PE.takeError();
+ break;
+ case 'P': {
+ auto PersonalityPointerEncoding =
+ readPointerEncoding(RecordReader, B, "personality");
+ if (!PersonalityPointerEncoding)
+ return PersonalityPointerEncoding.takeError();
+ if (auto Err =
+ getOrCreateEncodedPointerEdge(
+ PC, BlockEdges, *PersonalityPointerEncoding, RecordReader,
+ B, RecordOffset + RecordReader.getOffset(), "personality")
+ .takeError())
+ return Err;
+ break;
+ }
+ case 'R':
+ if (auto PE = readPointerEncoding(RecordReader, B, "address")) {
+ CIEInfo.AddressEncoding = *PE;
+ if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit)
+ return make_error<JITLinkError>(
+ "Invalid address encoding DW_EH_PE_omit in CIE at " +
+ formatv("{0:x}", (B.getAddress() + RecordOffset).getValue()));
+ } else
+ return PE.takeError();
+ break;
+ default:
+ llvm_unreachable("Invalid augmentation string field");
+ }
}
- }
- if (RecordReader.getOffset() - AugmentationDataStartOffset >
- AugmentationDataLength)
- return make_error<JITLinkError>("Read past the end of the augmentation "
- "data while parsing fields");
+ if (RecordReader.getOffset() - AugmentationDataStartOffset >
+ AugmentationDataLength)
+ return make_error<JITLinkError>("Read past the end of the augmentation "
+ "data while parsing fields");
+ }
assert(!PC.CIEInfos.count(CIESymbol.getAddress()) &&
"Multiple CIEs recorded at the same address?");
@@ -394,7 +291,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
size_t RecordOffset, size_t RecordLength,
size_t CIEDeltaFieldOffset,
uint32_t CIEDelta,
- BlockEdgeMap &BlockEdges) {
+ const BlockEdgeMap &BlockEdges) {
LLVM_DEBUG(dbgs() << " Record is FDE\n");
orc::ExecutorAddr RecordAddress = B.getAddress() + RecordOffset;
@@ -422,8 +319,8 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
LLVM_DEBUG({
dbgs() << " Adding edge at "
- << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset)
- << " to CIE at: " << formatv("{0:x16}", CIEAddress) << "\n";
+ << (RecordAddress + CIEDeltaFieldOffset)
+ << " to CIE at: " << CIEAddress << "\n";
});
if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
CIEInfo = *CIEInfoOrErr;
@@ -435,8 +332,8 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
} else {
LLVM_DEBUG({
dbgs() << " Already has edge at "
- << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset)
- << " to CIE at " << formatv("{0:x16}", CIEAddress) << "\n";
+ << (RecordAddress + CIEDeltaFieldOffset) << " to CIE at "
+ << CIEAddress << "\n";
});
auto &EI = CIEEdgeItr->second;
if (EI.Addend)
@@ -451,107 +348,41 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
}
}
- {
- // Process the PC-Begin field.
- Block *PCBeginBlock = nullptr;
- orc::ExecutorAddrDiff PCBeginFieldOffset = RecordReader.getOffset();
- auto PCEdgeItr = BlockEdges.find(RecordOffset + PCBeginFieldOffset);
- if (PCEdgeItr == BlockEdges.end()) {
- auto PCBeginPtrInfo =
- readEncodedPointer(CIEInfo->FDEPointerEncoding,
- RecordAddress + PCBeginFieldOffset, RecordReader);
- if (!PCBeginPtrInfo)
- return PCBeginPtrInfo.takeError();
- orc::ExecutorAddr PCBegin = PCBeginPtrInfo->first;
- Edge::Kind PCBeginEdgeKind = PCBeginPtrInfo->second;
- LLVM_DEBUG({
- dbgs() << " Adding edge at "
- << (RecordAddress + PCBeginFieldOffset) << " to PC at "
- << formatv("{0:x16}", PCBegin) << "\n";
- });
- auto PCBeginSym = getOrCreateSymbol(PC, PCBegin);
- if (!PCBeginSym)
- return PCBeginSym.takeError();
- B.addEdge(PCBeginEdgeKind, RecordOffset + PCBeginFieldOffset, *PCBeginSym,
- 0);
- PCBeginBlock = &PCBeginSym->getBlock();
- } else {
- auto &EI = PCEdgeItr->second;
- LLVM_DEBUG({
- dbgs() << " Already has edge at "
- << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset)
- << " to PC at " << formatv("{0:x16}", EI.Target->getAddress());
- if (EI.Addend)
- dbgs() << " + " << formatv("{0:x16}", EI.Addend);
- dbgs() << "\n";
- });
-
- // Make sure the existing edge points at a defined block.
- if (!EI.Target->isDefined()) {
- auto EdgeAddr = RecordAddress + PCBeginFieldOffset;
- return make_error<JITLinkError>("FDE edge at " +
- formatv("{0:x16}", EdgeAddr) +
- " points at external block");
- }
- PCBeginBlock = &EI.Target->getBlock();
- if (auto Err = RecordReader.skip(
- getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
- return Err;
- }
-
+ // Process the PC-Begin field.
+ LLVM_DEBUG({
+ dbgs() << " Processing PC-begin at "
+ << (RecordAddress + RecordReader.getOffset()) << "\n";
+ });
+ if (auto PCBegin = getOrCreateEncodedPointerEdge(
+ PC, BlockEdges, CIEInfo->AddressEncoding, RecordReader, B,
+ RecordReader.getOffset(), "PC begin")) {
+ assert(*PCBegin && "PC-begin symbol not set");
// Add a keep-alive edge from the FDE target to the FDE to ensure that the
// FDE is kept alive if its target is.
- assert(PCBeginBlock && "PC-begin block not recorded");
LLVM_DEBUG({
dbgs() << " Adding keep-alive edge from target at "
- << formatv("{0:x16}", PCBeginBlock->getAddress()) << " to FDE at "
- << formatv("{0:x16}", RecordAddress) << "\n";
+ << (*PCBegin)->getBlock().getAddress() << " to FDE at "
+ << RecordAddress << "\n";
});
- PCBeginBlock->addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
- }
+ (*PCBegin)->getBlock().addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
+ } else
+ return PCBegin.takeError();
// Skip over the PC range size field.
- if (auto Err = RecordReader.skip(
- getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
+ if (auto Err = skipEncodedPointer(CIEInfo->AddressEncoding, RecordReader))
return Err;
- if (CIEInfo->FDEsHaveLSDAField) {
+ if (CIEInfo->AugmentationDataPresent) {
uint64_t AugmentationDataSize;
if (auto Err = RecordReader.readULEB128(AugmentationDataSize))
return Err;
- orc::ExecutorAddrDiff LSDAFieldOffset = RecordReader.getOffset();
- auto LSDAEdgeItr = BlockEdges.find(RecordOffset + LSDAFieldOffset);
- if (LSDAEdgeItr == BlockEdges.end()) {
- auto LSDAPointerInfo =
- readEncodedPointer(CIEInfo->LSDAPointerEncoding,
- RecordAddress + LSDAFieldOffset, RecordReader);
- if (!LSDAPointerInfo)
- return LSDAPointerInfo.takeError();
- orc::ExecutorAddr LSDA = LSDAPointerInfo->first;
- Edge::Kind LSDAEdgeKind = LSDAPointerInfo->second;
- auto LSDASym = getOrCreateSymbol(PC, LSDA);
- if (!LSDASym)
- return LSDASym.takeError();
- LLVM_DEBUG({
- dbgs() << " Adding edge at "
- << formatv("{0:x16}", RecordAddress + LSDAFieldOffset)
- << " to LSDA at " << formatv("{0:x16}", LSDA) << "\n";
- });
- B.addEdge(LSDAEdgeKind, RecordOffset + LSDAFieldOffset, *LSDASym, 0);
- } else {
- LLVM_DEBUG({
- auto &EI = LSDAEdgeItr->second;
- dbgs() << " Already has edge at "
- << formatv("{0:x16}", RecordAddress + LSDAFieldOffset)
- << " to LSDA at " << formatv("{0:x16}", EI.Target->getAddress());
- if (EI.Addend)
- dbgs() << " + " << formatv("{0:x16}", EI.Addend);
- dbgs() << "\n";
- });
- if (auto Err = RecordReader.skip(AugmentationDataSize))
+ if (CIEInfo->LSDAPresent)
+ if (auto Err = getOrCreateEncodedPointerEdge(
+ PC, BlockEdges, CIEInfo->LSDAEncoding, RecordReader, B,
+ RecordReader.getOffset(), "LSDA")
+ .takeError())
return Err;
- }
} else {
LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
}
@@ -600,129 +431,163 @@ EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) {
return std::move(AugInfo);
}
-bool EHFrameEdgeFixer::isSupportedPointerEncoding(uint8_t PointerEncoding) {
+Expected<uint8_t> EHFrameEdgeFixer::readPointerEncoding(BinaryStreamReader &R,
+ Block &InBlock,
+ const char *FieldName) {
using namespace dwarf;
- // We only support PC-rel for now.
- if ((PointerEncoding & 0x70) != DW_EH_PE_pcrel)
- return false;
-
- // readEncodedPointer does not handle indirect.
- if (PointerEncoding & DW_EH_PE_indirect)
- return false;
+ uint8_t PointerEncoding;
+ if (auto Err = R.readInteger(PointerEncoding))
+ return std::move(Err);
- // Supported datatypes.
+ bool Supported = true;
switch (PointerEncoding & 0xf) {
- case DW_EH_PE_absptr:
- case DW_EH_PE_udata4:
- case DW_EH_PE_udata8:
- case DW_EH_PE_sdata4:
- case DW_EH_PE_sdata8:
- return true;
+ case DW_EH_PE_uleb128:
+ case DW_EH_PE_udata2:
+ case DW_EH_PE_sleb128:
+ case DW_EH_PE_sdata2:
+ Supported = false;
+ break;
+ }
+ if (Supported) {
+ switch (PointerEncoding & 0x70) {
+ case DW_EH_PE_textrel:
+ case DW_EH_PE_datarel:
+ case DW_EH_PE_funcrel:
+ case DW_EH_PE_aligned:
+ Supported = false;
+ break;
+ }
}
- return false;
+ if (Supported)
+ return PointerEncoding;
+
+ return make_error<JITLinkError>("Unsupported pointer encoding " +
+ formatv("{0:x2}", PointerEncoding) + " for " +
+ FieldName + "in CFI record at " +
+ formatv("{0:x16}", InBlock.getAddress()));
}
-unsigned EHFrameEdgeFixer::getPointerEncodingDataSize(uint8_t PointerEncoding) {
+Error EHFrameEdgeFixer::skipEncodedPointer(uint8_t PointerEncoding,
+ BinaryStreamReader &RecordReader) {
using namespace dwarf;
- assert(isSupportedPointerEncoding(PointerEncoding) &&
- "Unsupported pointer encoding");
+ // Switch absptr to corresponding udata encoding.
+ if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
+ PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
+
switch (PointerEncoding & 0xf) {
- case DW_EH_PE_absptr:
- return PointerSize;
case DW_EH_PE_udata4:
case DW_EH_PE_sdata4:
- return 4;
+ if (auto Err = RecordReader.skip(4))
+ return Err;
+ break;
case DW_EH_PE_udata8:
case DW_EH_PE_sdata8:
- return 8;
+ if (auto Err = RecordReader.skip(8))
+ return Err;
+ break;
default:
- llvm_unreachable("Unsupported encoding");
+ llvm_unreachable("Unrecognized encoding");
}
+ return Error::success();
}
-Expected<std::pair<orc::ExecutorAddr, Edge::Kind>>
-EHFrameEdgeFixer::readEncodedPointer(uint8_t PointerEncoding,
- orc::ExecutorAddr PointerFieldAddress,
- BinaryStreamReader &RecordReader) {
- assert(isSupportedPointerEncoding(PointerEncoding) &&
- "Unsupported pointer encoding");
-
+Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
+ ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
+ BinaryStreamReader &RecordReader, Block &BlockToFix,
+ size_t PointerFieldOffset, const char *FieldName) {
using namespace dwarf;
- // Isolate data type, remap absptr to udata4 or udata8. This relies on us
- // having verified that the graph uses 32-bit or 64-bit pointers only at the
- // start of this pass.
- uint8_t EffectiveType = PointerEncoding & 0xf;
- if (EffectiveType == DW_EH_PE_absptr)
- EffectiveType = (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
+ if (PointerEncoding == DW_EH_PE_omit)
+ return nullptr;
- orc::ExecutorAddr Addr;
- Edge::Kind PointerEdgeKind = Edge::Invalid;
- switch (EffectiveType) {
+ // If there's already an edge here then just skip the encoded pointer and
+ // return the edge's target.
+ {
+ auto EdgeI = BlockEdges.find(PointerFieldOffset);
+ if (EdgeI != BlockEdges.end()) {
+ LLVM_DEBUG({
+ dbgs() << " Existing edge at "
+ << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
+ << FieldName << " at " << EdgeI->second.Target->getAddress();
+ if (EdgeI->second.Target->hasName())
+ dbgs() << " (" << EdgeI->second.Target->getName() << ")";
+ dbgs() << "\n";
+ });
+ if (auto Err = skipEncodedPointer(PointerEncoding, RecordReader))
+ return std::move(Err);
+ return EdgeI->second.Target;
+ }
+ }
+
+ // Switch absptr to corresponding udata encoding.
+ if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
+ PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
+
+ // We need to create an edge. Start by reading the field value.
+ uint64_t FieldValue;
+ bool Is64Bit = false;
+ switch (PointerEncoding & 0xf) {
case DW_EH_PE_udata4: {
uint32_t Val;
if (auto Err = RecordReader.readInteger(Val))
return std::move(Err);
- Addr = PointerFieldAddress + Val;
- PointerEdgeKind = Delta32;
- break;
- }
- case DW_EH_PE_udata8: {
- uint64_t Val;
- if (auto Err = RecordReader.readInteger(Val))
- return std::move(Err);
- Addr = PointerFieldAddress + Val;
- PointerEdgeKind = Delta64;
+ FieldValue = Val;
break;
}
case DW_EH_PE_sdata4: {
- int32_t Val;
+ uint32_t Val;
if (auto Err = RecordReader.readInteger(Val))
return std::move(Err);
- Addr = PointerFieldAddress + Val;
- PointerEdgeKind = Delta32;
+ FieldValue = Val;
break;
}
- case DW_EH_PE_sdata8: {
- int64_t Val;
- if (auto Err = RecordReader.readInteger(Val))
+ case DW_EH_PE_udata8:
+ case DW_EH_PE_sdata8:
+ Is64Bit = true;
+ if (auto Err = RecordReader.readInteger(FieldValue))
return std::move(Err);
- Addr = PointerFieldAddress + Val;
- PointerEdgeKind = Delta64;
break;
- }
+ default:
+ llvm_unreachable("Unsupported encoding");
}
- if (PointerEdgeKind == Edge::Invalid)
- return make_error<JITLinkError>(
- "Unspported edge kind for encoded pointer at " +
- formatv("{0:x}", PointerFieldAddress));
+ // Find the edge target and edge kind to use.
+ orc::ExecutorAddr Target;
+ Edge::Kind PtrEdgeKind = Edge::Invalid;
+ if ((PointerEncoding & 0x70) == DW_EH_PE_pcrel) {
+ Target = BlockToFix.getAddress() + PointerFieldOffset;
+ PtrEdgeKind = Is64Bit ? Delta64 : Delta32;
+ } else
+ PtrEdgeKind = Is64Bit ? Pointer64 : Pointer32;
+ Target += FieldValue;
+
+ // Find or create a symbol to point the edge at.
+ auto TargetSym = getOrCreateSymbol(PC, Target);
+ if (!TargetSym)
+ return TargetSym.takeError();
+ BlockToFix.addEdge(PtrEdgeKind, PointerFieldOffset, *TargetSym, 0);
+
+ LLVM_DEBUG({
+ dbgs() << " Adding edge at "
+ << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
+ << FieldName << " at " << TargetSym->getAddress();
+ if (TargetSym->hasName())
+ dbgs() << " (" << TargetSym->getName() << ")";
+ dbgs() << "\n";
+ });
- return std::make_pair(Addr, Delta64);
+ return &*TargetSym;
}
Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
orc::ExecutorAddr Addr) {
- Symbol *CanonicalSym = nullptr;
-
- auto UpdateCanonicalSym = [&](Symbol *Sym) {
- if (!CanonicalSym || Sym->getLinkage() < CanonicalSym->getLinkage() ||
- Sym->getScope() < CanonicalSym->getScope() ||
- (Sym->hasName() && !CanonicalSym->hasName()) ||
- Sym->getName() < CanonicalSym->getName())
- CanonicalSym = Sym;
- };
-
- if (auto *SymbolsAtAddr = PC.AddrToSyms.getSymbolsAt(Addr))
- for (auto *Sym : *SymbolsAtAddr)
- UpdateCanonicalSym(Sym);
-
- // If we found an existing symbol at the given address then use it.
- if (CanonicalSym)
- return *CanonicalSym;
+ // See whether we have a canonical symbol for the given address already.
+ auto CanonicalSymI = PC.AddrToSym.find(Addr);
+ if (CanonicalSymI != PC.AddrToSym.end())
+ return *CanonicalSymI->second;
// Otherwise search for a block covering the address and create a new symbol.
auto *B = PC.AddrToBlock.getBlockCovering(Addr);
@@ -730,7 +595,10 @@ Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
return make_error<JITLinkError>("No symbol or block covering address " +
formatv("{0:x16}", Addr));
- return PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
+ auto &S =
+ PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
+ PC.AddrToSym[S.getAddress()] = &S;
+ return S;
}
char EHFrameNullTerminator::NullTerminatorBlockContent[4] = {0, 0, 0, 0};
@@ -756,7 +624,7 @@ Error EHFrameNullTerminator::operator()(LinkGraph &G) {
return Error::success();
}
-EHFrameRegistrar::~EHFrameRegistrar() {}
+EHFrameRegistrar::~EHFrameRegistrar() = default;
Error InProcessEHFrameRegistrar::registerEHFrames(
orc::ExecutorAddrRange EHFrameSection) {
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
index ef4b47b9aa28..55cf7fc63ee7 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
@@ -21,27 +21,16 @@
namespace llvm {
namespace jitlink {
-/// A LinkGraph pass that splits blocks in an eh-frame section into sub-blocks
-/// representing individual eh-frames.
-/// EHFrameSplitter should not be run without EHFrameEdgeFixer, which is
-/// responsible for adding FDE-to-CIE edges.
-class EHFrameSplitter {
-public:
- EHFrameSplitter(StringRef EHFrameSectionName);
- Error operator()(LinkGraph &G);
-
-private:
- Error processBlock(LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache);
-
- StringRef EHFrameSectionName;
-};
-
/// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
/// edges.
class EHFrameEdgeFixer {
public:
+ /// Create an eh-frame edge fixer.
+ /// If a given edge-kind is not supported on the target architecture then
+ /// Edge::Invalid should be used.
EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
- Edge::Kind Delta64, Edge::Kind Delta32,
+ Edge::Kind Pointer32, Edge::Kind Pointer64,
+ Edge::Kind Delta32, Edge::Kind Delta64,
Edge::Kind NegDelta32);
Error operator()(LinkGraph &G);
@@ -57,9 +46,10 @@ private:
CIEInformation() = default;
CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
Symbol *CIESymbol = nullptr;
- bool FDEsHaveLSDAField = false;
- uint8_t FDEPointerEncoding = 0;
- uint8_t LSDAPointerEncoding = 0;
+ bool AugmentationDataPresent = false;
+ bool LSDAPresent = false;
+ uint8_t LSDAEncoding = 0;
+ uint8_t AddressEncoding = 0;
};
struct EdgeTarget {
@@ -87,33 +77,38 @@ private:
LinkGraph &G;
CIEInfosMap CIEInfos;
BlockAddressMap AddrToBlock;
- SymbolAddressMap AddrToSyms;
+ DenseMap<orc::ExecutorAddr, Symbol *> AddrToSym;
};
Error processBlock(ParseContext &PC, Block &B);
Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
- size_t RecordLength, size_t CIEDeltaFieldOffset);
+ size_t RecordLength, size_t CIEDeltaFieldOffset,
+ const BlockEdgeMap &BlockEdges);
Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
size_t RecordLength, size_t CIEDeltaFieldOffset,
- uint32_t CIEDelta, BlockEdgeMap &BlockEdges);
+ uint32_t CIEDelta, const BlockEdgeMap &BlockEdges);
Expected<AugmentationInfo>
parseAugmentationString(BinaryStreamReader &RecordReader);
- static bool isSupportedPointerEncoding(uint8_t PointerEncoding);
- unsigned getPointerEncodingDataSize(uint8_t PointerEncoding);
- Expected<std::pair<orc::ExecutorAddr, Edge::Kind>>
- readEncodedPointer(uint8_t PointerEncoding,
- orc::ExecutorAddr PointerFieldAddress,
- BinaryStreamReader &RecordReader);
+ Expected<uint8_t> readPointerEncoding(BinaryStreamReader &RecordReader,
+ Block &InBlock, const char *FieldName);
+ Error skipEncodedPointer(uint8_t PointerEncoding,
+ BinaryStreamReader &RecordReader);
+ Expected<Symbol *> getOrCreateEncodedPointerEdge(
+ ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
+ BinaryStreamReader &RecordReader, Block &BlockToFix,
+ size_t PointerFieldOffset, const char *FieldName);
Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
orc::ExecutorAddr Addr);
StringRef EHFrameSectionName;
unsigned PointerSize;
- Edge::Kind Delta64;
+ Edge::Kind Pointer32;
+ Edge::Kind Pointer64;
Edge::Kind Delta32;
+ Edge::Kind Delta64;
Edge::Kind NegDelta32;
};
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.cpp
index 2194a4fbf1f4..5a983c219627 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.cpp
@@ -27,7 +27,7 @@ namespace jitlink {
StringRef ELFLinkGraphBuilderBase::CommonSectionName(".common");
ArrayRef<const char *> ELFLinkGraphBuilderBase::DwarfSectionNames = DWSecNames;
-ELFLinkGraphBuilderBase::~ELFLinkGraphBuilderBase() {}
+ELFLinkGraphBuilderBase::~ELFLinkGraphBuilderBase() = default;
} // end namespace jitlink
} // end namespace llvm
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
index dd3eb97c21a0..98da3f155c3e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
@@ -11,20 +11,21 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h"
+#include "EHFrameSupportImpl.h"
#include "ELFLinkGraphBuilder.h"
#include "JITLinkGeneric.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
#include "llvm/ExecutionEngine/JITLink/aarch64.h"
#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Endian.h"
#define DEBUG_TYPE "jitlink"
using namespace llvm;
using namespace llvm::jitlink;
-namespace llvm {
-namespace jitlink {
+namespace {
class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
friend class JITLinker<ELFJITLinker_aarch64>;
@@ -37,50 +38,77 @@ public:
private:
Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
- using namespace aarch64;
- using namespace llvm::support;
-
- char *BlockWorkingMem = B.getAlreadyMutableContent().data();
- char *FixupPtr = BlockWorkingMem + E.getOffset();
- auto FixupAddress = B.getAddress() + E.getOffset();
- switch (E.getKind()) {
- case aarch64::R_AARCH64_CALL26: {
- assert((FixupAddress.getValue() & 0x3) == 0 &&
- "Call-inst is not 32-bit aligned");
- int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
-
- if (static_cast<uint64_t>(Value) & 0x3)
- return make_error<JITLinkError>("Call target is not 32-bit aligned");
-
- if (!isInt<28>(Value))
- return makeTargetOutOfRangeError(G, B, E);
-
- uint32_t RawInstr = *(little32_t *)FixupPtr;
- assert((RawInstr & 0x7fffffff) == 0x14000000 &&
- "RawInstr isn't a B or BR immediate instruction");
- uint32_t Imm = (static_cast<uint32_t>(Value) & ((1 << 28) - 1)) >> 2;
- uint32_t FixedInstr = RawInstr | Imm;
- *(little32_t *)FixupPtr = FixedInstr;
- break;
- }
- }
- return Error::success();
+ return aarch64::applyFixup(G, B, E);
}
};
template <typename ELFT>
class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
private:
- static Expected<aarch64::EdgeKind_aarch64>
+ enum ELFAArch64RelocationKind : Edge::Kind {
+ ELFCall26 = Edge::FirstRelocation,
+ ELFAdrPage21,
+ ELFAddAbs12,
+ ELFLdSt8Abs12,
+ ELFLdSt16Abs12,
+ ELFLdSt32Abs12,
+ ELFLdSt64Abs12,
+ ELFLdSt128Abs12,
+ ELFMovwAbsG0,
+ ELFMovwAbsG1,
+ ELFMovwAbsG2,
+ ELFMovwAbsG3,
+ ELFAbs64,
+ ELFPrel32,
+ ELFPrel64,
+ ELFAdrGOTPage21,
+ ELFLd64GOTLo12,
+ };
+
+ static Expected<ELFAArch64RelocationKind>
getRelocationKind(const uint32_t Type) {
using namespace aarch64;
switch (Type) {
case ELF::R_AARCH64_CALL26:
- return EdgeKind_aarch64::R_AARCH64_CALL26;
+ case ELF::R_AARCH64_JUMP26:
+ return ELFCall26;
+ case ELF::R_AARCH64_ADR_PREL_PG_HI21:
+ 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;
+ case ELF::R_AARCH64_MOVW_UABS_G0_NC:
+ return ELFMovwAbsG0;
+ case ELF::R_AARCH64_MOVW_UABS_G1_NC:
+ return ELFMovwAbsG1;
+ case ELF::R_AARCH64_MOVW_UABS_G2_NC:
+ return ELFMovwAbsG2;
+ case ELF::R_AARCH64_MOVW_UABS_G3:
+ return ELFMovwAbsG3;
+ case ELF::R_AARCH64_ABS64:
+ return ELFAbs64;
+ case ELF::R_AARCH64_PREL32:
+ return ELFPrel32;
+ case ELF::R_AARCH64_PREL64:
+ return ELFPrel64;
+ case ELF::R_AARCH64_ADR_GOT_PAGE:
+ return ELFAdrGOTPage21;
+ case ELF::R_AARCH64_LD64_GOT_LO12_NC:
+ return ELFLd64GOTLo12;
}
- return make_error<JITLinkError>("Unsupported aarch64 relocation:" +
- formatv("{0:d}", Type));
+ return make_error<JITLinkError>(
+ "Unsupported aarch64 relocation:" + formatv("{0:d}: ", Type) +
+ object::getELFRelocationTypeName(ELF::EM_AARCH64, Type));
}
Error addRelocations() override {
@@ -99,6 +127,7 @@ private:
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);
@@ -116,18 +145,159 @@ private:
inconvertibleErrorCode());
uint32_t Type = Rel.getType(false);
- Expected<aarch64::EdgeKind_aarch64> Kind = getRelocationKind(Type);
- if (!Kind)
- return Kind.takeError();
+ Expected<ELFAArch64RelocationKind> RelocKind = getRelocationKind(Type);
+ if (!RelocKind)
+ return RelocKind.takeError();
int64_t Addend = Rel.r_addend;
orc::ExecutorAddr FixupAddress =
orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
- Edge GE(*Kind, Offset, *GraphSymbol, Addend);
+
+ // Get a pointer to the fixup content.
+ const void *FixupContent = BlockToFix.getContent().data() +
+ (FixupAddress - BlockToFix.getAddress());
+
+ Edge::Kind Kind = Edge::Invalid;
+
+ switch (*RelocKind) {
+ case ELFCall26: {
+ Kind = aarch64::Branch26;
+ break;
+ }
+ case ELFAdrPage21: {
+ Kind = aarch64::Page21;
+ break;
+ }
+ case ELFAddAbs12: {
+ 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;
+ }
+ case ELFMovwAbsG0: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isMoveWideImm16(Instr) ||
+ aarch64::getMoveWide16Shift(Instr) != 0)
+ return make_error<JITLinkError>(
+ "R_AARCH64_MOVW_UABS_G0_NC target is not a "
+ "MOVK/MOVZ (imm16, LSL #0) instruction");
+
+ Kind = aarch64::MoveWide16;
+ break;
+ }
+ case ELFMovwAbsG1: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isMoveWideImm16(Instr) ||
+ aarch64::getMoveWide16Shift(Instr) != 16)
+ return make_error<JITLinkError>(
+ "R_AARCH64_MOVW_UABS_G1_NC target is not a "
+ "MOVK/MOVZ (imm16, LSL #16) instruction");
+
+ Kind = aarch64::MoveWide16;
+ break;
+ }
+ case ELFMovwAbsG2: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isMoveWideImm16(Instr) ||
+ aarch64::getMoveWide16Shift(Instr) != 32)
+ return make_error<JITLinkError>(
+ "R_AARCH64_MOVW_UABS_G2_NC target is not a "
+ "MOVK/MOVZ (imm16, LSL #32) instruction");
+
+ Kind = aarch64::MoveWide16;
+ break;
+ }
+ case ELFMovwAbsG3: {
+ uint32_t Instr = *(const ulittle32_t *)FixupContent;
+ if (!aarch64::isMoveWideImm16(Instr) ||
+ aarch64::getMoveWide16Shift(Instr) != 48)
+ return make_error<JITLinkError>(
+ "R_AARCH64_MOVW_UABS_G3 target is not a "
+ "MOVK/MOVZ (imm16, LSL #48) instruction");
+
+ Kind = aarch64::MoveWide16;
+ break;
+ }
+ case ELFAbs64: {
+ Kind = aarch64::Pointer64;
+ break;
+ }
+ case ELFPrel32: {
+ Kind = aarch64::Delta32;
+ break;
+ }
+ case ELFPrel64: {
+ Kind = aarch64::Delta64;
+ break;
+ }
+ case ELFAdrGOTPage21: {
+ Kind = aarch64::GOTPage21;
+ break;
+ }
+ case ELFLd64GOTLo12: {
+ Kind = aarch64::GOTPageOffset12;
+ break;
+ }
+ };
+
+ Edge GE(Kind, Offset, *GraphSymbol, Addend);
LLVM_DEBUG({
dbgs() << " ";
- printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(*Kind));
+ printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(Kind));
dbgs() << "\n";
});
@@ -135,6 +305,48 @@ private:
return Error::success();
}
+ /// Return the string name of the given ELF aarch64 edge kind.
+ const char *getELFAArch64RelocationKindName(Edge::Kind R) {
+ switch (R) {
+ case ELFCall26:
+ return "ELFCall26";
+ case ELFAdrPage21:
+ 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";
+ case ELFMovwAbsG0:
+ return "ELFMovwAbsG0";
+ case ELFMovwAbsG1:
+ return "ELFMovwAbsG1";
+ case ELFMovwAbsG2:
+ return "ELFMovwAbsG2";
+ case ELFMovwAbsG3:
+ return "ELFMovwAbsG3";
+ case ELFAbs64:
+ return "ELFAbs64";
+ case ELFPrel32:
+ return "ELFPrel32";
+ case ELFPrel64:
+ return "ELFPrel64";
+ case ELFAdrGOTPage21:
+ return "ELFAdrGOTPage21";
+ case ELFLd64GOTLo12:
+ return "ELFLd64GOTLo12";
+ default:
+ return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
+ }
+ }
+
public:
ELFLinkGraphBuilder_aarch64(StringRef FileName,
const object::ELFFile<ELFT> &Obj, const Triple T)
@@ -142,6 +354,20 @@ public:
aarch64::getEdgeKindName) {}
};
+Error buildTables_ELF_aarch64(LinkGraph &G) {
+ LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
+
+ aarch64::GOTTableManager GOT;
+ aarch64::PLTTableManager PLT(GOT);
+ visitExistingEdges(G, GOT, PLT);
+ return Error::success();
+}
+
+} // namespace
+
+namespace llvm {
+namespace jitlink {
+
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
LLVM_DEBUG({
@@ -168,11 +394,22 @@ void link_ELF_aarch64(std::unique_ptr<LinkGraph> G,
PassConfiguration Config;
const Triple &TT = G->getTargetTriple();
if (Ctx->shouldAddDefaultTargetPasses(TT)) {
+ // Add eh-frame passses.
+ Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));
+ Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+ ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,
+ aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32));
+
+ // Add a mark-live pass.
if (auto MarkLive = Ctx->getMarkLivePass(TT))
Config.PrePrunePasses.push_back(std::move(MarkLive));
else
Config.PrePrunePasses.push_back(markAllSymbolsLive);
+
+ // Add an in-place GOT/Stubs build pass.
+ Config.PostPrunePasses.push_back(buildTables_ELF_aarch64);
}
+
if (auto Err = Ctx->modifyPassConfig(*G, Config))
return Ctx->notifyFailed(std::move(Err));
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
index f83001417e94..197ab71f5274 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
@@ -160,23 +160,16 @@ static Expected<const Edge &> getRISCVPCRelHi20(const Edge &E) {
}
static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
- return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
+ return (Num & (((1ULL << Size) - 1) << Low)) >> Low;
}
-inline Error checkAlignment(llvm::orc::ExecutorAddr loc, uint64_t v, int n,
- const Edge &E) {
- if (v & (n - 1))
- return make_error<JITLinkError>("0x" + llvm::utohexstr(loc.getValue()) +
- " improper alignment for relocation " +
- formatv("{0:d}", E.getKind()) + ": 0x" +
- llvm::utohexstr(v) + " is not aligned to " +
- Twine(n) + " bytes");
- return Error::success();
+static inline bool isAlignmentCorrect(uint64_t Value, int N) {
+ return (Value & (N - 1)) ? false : true;
}
-static inline bool isInRangeForImmS32(int64_t Value) {
- return (Value >= std::numeric_limits<int32_t>::min() &&
- Value <= std::numeric_limits<int32_t>::max());
+// Requires 0 < N <= 64.
+static inline bool isInRangeForImm(int64_t Value, int N) {
+ return Value == llvm::SignExtend64(Value, N);
}
class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
@@ -208,23 +201,36 @@ private:
}
case R_RISCV_BRANCH: {
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
- Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E);
- if (AlignmentIssue) {
- return AlignmentIssue;
- }
- int64_t Lo = Value & 0xFFF;
- uint32_t Imm31_25 = extractBits(Lo, 5, 6) << 25 | extractBits(Lo, 12, 1)
- << 31;
- uint32_t Imm11_7 = extractBits(Lo, 1, 4) << 8 | extractBits(Lo, 11, 1)
- << 7;
+ if (LLVM_UNLIKELY(!isInRangeForImm(Value >> 1, 12)))
+ return makeTargetOutOfRangeError(G, B, E);
+ if (LLVM_UNLIKELY(!isAlignmentCorrect(Value, 2)))
+ return makeAlignmentError(FixupAddress, Value, 2, E);
+ uint32_t Imm31_25 =
+ extractBits(Value, 5, 6) << 25 | extractBits(Value, 12, 1) << 31;
+ uint32_t Imm11_7 =
+ extractBits(Value, 1, 4) << 8 | extractBits(Value, 11, 1) << 7;
uint32_t RawInstr = *(little32_t *)FixupPtr;
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
break;
}
+ case R_RISCV_JAL: {
+ int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
+ if (LLVM_UNLIKELY(!isInRangeForImm(Value >> 1, 20)))
+ return makeTargetOutOfRangeError(G, B, E);
+ if (LLVM_UNLIKELY(!isAlignmentCorrect(Value, 2)))
+ return makeAlignmentError(FixupAddress, Value, 2, E);
+ uint32_t Imm20 = extractBits(Value, 20, 1) << 31;
+ uint32_t Imm10_1 = extractBits(Value, 1, 10) << 21;
+ uint32_t Imm11 = extractBits(Value, 11, 1) << 20;
+ uint32_t Imm19_12 = extractBits(Value, 12, 8) << 12;
+ uint32_t RawInstr = *(little32_t *)FixupPtr;
+ *(little32_t *)FixupPtr = RawInstr | Imm20 | Imm10_1 | Imm11 | Imm19_12;
+ break;
+ }
case R_RISCV_HI20: {
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
int64_t Hi = Value + 0x800;
- if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
+ if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32)))
return makeTargetOutOfRangeError(G, B, E);
uint32_t RawInstr = *(little32_t *)FixupPtr;
*(little32_t *)FixupPtr =
@@ -244,7 +250,7 @@ private:
case R_RISCV_CALL: {
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
int64_t Hi = Value + 0x800;
- if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
+ if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32)))
return makeTargetOutOfRangeError(G, B, E);
int32_t Lo = Value & 0xFFF;
uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
@@ -258,7 +264,7 @@ private:
case R_RISCV_PCREL_HI20: {
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
int64_t Hi = Value + 0x800;
- if (LLVM_UNLIKELY(!isInRangeForImmS32(Hi)))
+ if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32)))
return makeTargetOutOfRangeError(G, B, E);
uint32_t RawInstr = *(little32_t *)FixupPtr;
*(little32_t *)FixupPtr =
@@ -359,6 +365,13 @@ private:
*FixupPtr = static_cast<uint8_t>(Value);
break;
}
+ case R_RISCV_SUB6: {
+ int64_t Value =
+ *(reinterpret_cast<const uint8_t *>(FixupAddress.getValue())) & 0x3f;
+ Value -= E.getTarget().getAddress().getValue() - E.getAddend();
+ *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<uint8_t>(Value) & 0x3f);
+ break;
+ }
case R_RISCV_SET6: {
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
uint32_t RawData = *(little32_t *)FixupPtr;
@@ -410,6 +423,8 @@ private:
return EdgeKind_riscv::R_RISCV_64;
case ELF::R_RISCV_BRANCH:
return EdgeKind_riscv::R_RISCV_BRANCH;
+ case ELF::R_RISCV_JAL:
+ return EdgeKind_riscv::R_RISCV_JAL;
case ELF::R_RISCV_HI20:
return EdgeKind_riscv::R_RISCV_HI20;
case ELF::R_RISCV_LO12_I:
@@ -442,6 +457,8 @@ private:
return EdgeKind_riscv::R_RISCV_SUB16;
case ELF::R_RISCV_SUB8:
return EdgeKind_riscv::R_RISCV_SUB8;
+ case ELF::R_RISCV_SUB6:
+ return EdgeKind_riscv::R_RISCV_SUB6;
case ELF::R_RISCV_SET6:
return EdgeKind_riscv::R_RISCV_SET6;
case ELF::R_RISCV_SET8:
@@ -454,8 +471,9 @@ private:
return EdgeKind_riscv::R_RISCV_32_PCREL;
}
- return make_error<JITLinkError>("Unsupported riscv relocation:" +
- formatv("{0:d}", Type));
+ return make_error<JITLinkError>(
+ "Unsupported riscv relocation:" + formatv("{0:d}: ", Type) +
+ object::getELFRelocationTypeName(ELF::EM_RISCV, Type));
}
Error addRelocations() override {
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 79d2cdbb30f1..8f21274bd1a3 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/JITLink/TableManager.h"
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
@@ -96,17 +97,6 @@ Error buildTables_ELF_x86_64(LinkGraph &G) {
}
} // namespace
-static const char *getELFX86_64RelocName(uint32_t Type) {
- switch (Type) {
-#define ELF_RELOC(Name, Number) \
- case Number: \
- return #Name;
-#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
-#undef ELF_RELOC
- }
- return "Unrecognized ELF/x86-64 relocation type";
-}
-
namespace llvm {
namespace jitlink {
@@ -145,9 +135,9 @@ private:
case ELF::R_X86_64_TLSGD:
return ELF_x86_64_Edges::ELFX86RelocationKind::PCRel32TLV;
}
- return make_error<JITLinkError>("Unsupported x86-64 relocation type " +
- formatv("{0:d}: ", Type) +
- getELFX86_64RelocName(Type));
+ return make_error<JITLinkError>(
+ "Unsupported x86-64 relocation type " + formatv("{0:d}: ", Type) +
+ object::getELFRelocationTypeName(ELF::EM_X86_64, Type));
}
Error addRelocations() override {
@@ -379,10 +369,10 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
- Config.PrePrunePasses.push_back(EHFrameSplitter(".eh_frame"));
- Config.PrePrunePasses.push_back(
- EHFrameEdgeFixer(".eh_frame", x86_64::PointerSize, x86_64::Delta64,
- x86_64::Delta32, x86_64::NegDelta32));
+ Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));
+ Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+ ".eh_frame", x86_64::PointerSize, x86_64::Pointer32, x86_64::Pointer64,
+ x86_64::Delta32, x86_64::Delta64, x86_64::NegDelta32));
Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame"));
// Construct a JITLinker and run the link function.
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index 78a603cfed17..43efe0725cfe 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -336,7 +336,7 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) {
void JITLinkAsyncLookupContinuation::anchor() {}
-JITLinkContext::~JITLinkContext() {}
+JITLinkContext::~JITLinkContext() = default;
bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const {
return true;
@@ -393,6 +393,15 @@ Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
return make_error<JITLinkError>(std::move(ErrMsg));
}
+Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N,
+ const Edge &E) {
+ return make_error<JITLinkError>("0x" + llvm::utohexstr(Loc.getValue()) +
+ " improper alignment for relocation " +
+ formatv("{0:d}", E.getKind()) + ": 0x" +
+ llvm::utohexstr(Value) +
+ " is not aligned to " + Twine(N) + " bytes");
+}
+
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) {
auto Magic = identify_magic(ObjectBuffer.getBuffer());
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index 35ee050c8566..6d321a080829 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -20,7 +20,7 @@
namespace llvm {
namespace jitlink {
-JITLinkerBase::~JITLinkerBase() {}
+JITLinkerBase::~JITLinkerBase() = default;
void JITLinkerBase::linkPhase1(std::unique_ptr<JITLinkerBase> Self) {
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
index 9315ac4f6120..acb759d6ce79 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
@@ -211,7 +211,7 @@ SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr, const JITLinkDylib *JD,
SimpleSegmentAlloc::SimpleSegmentAlloc(SimpleSegmentAlloc &&) = default;
SimpleSegmentAlloc &
SimpleSegmentAlloc::operator=(SimpleSegmentAlloc &&) = default;
-SimpleSegmentAlloc::~SimpleSegmentAlloc() {}
+SimpleSegmentAlloc::~SimpleSegmentAlloc() = default;
SimpleSegmentAlloc::SegmentInfo SimpleSegmentAlloc::getSegInfo(AllocGroup AG) {
auto I = ContentBlocks.find(AG);
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index 62574604458c..1bf12f438be0 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -19,7 +19,7 @@ static const char *CommonSectionName = "__common";
namespace llvm {
namespace jitlink {
-MachOLinkGraphBuilder::~MachOLinkGraphBuilder() {}
+MachOLinkGraphBuilder::~MachOLinkGraphBuilder() = default;
Expected<std::unique_ptr<LinkGraph>> MachOLinkGraphBuilder::buildGraph() {
@@ -368,7 +368,7 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
Twine(KV.first));
NSym.GraphSymbol = &G->addAbsoluteSymbol(
*NSym.Name, orc::ExecutorAddr(NSym.Value), 0, Linkage::Strong,
- Scope::Default, NSym.Desc & MachO::N_NO_DEAD_STRIP);
+ getScope(*NSym.Name, NSym.Type), NSym.Desc & MachO::N_NO_DEAD_STRIP);
break;
case MachO::N_SECT:
SecIndexToSymbols[NSym.Sect - 1].push_back(&NSym);
@@ -644,17 +644,27 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
// Scan section for null characters.
for (size_t I = 0; I != NSec.Size; ++I)
if (NSec.Data[I] == '\0') {
- orc::ExecutorAddrDiff BlockEnd = I + 1;
- size_t BlockSize = BlockEnd - BlockStart;
+ size_t BlockSize = I + 1 - BlockStart;
// Create a block for this null terminated string.
auto &B = G->createContentBlock(*NSec.GraphSection,
{NSec.Data + BlockStart, BlockSize},
- NSec.Address + BlockStart, 1, 0);
+ NSec.Address + BlockStart, NSec.Alignment,
+ BlockStart % NSec.Alignment);
LLVM_DEBUG({
- dbgs() << " Created block " << formatv("{0:x}", B.getAddress())
- << " -- " << formatv("{0:x}", B.getAddress() + B.getSize())
- << " for \"" << StringRef(B.getContent().data()) << "\"\n";
+ dbgs() << " Created block " << B.getRange()
+ << ", align = " << B.getAlignment()
+ << ", align-ofs = " << B.getAlignmentOffset() << " for \"";
+ for (size_t J = 0; J != std::min(B.getSize(), size_t(16)); ++J)
+ switch (B.getContent()[J]) {
+ case '\0': break;
+ case '\n': dbgs() << "\\n"; break;
+ case '\t': dbgs() << "\\t"; break;
+ default: dbgs() << B.getContent()[J]; break;
+ }
+ if (B.getSize() > 16)
+ dbgs() << "...";
+ dbgs() << "\"\n";
});
// If there's no symbol at the start of this block then create one.
@@ -663,15 +673,13 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
auto &S = G->addAnonymousSymbol(B, 0, BlockSize, false, false);
setCanonicalSymbol(NSec, S);
LLVM_DEBUG({
- dbgs() << " Adding anonymous symbol for c-string block "
- << formatv("{0:x16} -- {1:x16}", S.getAddress(),
- S.getAddress() + BlockSize)
- << "\n";
+ dbgs() << " Adding symbol for c-string block " << B.getRange()
+ << ": <anonymous symbol> at offset 0\n";
});
}
// Process any remaining symbols that point into this block.
- auto LastCanonicalAddr = B.getAddress() + BlockEnd;
+ auto LastCanonicalAddr = B.getAddress() + BlockSize;
while (!NSyms.empty() && orc::ExecutorAddr(NSyms.back()->Value) <
B.getAddress() + BlockSize) {
auto &NSym = *NSyms.back();
@@ -686,8 +694,15 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
LastCanonicalAddr = orc::ExecutorAddr(NSym.Value);
}
- createStandardGraphSymbol(NSym, B, SymSize, SectionIsText, SymLive,
- IsCanonical);
+ auto &Sym = createStandardGraphSymbol(NSym, B, SymSize, SectionIsText,
+ SymLive, IsCanonical);
+ (void)Sym;
+ LLVM_DEBUG({
+ dbgs() << " Adding symbol for c-string block " << B.getRange()
+ << ": "
+ << (Sym.hasName() ? Sym.getName() : "<anonymous symbol>")
+ << " at offset " << formatv("{0:x}", Sym.getOffset()) << "\n";
+ });
NSyms.pop_back();
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
index 3ca2e40c7263..dd50314d3ed7 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
@@ -11,15 +11,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITLink/MachO_arm64.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
+#include "llvm/ExecutionEngine/JITLink/aarch64.h"
#include "MachOLinkGraphBuilder.h"
-#include "PerGraphGOTAndPLTStubsBuilder.h"
#define DEBUG_TYPE "jitlink"
using namespace llvm;
using namespace llvm::jitlink;
-using namespace llvm::jitlink::MachO_arm64_Edges;
namespace {
@@ -27,19 +27,39 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
public:
MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj)
: MachOLinkGraphBuilder(Obj, Triple("arm64-apple-darwin"),
- getMachOARM64RelocationKindName),
+ aarch64::getEdgeKindName),
NumSymbols(Obj.getSymtabLoadCommand().nsyms) {}
private:
+ enum MachOARM64RelocationKind : Edge::Kind {
+ MachOBranch26 = Edge::FirstRelocation,
+ MachOPointer32,
+ MachOPointer64,
+ MachOPointer64Anon,
+ MachOPage21,
+ MachOPageOffset12,
+ MachOGOTPage21,
+ MachOGOTPageOffset12,
+ MachOTLVPage21,
+ MachOTLVPageOffset12,
+ MachOPointerToGOT,
+ MachOPairedAddend,
+ MachOLDRLiteral19,
+ MachODelta32,
+ MachODelta64,
+ MachONegDelta32,
+ MachONegDelta64,
+ };
+
static Expected<MachOARM64RelocationKind>
getRelocationKind(const MachO::relocation_info &RI) {
switch (RI.r_type) {
case MachO::ARM64_RELOC_UNSIGNED:
if (!RI.r_pcrel) {
if (RI.r_length == 3)
- return RI.r_extern ? Pointer64 : Pointer64Anon;
+ return RI.r_extern ? MachOPointer64 : MachOPointer64Anon;
else if (RI.r_length == 2)
- return Pointer32;
+ return MachOPointer32;
}
break;
case MachO::ARM64_RELOC_SUBTRACTOR:
@@ -48,46 +68,46 @@ private:
// They may be turned into NegDelta<W> by parsePairRelocation.
if (!RI.r_pcrel && RI.r_extern) {
if (RI.r_length == 2)
- return Delta32;
+ return MachODelta32;
else if (RI.r_length == 3)
- return Delta64;
+ return MachODelta64;
}
break;
case MachO::ARM64_RELOC_BRANCH26:
if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return Branch26;
+ return MachOBranch26;
break;
case MachO::ARM64_RELOC_PAGE21:
if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return Page21;
+ return MachOPage21;
break;
case MachO::ARM64_RELOC_PAGEOFF12:
if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return PageOffset12;
+ return MachOPageOffset12;
break;
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return GOTPage21;
+ return MachOGOTPage21;
break;
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return GOTPageOffset12;
+ return MachOGOTPageOffset12;
break;
case MachO::ARM64_RELOC_POINTER_TO_GOT:
if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return PointerToGOT;
+ return MachOPointerToGOT;
break;
case MachO::ARM64_RELOC_ADDEND:
if (!RI.r_pcrel && !RI.r_extern && RI.r_length == 2)
- return PairedAddend;
+ return MachOPairedAddend;
break;
case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return TLVPage21;
+ return MachOTLVPage21;
break;
case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
if (!RI.r_pcrel && RI.r_extern && RI.r_length == 2)
- return TLVPageOffset12;
+ return MachOTLVPageOffset12;
break;
}
@@ -101,8 +121,7 @@ private:
", length=" + formatv("{0:d}", RI.r_length));
}
- using PairRelocInfo =
- std::tuple<MachOARM64RelocationKind, Symbol *, uint64_t>;
+ using PairRelocInfo = std::tuple<Edge::Kind, Symbol *, uint64_t>;
// Parses paired SUBTRACTOR/UNSIGNED relocations and, on success,
// returns the edge kind and addend to be used.
@@ -114,8 +133,8 @@ private:
object::relocation_iterator &RelEnd) {
using namespace support;
- assert(((SubtractorKind == Delta32 && SubRI.r_length == 2) ||
- (SubtractorKind == Delta64 && SubRI.r_length == 3)) &&
+ assert(((SubtractorKind == MachODelta32 && SubRI.r_length == 2) ||
+ (SubtractorKind == MachODelta64 && SubRI.r_length == 3)) &&
"Subtractor kind should match length");
assert(SubRI.r_extern && "SUBTRACTOR reloc symbol should be extern");
assert(!SubRI.r_pcrel && "SUBTRACTOR reloc should not be PCRel");
@@ -165,17 +184,18 @@ private:
FixupValue -= ToSymbol->getAddress().getValue();
}
- MachOARM64RelocationKind DeltaKind;
+ Edge::Kind DeltaKind;
Symbol *TargetSymbol;
uint64_t Addend;
if (&BlockToFix == &FromSymbol->getAddressable()) {
TargetSymbol = ToSymbol;
- DeltaKind = (SubRI.r_length == 3) ? Delta64 : Delta32;
+ DeltaKind = (SubRI.r_length == 3) ? aarch64::Delta64 : aarch64::Delta32;
Addend = FixupValue + (FixupAddress - FromSymbol->getAddress());
// FIXME: handle extern 'from'.
} else if (&BlockToFix == &ToSymbol->getAddressable()) {
TargetSymbol = &*FromSymbol;
- DeltaKind = (SubRI.r_length == 3) ? NegDelta64 : NegDelta32;
+ DeltaKind =
+ (SubRI.r_length == 3) ? aarch64::NegDelta64 : aarch64::NegDelta32;
Addend = FixupValue - (FixupAddress - ToSymbol->getAddress());
} else {
// BlockToFix was neither FromSymbol nor ToSymbol.
@@ -229,9 +249,9 @@ private:
MachO::relocation_info RI = getRelocationInfo(RelItr);
// Validate the relocation kind.
- auto Kind = getRelocationKind(RI);
- if (!Kind)
- return Kind.takeError();
+ auto MachORelocKind = getRelocationKind(RI);
+ if (!MachORelocKind)
+ return MachORelocKind.takeError();
// Find the address of the value to fix up.
orc::ExecutorAddr FixupAddress =
@@ -255,6 +275,8 @@ private:
return make_error<JITLinkError>(
"Relocation content extends past end of fixup block");
+ Edge::Kind Kind = Edge::Invalid;
+
// Get a pointer to the fixup content.
const char *FixupContent = BlockToFix->getContent().data() +
(FixupAddress - BlockToFix->getAddress());
@@ -263,7 +285,7 @@ private:
Symbol *TargetSymbol = nullptr;
uint64_t Addend = 0;
- if (*Kind == PairedAddend) {
+ if (*MachORelocKind == MachOPairedAddend) {
// If this is an Addend relocation then process it and move to the
// paired reloc.
@@ -275,19 +297,21 @@ private:
++RelItr;
RI = getRelocationInfo(RelItr);
- Kind = getRelocationKind(RI);
- if (!Kind)
- return Kind.takeError();
+ MachORelocKind = getRelocationKind(RI);
+ if (!MachORelocKind)
+ return MachORelocKind.takeError();
- if (*Kind != Branch26 && *Kind != Page21 && *Kind != PageOffset12)
+ if (*MachORelocKind != MachOBranch26 &&
+ *MachORelocKind != MachOPage21 &&
+ *MachORelocKind != MachOPageOffset12)
return make_error<JITLinkError>(
"Invalid relocation pair: Addend + " +
- StringRef(getMachOARM64RelocationKindName(*Kind)));
+ StringRef(getMachOARM64RelocationKindName(*MachORelocKind)));
LLVM_DEBUG({
dbgs() << " Addend: value = " << formatv("{0:x6}", Addend)
- << ", pair is " << getMachOARM64RelocationKindName(*Kind)
- << "\n";
+ << ", pair is "
+ << getMachOARM64RelocationKindName(*MachORelocKind) << "\n";
});
// Find the address of the value to fix up.
@@ -298,8 +322,8 @@ private:
"different target");
}
- switch (*Kind) {
- case Branch26: {
+ switch (*MachORelocKind) {
+ case MachOBranch26: {
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
@@ -308,23 +332,26 @@ private:
if ((Instr & 0x7fffffff) != 0x14000000)
return make_error<JITLinkError>("BRANCH26 target is not a B or BL "
"instruction with a zero addend");
+ Kind = aarch64::Branch26;
break;
}
- case Pointer32:
+ case MachOPointer32:
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
return TargetSymbolOrErr.takeError();
Addend = *(const ulittle32_t *)FixupContent;
+ Kind = aarch64::Pointer32;
break;
- case Pointer64:
+ case MachOPointer64:
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
return TargetSymbolOrErr.takeError();
Addend = *(const ulittle64_t *)FixupContent;
+ Kind = aarch64::Pointer64;
break;
- case Pointer64Anon: {
+ case MachOPointer64Anon: {
orc::ExecutorAddr TargetAddress(*(const ulittle64_t *)FixupContent);
auto TargetNSec = findSectionByIndex(RI.r_symbolnum - 1);
if (!TargetNSec)
@@ -335,11 +362,12 @@ private:
else
return TargetSymbolOrErr.takeError();
Addend = TargetAddress - TargetSymbol->getAddress();
+ Kind = aarch64::Pointer64Anon;
break;
}
- case Page21:
- case TLVPage21:
- case GOTPage21: {
+ case MachOPage21:
+ case MachOTLVPage21:
+ case MachOGOTPage21: {
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
@@ -349,9 +377,17 @@ private:
return make_error<JITLinkError>("PAGE21/GOTPAGE21 target is not an "
"ADRP instruction with a zero "
"addend");
+
+ if (*MachORelocKind == MachOPage21) {
+ Kind = aarch64::Page21;
+ } else if (*MachORelocKind == MachOTLVPage21) {
+ Kind = aarch64::TLVPage21;
+ } else if (*MachORelocKind == MachOGOTPage21) {
+ Kind = aarch64::GOTPage21;
+ }
break;
}
- case PageOffset12: {
+ case MachOPageOffset12: {
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
@@ -361,10 +397,11 @@ private:
if (EncodedAddend != 0)
return make_error<JITLinkError>("GOTPAGEOFF12 target has non-zero "
"encoded addend");
+ Kind = aarch64::PageOffset12;
break;
}
- case TLVPageOffset12:
- case GOTPageOffset12: {
+ case MachOTLVPageOffset12:
+ case MachOGOTPageOffset12: {
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
@@ -374,27 +411,35 @@ private:
return make_error<JITLinkError>("GOTPAGEOFF12 target is not an LDR "
"immediate instruction with a zero "
"addend");
+
+ if (*MachORelocKind == MachOTLVPageOffset12) {
+ Kind = aarch64::TLVPageOffset12;
+ } else if (*MachORelocKind == MachOGOTPageOffset12) {
+ Kind = aarch64::GOTPageOffset12;
+ }
break;
}
- case PointerToGOT:
+ case MachOPointerToGOT:
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
else
return TargetSymbolOrErr.takeError();
+
+ Kind = aarch64::PointerToGOT;
break;
- case Delta32:
- case Delta64: {
+ case MachODelta32:
+ case MachODelta64: {
// We use Delta32/Delta64 to represent SUBTRACTOR relocations.
// parsePairRelocation handles the paired reloc, and returns the
// edge kind to be used (either Delta32/Delta64, or
// NegDelta32/NegDelta64, depending on the direction of the
// subtraction) along with the addend.
auto PairInfo =
- parsePairRelocation(*BlockToFix, *Kind, RI, FixupAddress,
- FixupContent, ++RelItr, RelEnd);
+ parsePairRelocation(*BlockToFix, *MachORelocKind, RI,
+ FixupAddress, FixupContent, ++RelItr, RelEnd);
if (!PairInfo)
return PairInfo.takeError();
- std::tie(*Kind, TargetSymbol, Addend) = *PairInfo;
+ std::tie(Kind, TargetSymbol, Addend) = *PairInfo;
assert(TargetSymbol && "No target symbol from parsePairRelocation?");
break;
}
@@ -405,108 +450,59 @@ private:
LLVM_DEBUG({
dbgs() << " ";
- Edge GE(*Kind, FixupAddress - BlockToFix->getAddress(), *TargetSymbol,
+ Edge GE(Kind, FixupAddress - BlockToFix->getAddress(), *TargetSymbol,
Addend);
- printEdge(dbgs(), *BlockToFix, GE,
- getMachOARM64RelocationKindName(*Kind));
+ printEdge(dbgs(), *BlockToFix, GE, aarch64::getEdgeKindName(Kind));
dbgs() << "\n";
});
- BlockToFix->addEdge(*Kind, FixupAddress - BlockToFix->getAddress(),
+ BlockToFix->addEdge(Kind, FixupAddress - BlockToFix->getAddress(),
*TargetSymbol, Addend);
}
}
return Error::success();
}
- unsigned NumSymbols = 0;
-};
-
-class PerGraphGOTAndPLTStubsBuilder_MachO_arm64
- : public PerGraphGOTAndPLTStubsBuilder<
- PerGraphGOTAndPLTStubsBuilder_MachO_arm64> {
-public:
- using PerGraphGOTAndPLTStubsBuilder<
- PerGraphGOTAndPLTStubsBuilder_MachO_arm64>::PerGraphGOTAndPLTStubsBuilder;
-
- bool isGOTEdgeToFix(Edge &E) const {
- return E.getKind() == GOTPage21 || E.getKind() == GOTPageOffset12 ||
- E.getKind() == TLVPage21 || E.getKind() == TLVPageOffset12 ||
- E.getKind() == PointerToGOT;
- }
-
- Symbol &createGOTEntry(Symbol &Target) {
- auto &GOTEntryBlock = G.createContentBlock(
- getGOTSection(), getGOTEntryBlockContent(), orc::ExecutorAddr(), 8, 0);
- GOTEntryBlock.addEdge(Pointer64, 0, Target, 0);
- return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
- }
-
- void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
- if (E.getKind() == GOTPage21 || E.getKind() == GOTPageOffset12 ||
- E.getKind() == TLVPage21 || E.getKind() == TLVPageOffset12) {
- // Update the target, but leave the edge addend as-is.
- E.setTarget(GOTEntry);
- } else if (E.getKind() == PointerToGOT) {
- E.setTarget(GOTEntry);
- E.setKind(Delta32);
- } else
- llvm_unreachable("Not a GOT edge?");
- }
-
- bool isExternalBranchEdge(Edge &E) {
- return E.getKind() == Branch26 && !E.getTarget().isDefined();
- }
-
- Symbol &createPLTStub(Symbol &Target) {
- auto &StubContentBlock = G.createContentBlock(
- getStubsSection(), getStubBlockContent(), orc::ExecutorAddr(), 1, 0);
- // Re-use GOT entries for stub targets.
- auto &GOTEntrySymbol = getGOTEntry(Target);
- StubContentBlock.addEdge(LDRLiteral19, 0, GOTEntrySymbol, 0);
- return G.addAnonymousSymbol(StubContentBlock, 0, 8, true, false);
- }
-
- void fixPLTEdge(Edge &E, Symbol &Stub) {
- assert(E.getKind() == Branch26 && "Not a Branch32 edge?");
- assert(E.getAddend() == 0 && "Branch32 edge has non-zero addend?");
- E.setTarget(Stub);
- }
-
-private:
- Section &getGOTSection() {
- if (!GOTSection)
- GOTSection = &G.createSection("$__GOT", MemProt::Read | MemProt::Exec);
- return *GOTSection;
- }
-
- Section &getStubsSection() {
- if (!StubsSection)
- StubsSection =
- &G.createSection("$__STUBS", MemProt::Read | MemProt::Exec);
- return *StubsSection;
- }
-
- ArrayRef<char> getGOTEntryBlockContent() {
- return {reinterpret_cast<const char *>(NullGOTEntryContent),
- sizeof(NullGOTEntryContent)};
- }
-
- ArrayRef<char> getStubBlockContent() {
- return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
+ /// Return the string name of the given MachO arm64 edge kind.
+ const char *getMachOARM64RelocationKindName(Edge::Kind R) {
+ switch (R) {
+ case MachOBranch26:
+ return "MachOBranch26";
+ case MachOPointer64:
+ return "MachOPointer64";
+ case MachOPointer64Anon:
+ return "MachOPointer64Anon";
+ case MachOPage21:
+ return "MachOPage21";
+ case MachOPageOffset12:
+ return "MachOPageOffset12";
+ case MachOGOTPage21:
+ return "MachOGOTPage21";
+ case MachOGOTPageOffset12:
+ return "MachOGOTPageOffset12";
+ case MachOTLVPage21:
+ return "MachOTLVPage21";
+ case MachOTLVPageOffset12:
+ return "MachOTLVPageOffset12";
+ case MachOPointerToGOT:
+ return "MachOPointerToGOT";
+ case MachOPairedAddend:
+ return "MachOPairedAddend";
+ case MachOLDRLiteral19:
+ return "MachOLDRLiteral19";
+ case MachODelta32:
+ return "MachODelta32";
+ case MachODelta64:
+ return "MachODelta64";
+ case MachONegDelta32:
+ return "MachONegDelta32";
+ case MachONegDelta64:
+ return "MachONegDelta64";
+ default:
+ return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
+ }
}
- static const uint8_t NullGOTEntryContent[8];
- static const uint8_t StubContent[8];
- Section *GOTSection = nullptr;
- Section *StubsSection = nullptr;
-};
-
-const uint8_t
- PerGraphGOTAndPLTStubsBuilder_MachO_arm64::NullGOTEntryContent[8] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-const uint8_t PerGraphGOTAndPLTStubsBuilder_MachO_arm64::StubContent[8] = {
- 0x10, 0x00, 0x00, 0x58, // LDR x16, <literal>
- 0x00, 0x02, 0x1f, 0xd6 // BR x16
+ unsigned NumSymbols = 0;
};
} // namespace
@@ -514,6 +510,15 @@ const uint8_t PerGraphGOTAndPLTStubsBuilder_MachO_arm64::StubContent[8] = {
namespace llvm {
namespace jitlink {
+Error buildTables_MachO_arm64(LinkGraph &G) {
+ LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
+
+ aarch64::GOTTableManager GOT;
+ aarch64::PLTTableManager PLT(GOT);
+ visitExistingEdges(G, GOT, PLT);
+ return Error::success();
+}
+
class MachOJITLinker_arm64 : public JITLinker<MachOJITLinker_arm64> {
friend class JITLinker<MachOJITLinker_arm64>;
@@ -524,162 +529,8 @@ public:
: JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
private:
-
- static unsigned getPageOffset12Shift(uint32_t Instr) {
- constexpr uint32_t LoadStoreImm12Mask = 0x3b000000;
- constexpr uint32_t Vec128Mask = 0x04800000;
-
- if ((Instr & LoadStoreImm12Mask) == 0x39000000) {
- uint32_t ImplicitShift = Instr >> 30;
- if (ImplicitShift == 0)
- if ((Instr & Vec128Mask) == Vec128Mask)
- ImplicitShift = 4;
-
- return ImplicitShift;
- }
-
- return 0;
- }
-
Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
- using namespace support;
-
- char *BlockWorkingMem = B.getAlreadyMutableContent().data();
- char *FixupPtr = BlockWorkingMem + E.getOffset();
- orc::ExecutorAddr FixupAddress = B.getAddress() + E.getOffset();
-
- switch (E.getKind()) {
- case Branch26: {
- assert((FixupAddress.getValue() & 0x3) == 0 &&
- "Branch-inst is not 32-bit aligned");
-
- int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
-
- if (static_cast<uint64_t>(Value) & 0x3)
- return make_error<JITLinkError>("Branch26 target is not 32-bit "
- "aligned");
-
- if (Value < -(1 << 27) || Value > ((1 << 27) - 1))
- return makeTargetOutOfRangeError(G, B, E);
-
- uint32_t RawInstr = *(little32_t *)FixupPtr;
- assert((RawInstr & 0x7fffffff) == 0x14000000 &&
- "RawInstr isn't a B or BR immediate instruction");
- uint32_t Imm = (static_cast<uint32_t>(Value) & ((1 << 28) - 1)) >> 2;
- uint32_t FixedInstr = RawInstr | Imm;
- *(little32_t *)FixupPtr = FixedInstr;
- break;
- }
- case Pointer32: {
- uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
- if (Value > std::numeric_limits<uint32_t>::max())
- return makeTargetOutOfRangeError(G, B, E);
- *(ulittle32_t *)FixupPtr = Value;
- break;
- }
- case Pointer64:
- case Pointer64Anon: {
- uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
- *(ulittle64_t *)FixupPtr = Value;
- break;
- }
- case Page21:
- case TLVPage21:
- case GOTPage21: {
- assert((E.getKind() != GOTPage21 || E.getAddend() == 0) &&
- "GOTPAGE21 with non-zero addend");
- uint64_t TargetPage =
- (E.getTarget().getAddress().getValue() + E.getAddend()) &
- ~static_cast<uint64_t>(4096 - 1);
- uint64_t PCPage =
- FixupAddress.getValue() & ~static_cast<uint64_t>(4096 - 1);
-
- int64_t PageDelta = TargetPage - PCPage;
- if (PageDelta < -(1 << 30) || PageDelta > ((1 << 30) - 1))
- return makeTargetOutOfRangeError(G, B, E);
-
- uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
- assert((RawInstr & 0xffffffe0) == 0x90000000 &&
- "RawInstr isn't an ADRP instruction");
- uint32_t ImmLo = (static_cast<uint64_t>(PageDelta) >> 12) & 0x3;
- uint32_t ImmHi = (static_cast<uint64_t>(PageDelta) >> 14) & 0x7ffff;
- uint32_t FixedInstr = RawInstr | (ImmLo << 29) | (ImmHi << 5);
- *(ulittle32_t *)FixupPtr = FixedInstr;
- break;
- }
- case PageOffset12: {
- uint64_t TargetOffset =
- (E.getTarget().getAddress() + E.getAddend()).getValue() & 0xfff;
-
- uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
- unsigned ImmShift = getPageOffset12Shift(RawInstr);
-
- if (TargetOffset & ((1 << ImmShift) - 1))
- return make_error<JITLinkError>("PAGEOFF12 target is not aligned");
-
- uint32_t EncodedImm = (TargetOffset >> ImmShift) << 10;
- uint32_t FixedInstr = RawInstr | EncodedImm;
- *(ulittle32_t *)FixupPtr = FixedInstr;
- break;
- }
- case TLVPageOffset12:
- case GOTPageOffset12: {
- assert(E.getAddend() == 0 && "GOTPAGEOF12 with non-zero addend");
-
- uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
- assert((RawInstr & 0xfffffc00) == 0xf9400000 &&
- "RawInstr isn't a 64-bit LDR immediate");
-
- uint32_t TargetOffset = E.getTarget().getAddress().getValue() & 0xfff;
- assert((TargetOffset & 0x7) == 0 && "GOT entry is not 8-byte aligned");
- uint32_t EncodedImm = (TargetOffset >> 3) << 10;
- uint32_t FixedInstr = RawInstr | EncodedImm;
- *(ulittle32_t *)FixupPtr = FixedInstr;
- break;
- }
- case LDRLiteral19: {
- assert((FixupAddress.getValue() & 0x3) == 0 &&
- "LDR is not 32-bit aligned");
- assert(E.getAddend() == 0 && "LDRLiteral19 with non-zero addend");
- uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
- assert(RawInstr == 0x58000010 && "RawInstr isn't a 64-bit LDR literal");
- int64_t Delta = E.getTarget().getAddress() - FixupAddress;
- if (Delta & 0x3)
- return make_error<JITLinkError>("LDR literal target is not 32-bit "
- "aligned");
- if (Delta < -(1 << 20) || Delta > ((1 << 20) - 1))
- return makeTargetOutOfRangeError(G, B, E);
-
- uint32_t EncodedImm =
- ((static_cast<uint32_t>(Delta) >> 2) & 0x7ffff) << 5;
- uint32_t FixedInstr = RawInstr | EncodedImm;
- *(ulittle32_t *)FixupPtr = FixedInstr;
- break;
- }
- case Delta32:
- case Delta64:
- case NegDelta32:
- case NegDelta64: {
- int64_t Value;
- if (E.getKind() == Delta32 || E.getKind() == Delta64)
- Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
- else
- Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
-
- if (E.getKind() == Delta32 || E.getKind() == NegDelta32) {
- if (Value < std::numeric_limits<int32_t>::min() ||
- Value > std::numeric_limits<int32_t>::max())
- return makeTargetOutOfRangeError(G, B, E);
- *(little32_t *)FixupPtr = Value;
- } else
- *(little64_t *)FixupPtr = Value;
- break;
- }
- default:
- llvm_unreachable("Unrecognized edge kind");
- }
-
- return Error::success();
+ return aarch64::applyFixup(G, B, E);
}
uint64_t NullValue = 0;
@@ -712,13 +563,14 @@ void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
// Add eh-frame passses.
// FIXME: Prune eh-frames for which compact-unwind is available once
// we support compact-unwind registration with libunwind.
- Config.PrePrunePasses.push_back(EHFrameSplitter("__TEXT,__eh_frame"));
Config.PrePrunePasses.push_back(
- EHFrameEdgeFixer("__TEXT,__eh_frame", 8, Delta64, Delta32, NegDelta32));
+ DWARFRecordSectionSplitter("__TEXT,__eh_frame"));
+ Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+ "__TEXT,__eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,
+ aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32));
// Add an in-place GOT/Stubs pass.
- Config.PostPrunePasses.push_back(
- PerGraphGOTAndPLTStubsBuilder_MachO_arm64::asPass);
+ Config.PostPrunePasses.push_back(buildTables_MachO_arm64);
}
if (auto Err = Ctx->modifyPassConfig(*G, Config))
@@ -728,44 +580,5 @@ void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
MachOJITLinker_arm64::link(std::move(Ctx), std::move(G), std::move(Config));
}
-const char *getMachOARM64RelocationKindName(Edge::Kind R) {
- switch (R) {
- case Branch26:
- return "Branch26";
- case Pointer64:
- return "Pointer64";
- case Pointer64Anon:
- return "Pointer64Anon";
- case Page21:
- return "Page21";
- case PageOffset12:
- return "PageOffset12";
- case GOTPage21:
- return "GOTPage21";
- case GOTPageOffset12:
- return "GOTPageOffset12";
- case TLVPage21:
- return "TLVPage21";
- case TLVPageOffset12:
- return "TLVPageOffset12";
- case PointerToGOT:
- return "PointerToGOT";
- case PairedAddend:
- return "PairedAddend";
- case LDRLiteral19:
- return "LDRLiteral19";
- case Delta32:
- return "Delta32";
- case Delta64:
- return "Delta64";
- case NegDelta32:
- return "NegDelta32";
- case NegDelta64:
- return "NegDelta64";
- default:
- return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
- }
-}
-
} // end namespace jitlink
} // end namespace llvm
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
index 82afaa3aa3c5..6dfd5548fcfd 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
@@ -11,10 +11,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "MachOLinkGraphBuilder.h"
-#include "PerGraphGOTAndPLTStubsBuilder.h"
#define DEBUG_TYPE "jitlink"
@@ -504,12 +504,13 @@ void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
}
LinkGraphPassFunction createEHFrameSplitterPass_MachO_x86_64() {
- return EHFrameSplitter("__TEXT,__eh_frame");
+ return DWARFRecordSectionSplitter("__TEXT,__eh_frame");
}
LinkGraphPassFunction createEHFrameEdgeFixerPass_MachO_x86_64() {
return EHFrameEdgeFixer("__TEXT,__eh_frame", x86_64::PointerSize,
- x86_64::Delta64, x86_64::Delta32, x86_64::NegDelta32);
+ x86_64::Pointer32, x86_64::Pointer64, x86_64::Delta32,
+ x86_64::Delta64, x86_64::NegDelta32);
}
} // end namespace jitlink
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch64.cpp
index 6dccc4811885..28a6f9ce90d9 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch64.cpp
@@ -18,13 +18,55 @@ namespace llvm {
namespace jitlink {
namespace aarch64 {
-const char *getEdgeKindName(Edge::Kind K) {
- switch (K) {
- case R_AARCH64_CALL26:
- return "R_AARCH64_CALL26";
+const uint8_t NullGOTEntryContent[8] = {0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+const uint8_t StubContent[8] = {
+ 0x10, 0x00, 0x00, 0x58, // LDR x16, <literal>
+ 0x00, 0x02, 0x1f, 0xd6 // BR x16
+};
+
+const char *getEdgeKindName(Edge::Kind R) {
+ switch (R) {
+ case Branch26:
+ return "Branch26";
+ case Pointer64:
+ return "Pointer64";
+ case Pointer64Anon:
+ return "Pointer64Anon";
+ case Page21:
+ return "Page21";
+ case PageOffset12:
+ return "PageOffset12";
+ case MoveWide16:
+ return "MoveWide16";
+ case GOTPage21:
+ return "GOTPage21";
+ case GOTPageOffset12:
+ return "GOTPageOffset12";
+ case TLVPage21:
+ return "TLVPage21";
+ case TLVPageOffset12:
+ return "TLVPageOffset12";
+ case PointerToGOT:
+ return "PointerToGOT";
+ case PairedAddend:
+ return "PairedAddend";
+ case LDRLiteral19:
+ return "LDRLiteral19";
+ case Delta32:
+ return "Delta32";
+ case Delta64:
+ return "Delta64";
+ case NegDelta32:
+ return "NegDelta32";
+ case NegDelta64:
+ return "NegDelta64";
+ default:
+ return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
}
- return getGenericEdgeKindName(K);
}
+
} // namespace aarch64
} // namespace jitlink
} // namespace llvm
diff --git a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
index 3ce2cf10a24c..3848cc6b5f01 100644
--- a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
@@ -26,6 +26,8 @@ const char *getEdgeKindName(Edge::Kind K) {
return "R_RISCV_64";
case R_RISCV_BRANCH:
return "R_RISCV_BRANCH";
+ case R_RISCV_JAL:
+ return "R_RISCV_JAL";
case R_RISCV_HI20:
return "R_RISCV_HI20";
case R_RISCV_LO12_I:
@@ -56,6 +58,8 @@ const char *getEdgeKindName(Edge::Kind K) {
return "R_RISCV_SUB16";
case R_RISCV_SUB8:
return "R_RISCV_SUB8";
+ case R_RISCV_SUB6:
+ return "R_RISCV_SUB6";
case R_RISCV_SET6:
return "R_RISCV_SET6";
case R_RISCV_SET8:
diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index ed912280ac82..4ac901daa5c8 100644
--- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -19,6 +19,7 @@
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DynamicLibrary.h"
diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
index a5dd420c9132..f6c4cdbb8c91 100644
--- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -72,8 +72,7 @@ class MCJIT : public ExecutionEngine {
class OwningModuleContainer {
public:
- OwningModuleContainer() {
- }
+ OwningModuleContainer() = default;
~OwningModuleContainer() {
freeModulePtrSet(AddedModules);
freeModulePtrSet(LoadedModules);
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
index f34247005258..fad7428e1f90 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
@@ -12,6 +12,7 @@
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index e5cb8103919a..dd80630a33c1 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -62,7 +62,7 @@ void ResourceTracker::makeDefunct() {
JDAndFlag.store(Val);
}
-ResourceManager::~ResourceManager() {}
+ResourceManager::~ResourceManager() = default;
ResourceTrackerDefunct::ResourceTrackerDefunct(ResourceTrackerSP RT)
: RT(std::move(RT)) {}
@@ -76,9 +76,21 @@ void ResourceTrackerDefunct::log(raw_ostream &OS) const {
}
FailedToMaterialize::FailedToMaterialize(
+ std::shared_ptr<SymbolStringPool> SSP,
std::shared_ptr<SymbolDependenceMap> Symbols)
- : Symbols(std::move(Symbols)) {
+ : SSP(std::move(SSP)), Symbols(std::move(Symbols)) {
+ assert(this->SSP && "String pool cannot be null");
assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
+
+ // FIXME: Use a new dep-map type for FailedToMaterialize errors so that we
+ // don't have to manually retain/release.
+ for (auto &KV : *this->Symbols)
+ KV.first->Retain();
+}
+
+FailedToMaterialize::~FailedToMaterialize() {
+ for (auto &KV : *Symbols)
+ KV.first->Release();
}
std::error_code FailedToMaterialize::convertToErrorCode() const {
@@ -251,9 +263,21 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
void AbsoluteSymbolsMaterializationUnit::materialize(
std::unique_ptr<MaterializationResponsibility> R) {
- // No dependencies, so these calls can't fail.
- cantFail(R->notifyResolved(Symbols));
- cantFail(R->notifyEmitted());
+ // Even though these are just absolute symbols we need to check for failure
+ // to resolve/emit: the tracker for these symbols may have been removed while
+ // the materialization was in flight (e.g. due to a failure in some action
+ // triggered by the queries attached to the resolution/emission of these
+ // symbols).
+ if (auto Err = R->notifyResolved(Symbols)) {
+ R->getExecutionSession().reportError(std::move(Err));
+ R->failMaterialization();
+ return;
+ }
+ if (auto Err = R->notifyEmitted()) {
+ R->getExecutionSession().reportError(std::move(Err));
+ R->failMaterialization();
+ return;
+ }
}
void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
@@ -485,13 +509,16 @@ Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD,
class InProgressLookupState {
public:
+ // FIXME: Reduce the number of SymbolStringPtrs here. See
+ // https://github.com/llvm/llvm-project/issues/55576.
+
InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder,
SymbolLookupSet LookupSet, SymbolState RequiredState)
: K(K), SearchOrder(std::move(SearchOrder)),
LookupSet(std::move(LookupSet)), RequiredState(RequiredState) {
DefGeneratorCandidates = this->LookupSet;
}
- virtual ~InProgressLookupState() {}
+ virtual ~InProgressLookupState() = default;
virtual void complete(std::unique_ptr<InProgressLookupState> IPLS) = 0;
virtual void fail(Error Err) = 0;
@@ -609,7 +636,7 @@ void LookupState::continueLookup(Error Err) {
ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));
}
-DefinitionGenerator::~DefinitionGenerator() {}
+DefinitionGenerator::~DefinitionGenerator() = default;
JITDylib::~JITDylib() {
LLVM_DEBUG(dbgs() << "Destroying JITDylib " << getName() << "\n");
@@ -959,6 +986,7 @@ Error JITDylib::resolve(MaterializationResponsibility &MR,
auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
(*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
return make_error<FailedToMaterialize>(
+ getExecutionSession().getSymbolStringPool(),
std::move(FailedSymbolsDepMap));
}
@@ -1036,6 +1064,7 @@ Error JITDylib::emit(MaterializationResponsibility &MR,
auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
(*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
return make_error<FailedToMaterialize>(
+ getExecutionSession().getSymbolStringPool(),
std::move(FailedSymbolsDepMap));
}
@@ -1411,12 +1440,11 @@ void JITDylib::dump(raw_ostream &OS) {
for (auto &KV : Symbols) {
OS << " \"" << *KV.first << "\": ";
if (auto Addr = KV.second.getAddress())
- OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
- << " ";
+ OS << format("0x%016" PRIx64, Addr);
else
OS << "<not resolved> ";
- OS << KV.second.getFlags() << " " << KV.second.getState();
+ OS << " " << KV.second.getFlags() << " " << KV.second.getState();
if (KV.second.hasMaterializerAttached()) {
OS << " (Materializer ";
@@ -1751,7 +1779,7 @@ void JITDylib::transferEmittedNodeDependencies(
}
}
-Platform::~Platform() {}
+Platform::~Platform() = default;
Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
ExecutionSession &ES,
@@ -1858,6 +1886,12 @@ ExecutionSession::ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC)
this->EPC->ES = this;
}
+ExecutionSession::~ExecutionSession() {
+ // You must call endSession prior to destroying the session.
+ assert(!SessionOpen &&
+ "Session still open. Did you forget to call endSession?");
+}
+
Error ExecutionSession::endSession() {
LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
@@ -1869,7 +1903,7 @@ Error ExecutionSession::endSession() {
// TODO: notifiy platform? run static deinits?
Error Err = Error::success();
- for (auto &JD : JITDylibsToClose)
+ for (auto &JD : reverse(JITDylibsToClose))
Err = joinErrors(std::move(Err), JD->clear());
Err = joinErrors(std::move(Err), EPC->disconnect());
@@ -1987,9 +2021,8 @@ JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) {
auto &JD = *KV.first;
- if (Visited.count(&JD))
+ if (!Visited.insert(&JD).second)
continue;
- Visited.insert(&JD);
WorkStack.push_back(&JD);
}
}
@@ -2071,7 +2104,7 @@ void ExecutionSession::lookup(
Expected<SymbolMap>
ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
- const SymbolLookupSet &Symbols, LookupKind K,
+ SymbolLookupSet Symbols, LookupKind K,
SymbolState RequiredState,
RegisterDependenciesFunction RegisterDependencies) {
#if LLVM_ENABLE_THREADS
@@ -2103,7 +2136,7 @@ ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
#endif
// Perform the asynchronous lookup.
- lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
+ lookup(K, SearchOrder, std::move(Symbols), RequiredState, NotifyComplete,
RegisterDependencies);
#if LLVM_ENABLE_THREADS
@@ -2257,7 +2290,8 @@ Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) {
joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe()));
for (auto &Q : QueriesToFail)
- Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
+ Q->handleFailed(
+ make_error<FailedToMaterialize>(getSymbolStringPool(), FailedSymbols));
return Err;
}
@@ -2337,7 +2371,8 @@ Error ExecutionSession::IL_updateCandidatesFor(
if (SymI->second.getFlags().hasError()) {
auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
(*FailedSymbolsMap)[&JD] = {Name};
- return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
+ return make_error<FailedToMaterialize>(getSymbolStringPool(),
+ std::move(FailedSymbolsMap));
}
// Otherwise this is a match. Remove it from the candidate set.
@@ -2611,7 +2646,7 @@ void ExecutionSession::OL_completeLookup(
auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
(*FailedSymbolsMap)[&JD] = {Name};
return make_error<FailedToMaterialize>(
- std::move(FailedSymbolsMap));
+ getSymbolStringPool(), std::move(FailedSymbolsMap));
}
// Otherwise this is a match.
@@ -2947,7 +2982,8 @@ void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) {
});
for (auto &Q : FailedQueries)
- Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
+ Q->handleFailed(
+ make_error<FailedToMaterialize>(getSymbolStringPool(), FailedSymbols));
}
Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
diff --git a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
index 4ff6b7fd54df..1e68ea1225e6 100644
--- a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
@@ -42,7 +42,7 @@ class DebugObjectSection {
public:
virtual void setTargetMemoryRange(SectionRange Range) = 0;
virtual void dump(raw_ostream &OS, StringRef Name) {}
- virtual ~DebugObjectSection() {}
+ virtual ~DebugObjectSection() = default;
};
template <typename ELFT>
diff --git a/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp
index 5b386a458f1f..028bd245fb55 100644
--- a/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp
@@ -297,6 +297,13 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
llvm_unreachable("Invalid state");
}
+raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPool &SSP) {
+ std::lock_guard<std::mutex> Lock(SSP.PoolMutex);
+ for (auto &KV : SSP.Pool)
+ OS << KV.first() << ": " << KV.second << "\n";
+ return OS;
+}
+
DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride)
: DumpDir(std::move(DumpDir)),
IdentifierOverride(std::move(IdentifierOverride)) {
diff --git a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
index 6916ee4a827f..3c44fe81b4a9 100644
--- a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
@@ -48,7 +48,7 @@ public:
MachODebugObjectSynthesizerBase(LinkGraph &G, ExecutorAddr RegisterActionAddr)
: G(G), RegisterActionAddr(RegisterActionAddr) {}
- virtual ~MachODebugObjectSynthesizerBase() {}
+ virtual ~MachODebugObjectSynthesizerBase() = default;
Error preserveDebugSections() {
if (G.findSectionByName(SynthDebugSectionName)) {
@@ -349,10 +349,11 @@ public:
}
SectionRange R(MachOContainerBlock->getSection());
- G.allocActions().push_back({cantFail(shared::WrapperFunctionCall::Create<
- SPSArgList<SPSExecutorAddrRange>>(
- RegisterActionAddr, R.getRange())),
- {}});
+ G.allocActions().push_back(
+ {cantFail(shared::WrapperFunctionCall::Create<
+ shared::SPSArgList<shared::SPSExecutorAddrRange>>(
+ RegisterActionAddr, R.getRange())),
+ {}});
return Error::success();
}
diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
index d02760703f06..e476c549412a 100644
--- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
@@ -10,6 +10,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
+#include "llvm/ExecutionEngine/JITLink/aarch64.h"
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
@@ -47,6 +48,11 @@ public:
Endianness = support::endianness::little;
EdgeKind = jitlink::x86_64::Pointer64;
break;
+ case Triple::aarch64:
+ PointerSize = 8;
+ Endianness = support::endianness::little;
+ EdgeKind = jitlink::aarch64::Pointer64;
+ break;
default:
llvm_unreachable("Unrecognized architecture");
}
@@ -95,8 +101,6 @@ StringRef InitArrayFuncSectionName = ".init_array";
StringRef ThreadBSSSectionName = ".tbss";
StringRef ThreadDataSectionName = ".tdata";
-StringRef InitSectionNames[] = {InitArrayFuncSectionName};
-
} // end anonymous namespace
namespace llvm {
@@ -117,8 +121,12 @@ ELFNixPlatform::Create(ExecutionSession &ES,
inconvertibleErrorCode());
// Create default aliases if the caller didn't supply any.
- if (!RuntimeAliases)
- RuntimeAliases = standardPlatformAliases(ES);
+ if (!RuntimeAliases) {
+ auto StandardRuntimeAliases = standardPlatformAliases(ES, PlatformJD);
+ if (!StandardRuntimeAliases)
+ return StandardRuntimeAliases.takeError();
+ RuntimeAliases = std::move(*StandardRuntimeAliases);
+ }
// Define the aliases.
if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
@@ -189,10 +197,53 @@ static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
}
}
-SymbolAliasMap ELFNixPlatform::standardPlatformAliases(ExecutionSession &ES) {
+Expected<SymbolAliasMap>
+ELFNixPlatform::standardPlatformAliases(ExecutionSession &ES,
+ JITDylib &PlatformJD) {
SymbolAliasMap Aliases;
addAliases(ES, Aliases, requiredCXXAliases());
addAliases(ES, Aliases, standardRuntimeUtilityAliases());
+
+ // Determine whether or not the libunwind extended-API function for
+ // dynamically registering an entire .eh_frame section is available.
+ // If it is not, we assume that libgcc_s is being used, and alias to
+ // its __register_frame with the same functionality.
+ auto RTRegisterFrame = ES.intern("__orc_rt_register_eh_frame_section");
+ auto LibUnwindRegisterFrame = ES.intern("__unw_add_dynamic_eh_frame_section");
+ auto RTDeregisterFrame = ES.intern("__orc_rt_deregister_eh_frame_section");
+ auto LibUnwindDeregisterFrame =
+ ES.intern("__unw_remove_dynamic_eh_frame_section");
+ auto SM = ES.lookup(makeJITDylibSearchOrder(&PlatformJD),
+ SymbolLookupSet()
+ .add(LibUnwindRegisterFrame,
+ SymbolLookupFlags::WeaklyReferencedSymbol)
+ .add(LibUnwindDeregisterFrame,
+ SymbolLookupFlags::WeaklyReferencedSymbol));
+ if (!SM) { // Weak-ref means no "missing symbol" errors, so this must be
+ // something more serious that we should report.
+ return SM.takeError();
+ } else if (SM->size() == 2) {
+ LLVM_DEBUG({
+ dbgs() << "Using libunwind " << LibUnwindRegisterFrame
+ << " for unwind info registration\n";
+ });
+ Aliases[std::move(RTRegisterFrame)] = {LibUnwindRegisterFrame,
+ JITSymbolFlags::Exported};
+ Aliases[std::move(RTDeregisterFrame)] = {LibUnwindDeregisterFrame,
+ JITSymbolFlags::Exported};
+ } else {
+ // Since LLVM libunwind is not present, we assume that unwinding
+ // is provided by libgcc
+ LLVM_DEBUG({
+ dbgs() << "Using libgcc __register_frame"
+ << " for unwind info registration\n";
+ });
+ Aliases[std::move(RTRegisterFrame)] = {ES.intern("__register_frame"),
+ JITSymbolFlags::Exported};
+ Aliases[std::move(RTDeregisterFrame)] = {ES.intern("__deregister_frame"),
+ JITSymbolFlags::Exported};
+ }
+
return Aliases;
}
@@ -210,6 +261,10 @@ ELFNixPlatform::standardRuntimeUtilityAliases() {
static const std::pair<const char *, const char *>
StandardRuntimeUtilityAliases[] = {
{"__orc_rt_run_program", "__orc_rt_elfnix_run_program"},
+ {"__orc_rt_jit_dlerror", "__orc_rt_elfnix_jit_dlerror"},
+ {"__orc_rt_jit_dlopen", "__orc_rt_elfnix_jit_dlopen"},
+ {"__orc_rt_jit_dlclose", "__orc_rt_elfnix_jit_dlclose"},
+ {"__orc_rt_jit_dlsym", "__orc_rt_elfnix_jit_dlsym"},
{"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};
return ArrayRef<std::pair<const char *, const char *>>(
@@ -217,16 +272,16 @@ ELFNixPlatform::standardRuntimeUtilityAliases() {
}
bool ELFNixPlatform::isInitializerSection(StringRef SecName) {
- for (auto &Name : InitSectionNames) {
- if (Name.equals(SecName))
- return true;
- }
+ if (SecName.consume_front(InitArrayFuncSectionName) &&
+ (SecName.empty() || SecName[0] == '.'))
+ return true;
return false;
}
bool ELFNixPlatform::supportedTarget(const Triple &TT) {
switch (TT.getArch()) {
case Triple::x86_64:
+ case Triple::aarch64:
return true;
default:
return false;
@@ -723,16 +778,15 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::preserveInitSections(
jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
JITLinkSymbolSet InitSectionSymbols;
- for (auto &InitSectionName : InitSectionNames) {
+ for (auto &InitSection : G.sections()) {
// Skip non-init sections.
- auto *InitSection = G.findSectionByName(InitSectionName);
- if (!InitSection)
+ if (!isInitializerSection(InitSection.getName()))
continue;
// Make a pass over live symbols in the section: those blocks are already
// preserved.
DenseSet<jitlink::Block *> AlreadyLiveBlocks;
- for (auto &Sym : InitSection->symbols()) {
+ for (auto &Sym : InitSection.symbols()) {
auto &B = Sym->getBlock();
if (Sym->isLive() && Sym->getOffset() == 0 &&
Sym->getSize() == B.getSize() && !AlreadyLiveBlocks.count(&B)) {
@@ -742,7 +796,7 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::preserveInitSections(
}
// Add anonymous symbols to preserve any not-already-preserved blocks.
- for (auto *B : InitSection->blocks())
+ for (auto *B : InitSection.blocks())
if (!AlreadyLiveBlocks.count(B))
InitSectionSymbols.insert(
&G.addAnonymousSymbol(*B, 0, B->getSize(), false, true));
@@ -763,9 +817,9 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
LLVM_DEBUG({ dbgs() << "ELFNixPlatform::registerInitSections\n"; });
- for (auto InitSectionName : InitSectionNames) {
- if (auto *Sec = G.findSectionByName(InitSectionName)) {
- InitSections.push_back(Sec);
+ for (auto &Sec : G.sections()) {
+ if (isInitializerSection(Sec.getName())) {
+ InitSections.push_back(&Sec);
}
}
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
index f3fe0555fa75..c591acdd646b 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp
@@ -45,7 +45,8 @@ createJITLoaderGDBRegistrar(ExecutionSession &ES) {
Error EPCDebugObjectRegistrar::registerDebugObject(
ExecutorAddrRange TargetMem) {
- return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(RegisterFn, TargetMem);
+ return ES.callSPSWrapper<void(shared::SPSExecutorAddrRange)>(RegisterFn,
+ TargetMem);
}
} // namespace orc
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp
index b901a2d2da23..48aaab96e71f 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp
@@ -88,7 +88,6 @@ EPCTrampolinePool::EPCTrampolinePool(EPCIndirectionUtils &EPCIU)
}
Error EPCTrampolinePool::deallocatePool() {
- Error Err = Error::success();
std::promise<MSVCPError> DeallocResultP;
auto DeallocResultF = DeallocResultP.get_future();
@@ -234,7 +233,7 @@ Error EPCIndirectStubsManager::updatePointer(StringRef Name,
namespace llvm {
namespace orc {
-EPCIndirectionUtils::ABISupport::~ABISupport() {}
+EPCIndirectionUtils::ABISupport::~ABISupport() = default;
Expected<std::unique_ptr<EPCIndirectionUtils>>
EPCIndirectionUtils::Create(ExecutorProcessControl &EPC) {
@@ -261,6 +260,9 @@ EPCIndirectionUtils::Create(ExecutorProcessControl &EPC) {
case Triple::mips64el:
return CreateWithABI<OrcMips64>(EPC);
+ case Triple::riscv64:
+ return CreateWithABI<OrcRiscv64>(EPC);
+
case Triple::x86_64:
if (TT.getOS() == Triple::OSType::Win32)
return CreateWithABI<OrcX86_64_Win32>(EPC);
@@ -302,7 +304,8 @@ EPCIndirectionUtils::writeResolverBlock(JITTargetAddress ReentryFnAddr,
return Alloc.takeError();
auto SegInfo = Alloc->getSegInfo(MemProt::Read | MemProt::Exec);
- ABI->writeResolverCode(SegInfo.WorkingMem.data(), SegInfo.Addr.getValue(),
+ ResolverBlockAddr = SegInfo.Addr.getValue();
+ ABI->writeResolverCode(SegInfo.WorkingMem.data(), ResolverBlockAddr,
ReentryFnAddr, ReentryCtxAddr);
auto FA = Alloc->finalize();
@@ -310,7 +313,7 @@ EPCIndirectionUtils::writeResolverBlock(JITTargetAddress ReentryFnAddr,
return FA.takeError();
ResolverBlock = std::move(*FA);
- return SegInfo.Addr.getValue();
+ return ResolverBlockAddr;
}
std::unique_ptr<IndirectStubsManager>
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index ae2d47fb8c5e..95cf89ec3f8b 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -62,7 +62,7 @@ CtorDtorIterator::Element CtorDtorIterator::operator*() const {
break;
} else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
if (CE->isCast())
- FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
+ FuncC = CE->getOperand(0);
else
break;
} else {
@@ -273,10 +273,10 @@ Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
StaticLibraryDefinitionGenerator::Load(
ObjectLayer &L, const char *FileName,
GetObjectFileInterface GetObjFileInterface) {
- auto ArchiveBuffer = errorOrToExpected(MemoryBuffer::getFile(FileName));
+ auto ArchiveBuffer = MemoryBuffer::getFile(FileName);
if (!ArchiveBuffer)
- return ArchiveBuffer.takeError();
+ return createFileError(FileName, ArchiveBuffer.getError());
return Create(L, std::move(*ArchiveBuffer), std::move(GetObjFileInterface));
}
@@ -288,7 +288,7 @@ StaticLibraryDefinitionGenerator::Load(
auto B = object::createBinary(FileName);
if (!B)
- return B.takeError();
+ return createFileError(FileName, B.takeError());
// If this is a regular archive then create an instance from it.
if (isa<object::Archive>(B->getBinary()))
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp
index 2eb835551adb..412b9f95ea62 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp
@@ -19,9 +19,9 @@
namespace llvm {
namespace orc {
-ExecutorProcessControl::MemoryAccess::~MemoryAccess() {}
+ExecutorProcessControl::MemoryAccess::~MemoryAccess() = default;
-ExecutorProcessControl::~ExecutorProcessControl() {}
+ExecutorProcessControl::~ExecutorProcessControl() = default;
SelfExecutorProcessControl::SelfExecutorProcessControl(
std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
diff --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
index aadc437c80c4..69aba1fff59a 100644
--- a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp
@@ -11,7 +11,7 @@
namespace llvm {
namespace orc {
-IRCompileLayer::IRCompiler::~IRCompiler() {}
+IRCompileLayer::IRCompiler::~IRCompiler() = default;
IRCompileLayer::IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
std::unique_ptr<IRCompiler> Compile)
diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index 7a71d2f781d7..38cab526704f 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -59,7 +59,7 @@ private:
namespace llvm {
namespace orc {
-TrampolinePool::~TrampolinePool() {}
+TrampolinePool::~TrampolinePool() = default;
void IndirectStubsManager::anchor() {}
Expected<JITTargetAddress>
@@ -152,6 +152,11 @@ createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES,
return CCMgrT::Create(ES, ErrorHandlerAddress);
}
+ case Triple::riscv64: {
+ typedef orc::LocalJITCompileCallbackManager<orc::OrcRiscv64> CCMgrT;
+ return CCMgrT::Create(ES, ErrorHandlerAddress);
+ }
+
case Triple::x86_64: {
if (T.getOS() == Triple::OSType::Win32) {
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT;
@@ -206,6 +211,12 @@ createLocalIndirectStubsManagerBuilder(const Triple &T) {
orc::LocalIndirectStubsManager<orc::OrcMips64>>();
};
+ case Triple::riscv64:
+ return []() {
+ return std::make_unique<
+ orc::LocalIndirectStubsManager<orc::OrcRiscv64>>();
+ };
+
case Triple::x86_64:
if (T.getOS() == Triple::OSType::Win32) {
return [](){
@@ -431,8 +442,7 @@ Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym,
auto RelocOffInInstr =
MIA.getMemoryOperandRelocationOffset(Instr, InstrSize);
- if (!RelocOffInInstr.hasValue() ||
- InstrSize - RelocOffInInstr.getValue() != 4) {
+ if (!RelocOffInInstr || InstrSize - *RelocOffInInstr != 4) {
LLVM_DEBUG(dbgs() << "Skipping unknown self-relocation at "
<< InstrStart);
continue;
diff --git a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
index 0fbf79b8a56d..c60f4b3b263c 100644
--- a/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp
@@ -19,6 +19,7 @@ JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
: TT(std::move(TT)) {
Options.EmulatedTLS = true;
Options.ExplicitEmulatedTLS = true;
+ Options.UseInitArray = true;
}
Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 91949c9d7eeb..6d67e6d87b56 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -143,7 +143,7 @@ public:
JITEvaluatedSymbol(pointerToJITTargetAddress(this),
JITSymbolFlags::Exported);
StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] =
- JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper),
+ JITEvaluatedSymbol(pointerToJITTargetAddress(registerCxaAtExitHelper),
JITSymbolFlags());
cantFail(
@@ -162,6 +162,9 @@ public:
PerJDInterposes[J.mangleAndIntern("__lljit.run_atexits_helper")] =
JITEvaluatedSymbol(pointerToJITTargetAddress(runAtExitsHelper),
JITSymbolFlags());
+ PerJDInterposes[J.mangleAndIntern("__lljit.atexit_helper")] =
+ JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper),
+ JITSymbolFlags());
cantFail(JD.define(absoluteSymbols(std::move(PerJDInterposes))));
auto Ctx = std::make_unique<LLVMContext>();
@@ -190,6 +193,14 @@ public:
GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper",
{PlatformInstanceDecl, DSOHandle});
+ auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
+ auto *AtExitCallbackTy = FunctionType::get(VoidTy, {}, false);
+ auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);
+ addHelperAndWrapper(*M, "atexit",
+ FunctionType::get(IntTy, {AtExitCallbackPtrTy}, false),
+ GlobalValue::HiddenVisibility, "__lljit.atexit_helper",
+ {PlatformInstanceDecl, DSOHandle});
+
return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx)));
}
@@ -413,16 +424,25 @@ private:
.takeError();
}
- static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx,
- void *DSOHandle) {
+ static void registerCxaAtExitHelper(void *Self, void (*F)(void *), void *Ctx,
+ void *DSOHandle) {
LLVM_DEBUG({
- dbgs() << "Registering atexit function " << (void *)F << " for JD "
+ dbgs() << "Registering cxa atexit function " << (void *)F << " for JD "
<< (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
});
static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
F, Ctx, DSOHandle);
}
+ static void registerAtExitHelper(void *Self, void *DSOHandle, void (*F)()) {
+ LLVM_DEBUG({
+ dbgs() << "Registering atexit function " << (void *)F << " for JD "
+ << (*static_cast<JITDylib **>(DSOHandle))->getName() << "\n";
+ });
+ static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(
+ reinterpret_cast<void (*)(void *)>(F), nullptr, DSOHandle);
+ }
+
static void runAtExitsHelper(void *Self, void *DSOHandle) {
LLVM_DEBUG({
dbgs() << "Running atexit functions for JD "
@@ -450,12 +470,12 @@ private:
auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);
auto *VoidTy = Type::getVoidTy(*Ctx);
auto *BytePtrTy = PointerType::getUnqual(Int8Ty);
- auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);
- auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);
+ auto *CxaAtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);
+ auto *CxaAtExitCallbackPtrTy = PointerType::getUnqual(CxaAtExitCallbackTy);
addHelperAndWrapper(
*M, "__cxa_atexit",
- FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy},
+ FunctionType::get(IntTy, {CxaAtExitCallbackPtrTy, BytePtrTy, BytePtrTy},
false),
GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper",
{PlatformInstanceDecl});
@@ -521,11 +541,7 @@ GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM,
for (auto E : COrDtors)
InitsOrDeInits.push_back(std::make_pair(E.Func, E.Priority));
- llvm::sort(InitsOrDeInits,
- [](const std::pair<Function *, unsigned> &LHS,
- const std::pair<Function *, unsigned> &RHS) {
- return LHS.first < RHS.first;
- });
+ llvm::sort(InitsOrDeInits, llvm::less_second());
auto *InitOrDeInitFuncEntryBlock =
BasicBlock::Create(Ctx, "entry", InitOrDeInitFunc);
@@ -589,7 +605,7 @@ void LLJIT::PlatformSupport::setInitTransform(
J.InitHelperTransformLayer->setTransform(std::move(T));
}
-LLJIT::PlatformSupport::~PlatformSupport() {}
+LLJIT::PlatformSupport::~PlatformSupport() = default;
Error LLJITBuilderState::prepareForConstruction() {
@@ -701,10 +717,14 @@ Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
return addObjectFile(JD.getDefaultResourceTracker(), std::move(Obj));
}
-Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
- SymbolStringPtr Name) {
- return ES->lookup(
- makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), Name);
+Expected<ExecutorAddr> LLJIT::lookupLinkerMangled(JITDylib &JD,
+ SymbolStringPtr Name) {
+ if (auto Sym = ES->lookup(
+ makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols),
+ Name))
+ return ExecutorAddr(Sym->getAddress());
+ else
+ return Sym.takeError();
}
Expected<std::unique_ptr<ObjectLayer>>
@@ -897,7 +917,7 @@ LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
LCTMgr = std::move(S.LCTMgr);
else {
if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
- S.TT, *ES, S.LazyCompileFailureAddr))
+ S.TT, *ES, S.LazyCompileFailureAddr.getValue()))
LCTMgr = std::move(*LCTMgrOrErr);
else {
Err = LCTMgrOrErr.takeError();
diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index adb8861793b1..4a50f2d7a153 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -19,7 +19,7 @@
namespace llvm {
namespace orc {
-IRLayer::~IRLayer() {}
+IRLayer::~IRLayer() = default;
Error IRLayer::add(ResourceTrackerSP RT, ThreadSafeModule TSM) {
assert(RT && "RT can not be null");
@@ -158,7 +158,7 @@ char ObjectLayer::ID;
ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
-ObjectLayer::~ObjectLayer() {}
+ObjectLayer::~ObjectLayer() = default;
Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O,
MaterializationUnit::Interface I) {
diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
index 66453e6a632f..20b655bdf4b1 100644
--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
@@ -131,6 +131,10 @@ createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES,
case Triple::mips64el:
return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
+ case Triple::riscv64:
+ return LocalLazyCallThroughManager::Create<OrcRiscv64>(ES,
+ ErrorHandlerAddr);
+
case Triple::x86_64:
if (T.getOS() == Triple::OSType::Win32)
return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
diff --git a/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp b/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
index 44cb78c773c9..3452267e4df4 100644
--- a/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp
@@ -24,7 +24,7 @@ void lookupAndRecordAddrs(
Symbols.add(KV.first, LookupFlags);
ES.lookup(
- K, SearchOrder, Symbols, SymbolState::Ready,
+ K, SearchOrder, std::move(Symbols), SymbolState::Ready,
[Pairs = std::move(Pairs),
OnRec = std::move(OnRecorded)](Expected<SymbolMap> Result) mutable {
if (!Result)
@@ -47,7 +47,7 @@ Error lookupAndRecordAddrs(
std::promise<MSVCPError> ResultP;
auto ResultF = ResultP.get_future();
lookupAndRecordAddrs([&](Error Err) { ResultP.set_value(std::move(Err)); },
- ES, K, SearchOrder, Pairs, LookupFlags);
+ ES, K, SearchOrder, std::move(Pairs), LookupFlags);
return ResultF.get();
}
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index a364719855b4..d5274b06a76f 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -22,6 +22,39 @@ using namespace llvm;
using namespace llvm::orc;
using namespace llvm::orc::shared;
+namespace llvm {
+namespace orc {
+namespace shared {
+
+using SPSMachOJITDylibDepInfo = SPSTuple<bool, SPSSequence<SPSExecutorAddr>>;
+using SPSMachOJITDylibDepInfoMap =
+ SPSSequence<SPSTuple<SPSExecutorAddr, SPSMachOJITDylibDepInfo>>;
+
+template <>
+class SPSSerializationTraits<SPSMachOJITDylibDepInfo,
+ MachOPlatform::MachOJITDylibDepInfo> {
+public:
+ static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI) {
+ return SPSMachOJITDylibDepInfo::AsArgList::size(DDI.Sealed, DDI.DepHeaders);
+ }
+
+ static bool serialize(SPSOutputBuffer &OB,
+ const MachOPlatform::MachOJITDylibDepInfo &DDI) {
+ return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.Sealed,
+ DDI.DepHeaders);
+ }
+
+ static bool deserialize(SPSInputBuffer &IB,
+ MachOPlatform::MachOJITDylibDepInfo &DDI) {
+ return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.Sealed,
+ DDI.DepHeaders);
+ }
+};
+
+} // namespace shared
+} // namespace orc
+} // namespace llvm
+
namespace {
class MachOHeaderMaterializationUnit : public MaterializationUnit {
@@ -199,11 +232,25 @@ MachOPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
}
Error MachOPlatform::setupJITDylib(JITDylib &JD) {
- return JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
- *this, MachOHeaderStartSymbol));
+ if (auto Err = JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
+ *this, MachOHeaderStartSymbol)))
+ return Err;
+
+ return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
}
-Error MachOPlatform::teardownJITDylib(JITDylib &JD) { return Error::success(); }
+Error MachOPlatform::teardownJITDylib(JITDylib &JD) {
+ std::lock_guard<std::mutex> Lock(PlatformMutex);
+ auto I = JITDylibToHeaderAddr.find(&JD);
+ if (I != JITDylibToHeaderAddr.end()) {
+ assert(HeaderAddrToJITDylib.count(I->second) &&
+ "HeaderAddrToJITDylib missing entry");
+ HeaderAddrToJITDylib.erase(I->second);
+ JITDylibToHeaderAddr.erase(I);
+ }
+ JITDylibToPThreadKey.erase(&JD);
+ return Error::success();
+}
Error MachOPlatform::notifyAdding(ResourceTracker &RT,
const MaterializationUnit &MU) {
@@ -255,6 +302,10 @@ MachOPlatform::standardRuntimeUtilityAliases() {
static const std::pair<const char *, const char *>
StandardRuntimeUtilityAliases[] = {
{"___orc_rt_run_program", "___orc_rt_macho_run_program"},
+ {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
+ {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
+ {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
+ {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
{"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
return ArrayRef<std::pair<const char *, const char *>>(
@@ -305,16 +356,6 @@ MachOPlatform::MachOPlatform(
State = BootstrapPhase2;
- // PlatformJD hasn't been 'set-up' by the platform yet (since we're creating
- // the platform now), so set it up.
- if (auto E2 = setupJITDylib(PlatformJD)) {
- Err = std::move(E2);
- return;
- }
-
- RegisteredInitSymbols[&PlatformJD].add(
- MachOHeaderStartSymbol, SymbolLookupFlags::WeaklyReferencedSymbol);
-
// Associate wrapper function tags with JIT-side function implementations.
if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
Err = std::move(E2);
@@ -329,23 +370,24 @@ MachOPlatform::MachOPlatform(
return;
}
+ // PlatformJD hasn't been set up by the platform yet (since we're creating
+ // the platform now), so set it up.
+ if (auto E2 = setupJITDylib(PlatformJD)) {
+ Err = std::move(E2);
+ return;
+ }
+
State = Initialized;
}
Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
ExecutionSession::JITDispatchHandlerAssociationMap WFs;
- using GetInitializersSPSSig =
- SPSExpected<SPSMachOJITDylibInitializerSequence>(SPSString);
- WFs[ES.intern("___orc_rt_macho_get_initializers_tag")] =
- ES.wrapAsyncWithSPS<GetInitializersSPSSig>(
- this, &MachOPlatform::rt_getInitializers);
-
- using GetDeinitializersSPSSig =
- SPSExpected<SPSMachOJITDylibDeinitializerSequence>(SPSExecutorAddr);
- WFs[ES.intern("___orc_rt_macho_get_deinitializers_tag")] =
- ES.wrapAsyncWithSPS<GetDeinitializersSPSSig>(
- this, &MachOPlatform::rt_getDeinitializers);
+ using PushInitializersSPSSig =
+ SPSExpected<SPSMachOJITDylibDepInfoMap>(SPSExecutorAddr);
+ WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =
+ ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
+ this, &MachOPlatform::rt_pushInitializers);
using LookupSymbolSPSSig =
SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSString);
@@ -356,53 +398,83 @@ Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
}
-void MachOPlatform::getInitializersBuildSequencePhase(
- SendInitializerSequenceFn SendResult, JITDylib &JD,
- std::vector<JITDylibSP> DFSLinkOrder) {
- MachOJITDylibInitializerSequence FullInitSeq;
- {
- std::lock_guard<std::mutex> Lock(PlatformMutex);
- for (auto &InitJD : reverse(DFSLinkOrder)) {
- LLVM_DEBUG({
- dbgs() << "MachOPlatform: Appending inits for \"" << InitJD->getName()
- << "\" to sequence\n";
- });
- auto ISItr = InitSeqs.find(InitJD.get());
- if (ISItr != InitSeqs.end()) {
- FullInitSeq.emplace_back(std::move(ISItr->second));
- InitSeqs.erase(ISItr);
- }
- }
- }
+void MachOPlatform::pushInitializersLoop(
+ PushInitializersSendResultFn SendResult, JITDylibSP JD) {
+ DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
+ DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;
+ SmallVector<JITDylib *, 16> Worklist({JD.get()});
- SendResult(std::move(FullInitSeq));
-}
+ ES.runSessionLocked([&]() {
+ while (!Worklist.empty()) {
+ // FIXME: Check for defunct dylibs.
-void MachOPlatform::getInitializersLookupPhase(
- SendInitializerSequenceFn SendResult, JITDylib &JD) {
+ auto DepJD = Worklist.back();
+ Worklist.pop_back();
- auto DFSLinkOrder = JD.getDFSLinkOrder();
- if (!DFSLinkOrder) {
- SendResult(DFSLinkOrder.takeError());
- return;
- }
+ // If we've already visited this JITDylib on this iteration then continue.
+ if (JDDepMap.count(DepJD))
+ continue;
- DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
- ES.runSessionLocked([&]() {
- for (auto &InitJD : *DFSLinkOrder) {
- auto RISItr = RegisteredInitSymbols.find(InitJD.get());
+ // Add dep info.
+ auto &DM = JDDepMap[DepJD];
+ DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
+ for (auto &KV : O) {
+ if (KV.first == DepJD)
+ continue;
+ DM.push_back(KV.first);
+ Worklist.push_back(KV.first);
+ }
+ });
+
+ // Add any registered init symbols.
+ auto RISItr = RegisteredInitSymbols.find(DepJD);
if (RISItr != RegisteredInitSymbols.end()) {
- NewInitSymbols[InitJD.get()] = std::move(RISItr->second);
+ NewInitSymbols[DepJD] = std::move(RISItr->second);
RegisteredInitSymbols.erase(RISItr);
}
}
});
- // If there are no further init symbols to look up then move on to the next
- // phase.
+ // If there are no further init symbols to look up then send the link order
+ // (as a list of header addresses) to the caller.
if (NewInitSymbols.empty()) {
- getInitializersBuildSequencePhase(std::move(SendResult), JD,
- std::move(*DFSLinkOrder));
+
+ // To make the list intelligible to the runtime we need to convert all
+ // JITDylib pointers to their header addresses.
+ DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
+ HeaderAddrs.reserve(JDDepMap.size());
+ {
+ std::lock_guard<std::mutex> Lock(PlatformMutex);
+ for (auto &KV : JDDepMap) {
+ auto I = JITDylibToHeaderAddr.find(KV.first);
+ if (I == JITDylibToHeaderAddr.end()) {
+ // The header address should have been materialized by the previous
+ // round, but we need to handle the pathalogical case where someone
+ // removes the symbol on another thread while we're running.
+ SendResult(
+ make_error<StringError>("JITDylib " + KV.first->getName() +
+ " has no registered header address",
+ inconvertibleErrorCode()));
+ return;
+ }
+ HeaderAddrs[KV.first] = I->second;
+ }
+ }
+
+ // Build the dep info map to return.
+ MachOJITDylibDepInfoMap DIM;
+ DIM.reserve(JDDepMap.size());
+ for (auto &KV : JDDepMap) {
+ assert(HeaderAddrs.count(KV.first) && "Missing header addr");
+ auto H = HeaderAddrs[KV.first];
+ MachOJITDylibDepInfo DepInfo;
+ for (auto &Dep : KV.second) {
+ assert(HeaderAddrs.count(Dep) && "Missing header addr");
+ DepInfo.DepHeaders.push_back(HeaderAddrs[Dep]);
+ }
+ DIM.push_back(std::make_pair(H, std::move(DepInfo)));
+ }
+ SendResult(DIM);
return;
}
@@ -412,58 +484,38 @@ void MachOPlatform::getInitializersLookupPhase(
if (Err)
SendResult(std::move(Err));
else
- getInitializersLookupPhase(std::move(SendResult), JD);
+ pushInitializersLoop(std::move(SendResult), JD);
},
ES, std::move(NewInitSymbols));
}
-void MachOPlatform::rt_getInitializers(SendInitializerSequenceFn SendResult,
- StringRef JDName) {
- LLVM_DEBUG({
- dbgs() << "MachOPlatform::rt_getInitializers(\"" << JDName << "\")\n";
- });
-
- JITDylib *JD = ES.getJITDylibByName(JDName);
- if (!JD) {
- LLVM_DEBUG({
- dbgs() << " No such JITDylib \"" << JDName << "\". Sending error.\n";
- });
- SendResult(make_error<StringError>("No JITDylib named " + JDName,
- inconvertibleErrorCode()));
- return;
- }
-
- getInitializersLookupPhase(std::move(SendResult), *JD);
-}
-
-void MachOPlatform::rt_getDeinitializers(SendDeinitializerSequenceFn SendResult,
- ExecutorAddr Handle) {
- LLVM_DEBUG({
- dbgs() << "MachOPlatform::rt_getDeinitializers(\""
- << formatv("{0:x}", Handle.getValue()) << "\")\n";
- });
-
- JITDylib *JD = nullptr;
-
+void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
+ ExecutorAddr JDHeaderAddr) {
+ JITDylibSP JD;
{
std::lock_guard<std::mutex> Lock(PlatformMutex);
- auto I = HeaderAddrToJITDylib.find(Handle);
+ auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
if (I != HeaderAddrToJITDylib.end())
JD = I->second;
}
+ LLVM_DEBUG({
+ dbgs() << "MachOPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";
+ if (JD)
+ dbgs() << "pushing initializers for " << JD->getName() << "\n";
+ else
+ dbgs() << "No JITDylib for header address.\n";
+ });
+
if (!JD) {
- LLVM_DEBUG({
- dbgs() << " No JITDylib for handle "
- << formatv("{0:x}", Handle.getValue()) << "\n";
- });
- SendResult(make_error<StringError>("No JITDylib associated with handle " +
- formatv("{0:x}", Handle.getValue()),
- inconvertibleErrorCode()));
+ SendResult(
+ make_error<StringError>("No JITDylib with header addr " +
+ formatv("{0:x}", JDHeaderAddr.getValue()),
+ inconvertibleErrorCode()));
return;
}
- SendResult(MachOJITDylibDeinitializerSequence());
+ pushInitializersLoop(std::move(SendResult), JD);
}
void MachOPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
@@ -526,10 +578,14 @@ Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
&orc_rt_macho_platform_bootstrap},
{ES.intern("___orc_rt_macho_platform_shutdown"),
&orc_rt_macho_platform_shutdown},
- {ES.intern("___orc_rt_macho_register_thread_data_section"),
- &orc_rt_macho_register_thread_data_section},
- {ES.intern("___orc_rt_macho_deregister_thread_data_section"),
- &orc_rt_macho_deregister_thread_data_section},
+ {ES.intern("___orc_rt_macho_register_jitdylib"),
+ &orc_rt_macho_register_jitdylib},
+ {ES.intern("___orc_rt_macho_deregister_jitdylib"),
+ &orc_rt_macho_deregister_jitdylib},
+ {ES.intern("___orc_rt_macho_register_object_platform_sections"),
+ &orc_rt_macho_register_object_platform_sections},
+ {ES.intern("___orc_rt_macho_deregister_object_platform_sections"),
+ &orc_rt_macho_deregister_object_platform_sections},
{ES.intern("___orc_rt_macho_create_pthread_key"),
&orc_rt_macho_create_pthread_key}}))
return Err;
@@ -537,45 +593,6 @@ Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
return ES.callSPSWrapper<void()>(orc_rt_macho_platform_bootstrap);
}
-Error MachOPlatform::registerInitInfo(
- JITDylib &JD, ExecutorAddr ObjCImageInfoAddr,
- ArrayRef<jitlink::Section *> InitSections) {
-
- std::unique_lock<std::mutex> Lock(PlatformMutex);
-
- MachOJITDylibInitializers *InitSeq = nullptr;
- {
- auto I = InitSeqs.find(&JD);
- if (I == InitSeqs.end()) {
- // If there's no init sequence entry yet then we need to look up the
- // header symbol to force creation of one.
- Lock.unlock();
-
- auto SearchOrder =
- JD.withLinkOrderDo([](const JITDylibSearchOrder &SO) { return SO; });
- if (auto Err = ES.lookup(SearchOrder, MachOHeaderStartSymbol).takeError())
- return Err;
-
- Lock.lock();
- I = InitSeqs.find(&JD);
- assert(I != InitSeqs.end() &&
- "Entry missing after header symbol lookup?");
- }
- InitSeq = &I->second;
- }
-
- InitSeq->ObjCImageInfoAddress = ObjCImageInfoAddr;
-
- for (auto *Sec : InitSections) {
- // FIXME: Avoid copy here.
- jitlink::SectionRange R(*Sec);
- InitSeq->InitSections[Sec->getName()].push_back(
- {ExecutorAddr(R.getStart()), ExecutorAddr(R.getEnd())});
- }
-
- return Error::success();
-}
-
Expected<uint64_t> MachOPlatform::createPThreadKey() {
if (!orc_rt_macho_create_pthread_key)
return make_error<StringError>(
@@ -617,11 +634,6 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
return Err;
return processObjCImageInfo(G, MR);
});
-
- Config.PostFixupPasses.push_back(
- [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
- return registerInitSections(G, JD);
- });
}
// --- Add passes for eh-frame and TLV support ---
@@ -639,10 +651,12 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
return fixTLVSectionsAndEdges(G, JD);
});
- // Add a pass to register the final addresses of the eh-frame and TLV sections
- // with the runtime.
- Config.PostFixupPasses.push_back(
- [this](jitlink::LinkGraph &G) { return registerEHAndTLVSections(G); });
+ // Add a pass to register the final addresses of any special sections in the
+ // object with the runtime.
+ Config.PostAllocationPasses.push_back(
+ [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
+ return registerObjectPlatformSections(G, JD);
+ });
}
ObjectLinkingLayer::Plugin::SyntheticSymbolDependenciesMap
@@ -661,7 +675,6 @@ MachOPlatform::MachOPlatformPlugin::getSyntheticSymbolDependencies(
Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
-
auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
return Sym->getName() == *MP.MachOHeaderStartSymbol;
});
@@ -670,10 +683,14 @@ Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
auto &JD = MR.getTargetJITDylib();
std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
auto HeaderAddr = (*I)->getAddress();
+ MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
- assert(!MP.InitSeqs.count(&JD) && "InitSeq entry for JD already exists");
- MP.InitSeqs.insert(
- std::make_pair(&JD, MachOJITDylibInitializers(JD.getName(), HeaderAddr)));
+ G.allocActions().push_back(
+ {cantFail(
+ WrapperFunctionCall::Create<SPSArgList<SPSString, SPSExecutorAddr>>(
+ MP.orc_rt_macho_register_jitdylib, JD.getName(), HeaderAddr)),
+ cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
+ MP.orc_rt_macho_deregister_jitdylib, HeaderAddr))});
return Error::success();
}
@@ -792,37 +809,6 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
return Error::success();
}
-Error MachOPlatform::MachOPlatformPlugin::registerInitSections(
- jitlink::LinkGraph &G, JITDylib &JD) {
-
- ExecutorAddr ObjCImageInfoAddr;
- SmallVector<jitlink::Section *> InitSections;
-
- if (auto *ObjCImageInfoSec = G.findSectionByName(ObjCImageInfoSectionName)) {
- if (auto Addr = jitlink::SectionRange(*ObjCImageInfoSec).getStart())
- ObjCImageInfoAddr = Addr;
- }
-
- for (auto InitSectionName : InitSectionNames)
- if (auto *Sec = G.findSectionByName(InitSectionName))
- InitSections.push_back(Sec);
-
- // Dump the scraped inits.
- LLVM_DEBUG({
- dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
- if (ObjCImageInfoAddr)
- dbgs() << " " << ObjCImageInfoSectionName << ": "
- << formatv("{0:x}", ObjCImageInfoAddr.getValue()) << "\n";
- for (auto *Sec : InitSections) {
- jitlink::SectionRange R(*Sec);
- dbgs() << " " << Sec->getName() << ": "
- << formatv("[ {0:x} -- {1:x} ]", R.getStart(), R.getEnd()) << "\n";
- }
- });
-
- return MP.registerInitInfo(JD, ObjCImageInfoAddr, InitSections);
-}
-
Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
jitlink::LinkGraph &G, JITDylib &JD) {
@@ -879,11 +865,10 @@ Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
return Error::success();
}
-Error MachOPlatform::MachOPlatformPlugin::registerEHAndTLVSections(
- jitlink::LinkGraph &G) {
+Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
+ jitlink::LinkGraph &G, JITDylib &JD) {
- // Add a pass to register the final addresses of the eh-frame and TLV sections
- // with the runtime.
+ // Add an action to register the eh-frame.
if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
jitlink::SectionRange R(*EHFrameSection);
if (!R.empty())
@@ -912,6 +897,8 @@ Error MachOPlatform::MachOPlatformPlugin::registerEHAndTLVSections(
ThreadDataSection = ThreadBSSSection;
}
+ SmallVector<std::pair<StringRef, ExecutorAddrRange>, 8> MachOPlatformSecs;
+
// Having merged thread BSS (if present) and thread data (if present),
// record the resulting section range.
if (ThreadDataSection) {
@@ -922,16 +909,64 @@ Error MachOPlatform::MachOPlatformPlugin::registerEHAndTLVSections(
"MachOPlatform has not finished booting",
inconvertibleErrorCode());
- G.allocActions().push_back(
- {cantFail(
- WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
- MP.orc_rt_macho_register_thread_data_section, R.getRange())),
- cantFail(
- WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
- MP.orc_rt_macho_deregister_thread_data_section,
- R.getRange()))});
+ MachOPlatformSecs.push_back({ThreadDataSectionName, R.getRange()});
+ }
+ }
+
+ // If any platform sections were found then add an allocation action to call
+ // the registration function.
+ StringRef PlatformSections[] = {
+ ModInitFuncSectionName, ObjCClassListSectionName,
+ ObjCImageInfoSectionName, ObjCSelRefsSectionName,
+ Swift5ProtoSectionName, Swift5ProtosSectionName,
+ Swift5TypesSectionName,
+ };
+
+ for (auto &SecName : PlatformSections) {
+ auto *Sec = G.findSectionByName(SecName);
+ if (!Sec)
+ continue;
+ jitlink::SectionRange R(*Sec);
+ if (R.empty())
+ continue;
+
+ MachOPlatformSecs.push_back({SecName, R.getRange()});
+ }
+
+ if (!MachOPlatformSecs.empty()) {
+ Optional<ExecutorAddr> HeaderAddr;
+ {
+ std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
+ auto I = MP.JITDylibToHeaderAddr.find(&JD);
+ if (I != MP.JITDylibToHeaderAddr.end())
+ HeaderAddr = I->second;
}
+
+ if (!HeaderAddr)
+ return make_error<StringError>("Missing header for " + JD.getName(),
+ inconvertibleErrorCode());
+
+ // Dump the scraped inits.
+ LLVM_DEBUG({
+ dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
+ for (auto &KV : MachOPlatformSecs)
+ dbgs() << " " << KV.first << ": " << KV.second << "\n";
+ });
+
+ using SPSRegisterObjectPlatformSectionsArgs =
+ SPSArgList<SPSExecutorAddr,
+ SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;
+ G.allocActions().push_back(
+ {cantFail(
+ WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
+ MP.orc_rt_macho_register_object_platform_sections, *HeaderAddr,
+ MachOPlatformSecs)),
+ cantFail(
+ WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
+ MP.orc_rt_macho_deregister_object_platform_sections,
+ *HeaderAddr, MachOPlatformSecs))});
}
+
return Error::success();
}
diff --git a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
new file mode 100644
index 000000000000..8b3fbd7117e2
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
@@ -0,0 +1,152 @@
+//===- MemoryMapper.cpp - Cross-process memory mapper ------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/MemoryMapper.h"
+
+namespace llvm {
+namespace orc {
+
+MemoryMapper::~MemoryMapper() {}
+
+void InProcessMemoryMapper::reserve(size_t NumBytes,
+ OnReservedFunction OnReserved) {
+ std::error_code EC;
+ auto MB = sys::Memory::allocateMappedMemory(
+ NumBytes, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
+
+ if (EC)
+ return OnReserved(errorCodeToError(EC));
+
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ Reservations[MB.base()].Size = MB.allocatedSize();
+ }
+
+ OnReserved(
+ ExecutorAddrRange(ExecutorAddr::fromPtr(MB.base()), MB.allocatedSize()));
+}
+
+char *InProcessMemoryMapper::prepare(ExecutorAddr Addr, size_t ContentSize) {
+ return Addr.toPtr<char *>();
+}
+
+void InProcessMemoryMapper::initialize(MemoryMapper::AllocInfo &AI,
+ OnInitializedFunction OnInitialized) {
+ ExecutorAddr MinAddr(~0ULL);
+
+ for (auto &Segment : AI.Segments) {
+ auto Base = AI.MappingBase + Segment.Offset;
+ auto Size = Segment.ContentSize + Segment.ZeroFillSize;
+
+ if (Base < MinAddr)
+ MinAddr = Base;
+
+ std::memset((Base + Segment.ContentSize).toPtr<void *>(), 0,
+ Segment.ZeroFillSize);
+
+ if (auto EC = sys::Memory::protectMappedMemory({Base.toPtr<void *>(), Size},
+ Segment.Prot)) {
+ return OnInitialized(errorCodeToError(EC));
+ }
+ if (Segment.Prot & sys::Memory::MF_EXEC)
+ sys::Memory::InvalidateInstructionCache(Base.toPtr<void *>(), Size);
+ }
+
+ auto DeinitializeActions = shared::runFinalizeActions(AI.Actions);
+ if (!DeinitializeActions)
+ return OnInitialized(DeinitializeActions.takeError());
+
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ Allocations[MinAddr].DeinitializationActions =
+ std::move(*DeinitializeActions);
+ Reservations[AI.MappingBase.toPtr<void *>()].Allocations.push_back(MinAddr);
+ }
+
+ OnInitialized(MinAddr);
+}
+
+void InProcessMemoryMapper::deinitialize(
+ ArrayRef<ExecutorAddr> Bases,
+ MemoryMapper::OnDeinitializedFunction OnDeinitialized) {
+ Error AllErr = Error::success();
+
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+
+ for (auto Base : Bases) {
+
+ if (Error Err = shared::runDeallocActions(
+ Allocations[Base].DeinitializationActions)) {
+ AllErr = joinErrors(std::move(AllErr), std::move(Err));
+ }
+
+ Allocations.erase(Base);
+ }
+ }
+
+ OnDeinitialized(std::move(AllErr));
+}
+
+void InProcessMemoryMapper::release(ArrayRef<ExecutorAddr> Bases,
+ OnReleasedFunction OnReleased) {
+ Error Err = Error::success();
+
+ for (auto Base : Bases) {
+ std::vector<ExecutorAddr> AllocAddrs;
+ size_t Size;
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ auto &R = Reservations[Base.toPtr<void *>()];
+ Size = R.Size;
+ AllocAddrs.swap(R.Allocations);
+ }
+
+ // deinitialize sub allocations
+ std::promise<MSVCPError> P;
+ auto F = P.get_future();
+ deinitialize(AllocAddrs, [&](Error Err) { P.set_value(std::move(Err)); });
+ if (Error E = F.get()) {
+ Err = joinErrors(std::move(Err), std::move(E));
+ }
+
+ // free the memory
+ auto MB = sys::MemoryBlock(Base.toPtr<void *>(), Size);
+
+ auto EC = sys::Memory::releaseMappedMemory(MB);
+ if (EC) {
+ Err = joinErrors(std::move(Err), errorCodeToError(EC));
+ }
+
+ std::lock_guard<std::mutex> Lock(Mutex);
+ Reservations.erase(Base.toPtr<void *>());
+ }
+
+ OnReleased(std::move(Err));
+}
+
+InProcessMemoryMapper::~InProcessMemoryMapper() {
+ std::vector<ExecutorAddr> ReservationAddrs;
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+
+ ReservationAddrs.reserve(Reservations.size());
+ for (const auto &R : Reservations) {
+ ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
+ }
+ }
+
+ std::promise<MSVCPError> P;
+ auto F = P.get_future();
+ release(ReservationAddrs, [&](Error Err) { P.set_value(std::move(Err)); });
+ cantFail(F.get());
+}
+
+} // namespace orc
+
+} // namespace llvm
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
index c1ad569dd65d..394a555e453b 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
@@ -63,7 +63,6 @@ getMachOObjectFileSymbolInfo(ExecutionSession &ES,
auto Name = Sym.getName();
if (!Name)
return Name.takeError();
- auto InternedName = ES.intern(*Name);
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
if (!SymFlags)
return SymFlags.takeError();
@@ -72,7 +71,7 @@ getMachOObjectFileSymbolInfo(ExecutionSession &ES,
if (Name->startswith("l"))
*SymFlags &= ~JITSymbolFlags::Exported;
- I.SymbolFlags[InternedName] = std::move(*SymFlags);
+ I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
}
for (auto &Sec : Obj.sections()) {
@@ -121,7 +120,7 @@ getELFObjectFileSymbolInfo(ExecutionSession &ES,
auto Name = Sym.getName();
if (!Name)
return Name.takeError();
- auto InternedName = ES.intern(*Name);
+
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
if (!SymFlags)
return SymFlags.takeError();
@@ -130,7 +129,7 @@ getELFObjectFileSymbolInfo(ExecutionSession &ES,
if (Sym.getBinding() == ELF::STB_GNU_UNIQUE)
*SymFlags |= JITSymbolFlags::Weak;
- I.SymbolFlags[InternedName] = std::move(*SymFlags);
+ I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
}
SymbolStringPtr InitSymbol;
@@ -175,12 +174,12 @@ getGenericObjectFileSymbolInfo(ExecutionSession &ES,
auto Name = Sym.getName();
if (!Name)
return Name.takeError();
- auto InternedName = ES.intern(*Name);
+
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
if (!SymFlags)
return SymFlags.takeError();
- I.SymbolFlags[InternedName] = std::move(*SymFlags);
+ I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
}
return I;
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 32c5998a789b..5ddb35cbafd5 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -78,9 +78,12 @@ private:
}
static bool hasELFInitSection(LinkGraph &G) {
- for (auto &Sec : G.sections())
- if (Sec.getName() == ".init_array")
+ for (auto &Sec : G.sections()) {
+ auto SecName = Sec.getName();
+ if (SecName.consume_front(".init_array") &&
+ (SecName.empty() || SecName[0] == '.'))
return true;
+ }
return false;
}
@@ -226,12 +229,13 @@ public:
}
for (auto *Sym : G.absolute_symbols())
- if (Sym->hasName()) {
+ if (Sym->hasName() && Sym->getScope() != Scope::Local) {
auto InternedName = ES.intern(Sym->getName());
JITSymbolFlags Flags;
- Flags |= JITSymbolFlags::Absolute;
if (Sym->isCallable())
Flags |= JITSymbolFlags::Callable;
+ if (Sym->getScope() == Scope::Default)
+ Flags |= JITSymbolFlags::Exported;
if (Sym->getLinkage() == Linkage::Weak)
Flags |= JITSymbolFlags::Weak;
InternedResult[InternedName] =
@@ -607,7 +611,7 @@ private:
DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
};
-ObjectLinkingLayer::Plugin::~Plugin() {}
+ObjectLinkingLayer::Plugin::~Plugin() = default;
char ObjectLinkingLayer::ID;
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
index 18b3c5e12b1c..ef764a3f0d7f 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
@@ -906,5 +906,176 @@ void OrcMips64::writeIndirectStubsBlock(
Stub[8 * I + 7] = 0x00000000; // nop
}
}
+
+void OrcRiscv64::writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) {
+
+ const uint32_t ResolverCode[] = {
+ 0xef810113, // 0x00: addi sp,sp,-264
+ 0x00813023, // 0x04: sd s0,0(sp)
+ 0x00913423, // 0x08: sd s1,8(sp)
+ 0x01213823, // 0x0c: sd s2,16(sp)
+ 0x01313c23, // 0x10: sd s3,24(sp)
+ 0x03413023, // 0x14: sd s4,32(sp)
+ 0x03513423, // 0x18: sd s5,40(sp)
+ 0x03613823, // 0x1c: sd s6,48(sp)
+ 0x03713c23, // 0x20: sd s7,56(sp)
+ 0x05813023, // 0x24: sd s8,64(sp)
+ 0x05913423, // 0x28: sd s9,72(sp)
+ 0x05a13823, // 0x2c: sd s10,80(sp)
+ 0x05b13c23, // 0x30: sd s11,88(sp)
+ 0x06113023, // 0x34: sd ra,96(sp)
+ 0x06a13423, // 0x38: sd a0,104(sp)
+ 0x06b13823, // 0x3c: sd a1,112(sp)
+ 0x06c13c23, // 0x40: sd a2,120(sp)
+ 0x08d13023, // 0x44: sd a3,128(sp)
+ 0x08e13423, // 0x48: sd a4,136(sp)
+ 0x08f13823, // 0x4c: sd a5,144(sp)
+ 0x09013c23, // 0x50: sd a6,152(sp)
+ 0x0b113023, // 0x54: sd a7,160(sp)
+ 0x0a813427, // 0x58: fsd fs0,168(sp)
+ 0x0a913827, // 0x5c: fsd fs1,176(sp)
+ 0x0b213c27, // 0x60: fsd fs2,184(sp)
+ 0x0d313027, // 0x64: fsd fs3,192(sp)
+ 0x0d413427, // 0x68: fsd fs4,200(sp)
+ 0x0d513827, // 0x6c: fsd fs5,208(sp)
+ 0x0d613c27, // 0x70: fsd fs6,216(sp)
+ 0x0f713027, // 0x74: fsd fs7,224(sp)
+ 0x0f813427, // 0x78: fsd fs8,232(sp)
+ 0x0f913827, // 0x7c: fsd fs9,240(sp)
+ 0x0fa13c27, // 0x80: fsd fs10,248(sp)
+ 0x11b13027, // 0x84: fsd fs11,256(sp)
+ 0x00000517, // 0x88: auipc a0,0x0
+ 0x0b053503, // 0x8c: ld a0,176(a0) # 0x138
+ 0x00030593, // 0x90: mv a1,t1
+ 0xff458593, // 0x94: addi a1,a1,-12
+ 0x00000617, // 0x98: auipc a2,0x0
+ 0x0a863603, // 0x9c: ld a2,168(a2) # 0x140
+ 0x000600e7, // 0xa0: jalr a2
+ 0x00050293, // 0xa4: mv t0,a0
+ 0x00013403, // 0xa8: ld s0,0(sp)
+ 0x00813483, // 0xac: ld s1,8(sp)
+ 0x01013903, // 0xb0: ld s2,16(sp)
+ 0x01813983, // 0xb4: ld s3,24(sp)
+ 0x02013a03, // 0xb8: ld s4,32(sp)
+ 0x02813a83, // 0xbc: ld s5,40(sp)
+ 0x03013b03, // 0xc0: ld s6,48(sp)
+ 0x03813b83, // 0xc4: ld s7,56(sp)
+ 0x04013c03, // 0xc8: ld s8,64(sp)
+ 0x04813c83, // 0xcc: ld s9,72(sp)
+ 0x05013d03, // 0xd0: ld s10,80(sp)
+ 0x05813d83, // 0xd4: ld s11,88(sp)
+ 0x06013083, // 0xd8: ld ra,96(sp)
+ 0x06813503, // 0xdc: ld a0,104(sp)
+ 0x07013583, // 0xe0: ld a1,112(sp)
+ 0x07813603, // 0xe4: ld a2,120(sp)
+ 0x08013683, // 0xe8: ld a3,128(sp)
+ 0x08813703, // 0xec: ld a4,136(sp)
+ 0x09013783, // 0xf0: ld a5,144(sp)
+ 0x09813803, // 0xf4: ld a6,152(sp)
+ 0x0a013883, // 0xf8: ld a7,160(sp)
+ 0x0a813407, // 0xfc: fld fs0,168(sp)
+ 0x0b013487, // 0x100: fld fs1,176(sp)
+ 0x0b813907, // 0x104: fld fs2,184(sp)
+ 0x0c013987, // 0x108: fld fs3,192(sp)
+ 0x0c813a07, // 0x10c: fld fs4,200(sp)
+ 0x0d013a87, // 0x110: fld fs5,208(sp)
+ 0x0d813b07, // 0x114: fld fs6,216(sp)
+ 0x0e013b87, // 0x118: fld fs7,224(sp)
+ 0x0e813c07, // 0x11c: fld fs8,232(sp)
+ 0x0f013c87, // 0x120: fld fs9,240(sp)
+ 0x0f813d07, // 0x124: fld fs10,248(sp)
+ 0x10013d87, // 0x128: fld fs11,256(sp)
+ 0x10810113, // 0x12c: addi sp,sp,264
+ 0x00028067, // 0x130: jr t0
+ 0x12345678, // 0x134: padding to align at 8 byte
+ 0x12345678, // 0x138: Lreentry_ctx_ptr:
+ 0xdeadbeef, // 0x13c: .quad 0
+ 0x98765432, // 0x140: Lreentry_fn_ptr:
+ 0xcafef00d // 0x144: .quad 0
+ };
+
+ const unsigned ReentryCtxAddrOffset = 0x138;
+ const unsigned ReentryFnAddrOffset = 0x140;
+
+ memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
+ memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
+ sizeof(uint64_t));
+ memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
+ sizeof(uint64_t));
+}
+
+void OrcRiscv64::writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines) {
+
+ unsigned OffsetToPtr = alignTo(NumTrampolines * TrampolineSize, 8);
+
+ memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
+ sizeof(uint64_t));
+
+ uint32_t *Trampolines =
+ reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
+ for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) {
+ uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xFFFFF000;
+ uint32_t Lo12 = OffsetToPtr - Hi20;
+ Trampolines[4 * I + 0] = 0x00000297 | Hi20; // auipc t0, %hi(Lptr)
+ Trampolines[4 * I + 1] =
+ 0x0002b283 | ((Lo12 & 0xFFF) << 20); // ld t0, %lo(Lptr)
+ Trampolines[4 * I + 2] = 0x00028367; // jalr t1, t0
+ Trampolines[4 * I + 3] = 0xdeadface; // padding
+ }
+}
+
+void OrcRiscv64::writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) {
+ // Stub format is:
+ //
+ // .section __orc_stubs
+ // stub1:
+ // auipc t0, %hi(ptr1) ; PC-rel load of ptr1
+ // ld t0, %lo(t0)
+ // jr t0 ; Jump to resolver
+ // .quad 0 ; Pad to 16 bytes
+ // stub2:
+ // auipc t0, %hi(ptr1) ; PC-rel load of ptr1
+ // ld t0, %lo(t0)
+ // jr t0 ; Jump to resolver
+ // .quad 0
+ //
+ // ...
+ //
+ // .section __orc_ptrs
+ // ptr1:
+ // .quad 0x0
+ // ptr2:
+ // .quad 0x0
+ //
+ // ...
+
+ assert(stubAndPointerRangesOk<OrcRiscv64>(
+ StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
+ "PointersBlock is out of range");
+
+ uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlockWorkingMem);
+
+ for (unsigned I = 0; I < NumStubs; ++I) {
+ uint64_t PtrDisplacement =
+ PointersBlockTargetAddress - StubsBlockTargetAddress;
+ uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xFFFFF000;
+ uint32_t Lo12 = PtrDisplacement - Hi20;
+ Stub[4 * I + 0] = 0x00000297 | Hi20; // auipc t0, %hi(Lptr)
+ Stub[4 * I + 1] = 0x0002b283 | ((Lo12 & 0xFFF) << 20); // ld t0, %lo(Lptr)
+ Stub[4 * I + 2] = 0x00028067; // jr t0
+ Stub[4 * I + 3] = 0xfeedbeef; // padding
+ PointersBlockTargetAddress += PointerSize;
+ StubsBlockTargetAddress += StubSize;
+ }
+}
+
} // End namespace orc.
} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
index 71be8dfdc004..b7eab6b85ecf 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
@@ -106,82 +106,6 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
-namespace llvm {
-namespace orc {
-
-class CAPIDefinitionGenerator final : public DefinitionGenerator {
-public:
- CAPIDefinitionGenerator(
- void *Ctx,
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
- : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
-
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags,
- const SymbolLookupSet &LookupSet) override {
-
- // Take the lookup state.
- LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
-
- // Translate the lookup kind.
- LLVMOrcLookupKind CLookupKind;
- switch (K) {
- case LookupKind::Static:
- CLookupKind = LLVMOrcLookupKindStatic;
- break;
- case LookupKind::DLSym:
- CLookupKind = LLVMOrcLookupKindDLSym;
- break;
- }
-
- // Translate the JITDylibSearchFlags.
- LLVMOrcJITDylibLookupFlags CJDLookupFlags;
- switch (JDLookupFlags) {
- case JITDylibLookupFlags::MatchExportedSymbolsOnly:
- CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
- break;
- case JITDylibLookupFlags::MatchAllSymbols:
- CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
- break;
- }
-
- // Translate the lookup set.
- std::vector<LLVMOrcCLookupSetElement> CLookupSet;
- CLookupSet.reserve(LookupSet.size());
- for (auto &KV : LookupSet) {
- LLVMOrcSymbolLookupFlags SLF;
- LLVMOrcSymbolStringPoolEntryRef Name =
- ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
- switch (KV.second) {
- case SymbolLookupFlags::RequiredSymbol:
- SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
- break;
- case SymbolLookupFlags::WeaklyReferencedSymbol:
- SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
- break;
- }
- CLookupSet.push_back({Name, SLF});
- }
-
- // Run the C TryToGenerate function.
- auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
- ::wrap(&JD), CJDLookupFlags,
- CLookupSet.data(), CLookupSet.size()));
-
- // Restore the lookup state.
- OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
-
- return Err;
- }
-
-private:
- void *Ctx;
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
namespace {
class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit {
@@ -282,8 +206,134 @@ toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) {
return SDM;
}
+static LookupKind toLookupKind(LLVMOrcLookupKind K) {
+ switch (K) {
+ case LLVMOrcLookupKindStatic:
+ return LookupKind::Static;
+ case LLVMOrcLookupKindDLSym:
+ return LookupKind::DLSym;
+ }
+ llvm_unreachable("unrecognized LLVMOrcLookupKind value");
+}
+
+static LLVMOrcLookupKind fromLookupKind(LookupKind K) {
+ switch (K) {
+ case LookupKind::Static:
+ return LLVMOrcLookupKindStatic;
+ case LookupKind::DLSym:
+ return LLVMOrcLookupKindDLSym;
+ }
+ llvm_unreachable("unrecognized LookupKind value");
+}
+
+static JITDylibLookupFlags
+toJITDylibLookupFlags(LLVMOrcJITDylibLookupFlags LF) {
+ switch (LF) {
+ case LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly:
+ return JITDylibLookupFlags::MatchExportedSymbolsOnly;
+ case LLVMOrcJITDylibLookupFlagsMatchAllSymbols:
+ return JITDylibLookupFlags::MatchAllSymbols;
+ }
+ llvm_unreachable("unrecognized LLVMOrcJITDylibLookupFlags value");
+}
+
+static LLVMOrcJITDylibLookupFlags
+fromJITDylibLookupFlags(JITDylibLookupFlags LF) {
+ switch (LF) {
+ case JITDylibLookupFlags::MatchExportedSymbolsOnly:
+ return LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
+ case JITDylibLookupFlags::MatchAllSymbols:
+ return LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
+ }
+ llvm_unreachable("unrecognized JITDylibLookupFlags value");
+}
+
+static SymbolLookupFlags toSymbolLookupFlags(LLVMOrcSymbolLookupFlags SLF) {
+ switch (SLF) {
+ case LLVMOrcSymbolLookupFlagsRequiredSymbol:
+ return SymbolLookupFlags::RequiredSymbol;
+ case LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol:
+ return SymbolLookupFlags::WeaklyReferencedSymbol;
+ }
+ llvm_unreachable("unrecognized LLVMOrcSymbolLookupFlags value");
+}
+
+static LLVMOrcSymbolLookupFlags fromSymbolLookupFlags(SymbolLookupFlags SLF) {
+ switch (SLF) {
+ case SymbolLookupFlags::RequiredSymbol:
+ return LLVMOrcSymbolLookupFlagsRequiredSymbol;
+ case SymbolLookupFlags::WeaklyReferencedSymbol:
+ return LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
+ }
+ llvm_unreachable("unrecognized SymbolLookupFlags value");
+}
+
+static LLVMJITEvaluatedSymbol
+fromJITEvaluatedSymbol(const JITEvaluatedSymbol &S) {
+ return {S.getAddress(), fromJITSymbolFlags(S.getFlags())};
+}
+
} // end anonymous namespace
+namespace llvm {
+namespace orc {
+
+class CAPIDefinitionGenerator final : public DefinitionGenerator {
+public:
+ CAPIDefinitionGenerator(
+ LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose, void *Ctx,
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
+ : Dispose(Dispose), Ctx(Ctx), TryToGenerate(TryToGenerate) {}
+
+ ~CAPIDefinitionGenerator() {
+ if (Dispose)
+ Dispose(Ctx);
+ }
+
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) override {
+
+ // Take the lookup state.
+ LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
+
+ // Translate the lookup kind.
+ LLVMOrcLookupKind CLookupKind = fromLookupKind(K);
+
+ // Translate the JITDylibLookupFlags.
+ LLVMOrcJITDylibLookupFlags CJDLookupFlags =
+ fromJITDylibLookupFlags(JDLookupFlags);
+
+ // Translate the lookup set.
+ std::vector<LLVMOrcCLookupSetElement> CLookupSet;
+ CLookupSet.reserve(LookupSet.size());
+ for (auto &KV : LookupSet) {
+ LLVMOrcSymbolStringPoolEntryRef Name =
+ ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
+ LLVMOrcSymbolLookupFlags SLF = fromSymbolLookupFlags(KV.second);
+ CLookupSet.push_back({Name, SLF});
+ }
+
+ // Run the C TryToGenerate function.
+ auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
+ ::wrap(&JD), CJDLookupFlags,
+ CLookupSet.data(), CLookupSet.size()));
+
+ // Restore the lookup state.
+ OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
+
+ return Err;
+ }
+
+private:
+ LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose;
+ void *Ctx;
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
void LLVMOrcExecutionSessionSetErrorReporter(
LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
void *Ctx) {
@@ -307,6 +357,42 @@ LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name)));
}
+void LLVMOrcExecutionSessionLookup(
+ LLVMOrcExecutionSessionRef ES, LLVMOrcLookupKind K,
+ LLVMOrcCJITDylibSearchOrder SearchOrder, size_t SearchOrderSize,
+ LLVMOrcCLookupSet Symbols, size_t SymbolsSize,
+ LLVMOrcExecutionSessionLookupHandleResultFunction HandleResult, void *Ctx) {
+ assert(ES && "ES cannot be null");
+ assert(SearchOrder && "SearchOrder cannot be null");
+ assert(Symbols && "Symbols cannot be null");
+ assert(HandleResult && "HandleResult cannot be null");
+
+ JITDylibSearchOrder SO;
+ for (size_t I = 0; I != SearchOrderSize; ++I)
+ SO.push_back({unwrap(SearchOrder[I].JD),
+ toJITDylibLookupFlags(SearchOrder[I].JDLookupFlags)});
+
+ SymbolLookupSet SLS;
+ for (size_t I = 0; I != SymbolsSize; ++I)
+ SLS.add(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Symbols[I].Name)),
+ toSymbolLookupFlags(Symbols[I].LookupFlags));
+
+ unwrap(ES)->lookup(
+ toLookupKind(K), SO, std::move(SLS), SymbolState::Ready,
+ [HandleResult, Ctx](Expected<SymbolMap> Result) {
+ if (Result) {
+ SmallVector<LLVMOrcCSymbolMapPair> CResult;
+ for (auto &KV : *Result)
+ CResult.push_back(LLVMOrcCSymbolMapPair{
+ wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first)),
+ fromJITEvaluatedSymbol(KV.second)});
+ HandleResult(LLVMErrorSuccess, CResult.data(), CResult.size(), Ctx);
+ } else
+ HandleResult(wrap(Result.takeError()), nullptr, 0, Ctx);
+ },
+ NoDependenciesToRegister);
+}
+
void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
}
@@ -589,11 +675,19 @@ void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
}
LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) {
- auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx,
+ LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose) {
+ auto DG = std::make_unique<CAPIDefinitionGenerator>(Dispose, Ctx, F);
return wrap(DG.release());
}
+void LLVMOrcLookupStateContinueLookup(LLVMOrcLookupStateRef S,
+ LLVMErrorRef Err) {
+ LookupState LS;
+ OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(S));
+ LS.continueLookup(unwrap(Err));
+}
+
LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix,
LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
@@ -951,7 +1045,7 @@ LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
return wrap(Sym.takeError());
}
- *Result = Sym->getAddress();
+ *Result = Sym->getValue();
return LLVMErrorSuccess;
}
diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
index 64fc717b7b56..2bb204e688fc 100644
--- a/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
@@ -43,8 +43,8 @@ const char *DispatchFnName = "__llvm_orc_SimpleRemoteEPC_dispatch_fn";
} // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
-SimpleRemoteEPCTransportClient::~SimpleRemoteEPCTransportClient() {}
-SimpleRemoteEPCTransport::~SimpleRemoteEPCTransport() {}
+SimpleRemoteEPCTransportClient::~SimpleRemoteEPCTransportClient() = default;
+SimpleRemoteEPCTransport::~SimpleRemoteEPCTransport() = default;
Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
FDSimpleRemoteEPCTransport::Create(SimpleRemoteEPCTransportClient &C, int InFD,
diff --git a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
index 0b4755fe23cf..b52d01318c0d 100644
--- a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp
@@ -85,7 +85,7 @@ void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
auto IRNames = QueryAnalysis(Fn);
// Instrument and register if Query has result
- if (IRNames.hasValue()) {
+ if (IRNames) {
// Emit globals for each function.
auto LoadValueTy = Type::getInt8Ty(MContext);
@@ -126,7 +126,7 @@ void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
assert(Mutator.GetInsertBlock()->getParent() == &Fn &&
"IR builder association mismatch?");
- S.registerSymbols(internToJITSymbols(IRNames.getValue()),
+ S.registerSymbols(internToJITSymbols(*IRNames),
&R->getTargetJITDylib());
}
}
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
index b6b21bde1182..8ab0af3eab6e 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp
@@ -22,9 +22,9 @@ using namespace llvm::orc::shared;
namespace llvm {
namespace orc {
-ExecutorBootstrapService::~ExecutorBootstrapService() {}
+ExecutorBootstrapService::~ExecutorBootstrapService() = default;
-SimpleRemoteEPCServer::Dispatcher::~Dispatcher() {}
+SimpleRemoteEPCServer::Dispatcher::~Dispatcher() = default;
#if LLVM_ENABLE_THREADS
void SimpleRemoteEPCServer::ThreadDispatcher::dispatch(
diff --git a/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp b/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp
index 111c84ec87ed..11a99986f2ee 100644
--- a/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp
@@ -16,7 +16,7 @@ char GenericNamedTask::ID = 0;
const char *GenericNamedTask::DefaultDescription = "Generic Task";
void Task::anchor() {}
-TaskDispatcher::~TaskDispatcher() {}
+TaskDispatcher::~TaskDispatcher() = default;
void InPlaceTaskDispatcher::dispatch(std::unique_ptr<Task> T) { T->run(); }
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
index 9c8d402364c6..bc42eebf3fec 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
@@ -29,7 +29,7 @@
namespace llvm {
-RTDyldMemoryManager::~RTDyldMemoryManager() {}
+RTDyldMemoryManager::~RTDyldMemoryManager() = default;
#if defined(HAVE_REGISTER_FRAME) && defined(HAVE_DEREGISTER_FRAME) && \
!defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
@@ -95,18 +95,16 @@ void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr,
// and projects/libunwind/src/UnwindLevel1-gcc-ext.c.
const char *P = (const char *)Addr;
const char *End = P + Size;
- do {
+ while (P != End)
P = processFDE(P, false);
- } while(P != End);
}
void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr,
size_t Size) {
const char *P = (const char *)Addr;
const char *End = P + Size;
- do {
+ while (P != End)
P = processFDE(P, true);
- } while(P != End);
}
#else
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 3f38d26869d4..2e0cba849165 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -66,7 +66,7 @@ std::error_code RuntimeDyldError::convertToErrorCode() const {
}
// Empty out-of-line virtual destructor as the key function.
-RuntimeDyldImpl::~RuntimeDyldImpl() {}
+RuntimeDyldImpl::~RuntimeDyldImpl() = default;
// Pin LoadedObjectInfo's vtables to this file.
void RuntimeDyld::LoadedObjectInfo::anchor() {}
@@ -1311,7 +1311,7 @@ RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
ProcessAllSections = false;
}
-RuntimeDyld::~RuntimeDyld() {}
+RuntimeDyld::~RuntimeDyld() = default;
static std::unique_ptr<RuntimeDyldCOFF>
createRuntimeDyldCOFF(
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 33db23408cf2..ae1bb5a1da4b 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include <cctype>
#include <memory>
@@ -892,7 +893,7 @@ RuntimeDyldChecker::RuntimeDyldChecker(
std::move(GetGOTInfo), Endianness, Disassembler, InstPrinter,
ErrStream)) {}
-RuntimeDyldChecker::~RuntimeDyldChecker() {}
+RuntimeDyldChecker::~RuntimeDyldChecker() = default;
bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
return Impl->check(CheckExpr);
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index f92618afdff6..da1102fc9f07 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -216,7 +216,7 @@ namespace llvm {
RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
JITSymbolResolver &Resolver)
: RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
-RuntimeDyldELF::~RuntimeDyldELF() {}
+RuntimeDyldELF::~RuntimeDyldELF() = default;
void RuntimeDyldELF::registerEHFrames() {
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
@@ -446,6 +446,13 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
write(isBE, TargetPtr, static_cast<uint32_t>(Result));
break;
}
+ case ELF::R_AARCH64_PREL16: {
+ uint64_t Result = Value + Addend - FinalAddress;
+ assert(static_cast<int64_t>(Result) >= INT16_MIN &&
+ static_cast<int64_t>(Result) <= UINT16_MAX);
+ write(isBE, TargetPtr, static_cast<uint16_t>(Result & 0xffffU));
+ break;
+ }
case ELF::R_AARCH64_PREL32: {
uint64_t Result = Value + Addend - FinalAddress;
assert(static_cast<int64_t>(Result) >= INT32_MIN &&
diff --git a/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp b/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp
index 56b232b9dbcd..b23e33039c35 100644
--- a/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp
@@ -238,7 +238,7 @@ SectionMemoryManager::~SectionMemoryManager() {
}
}
-SectionMemoryManager::MemoryMapper::~MemoryMapper() {}
+SectionMemoryManager::MemoryMapper::~MemoryMapper() = default;
void SectionMemoryManager::anchor() {}