14#define DEBUG_TYPE "orc"
26 {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},
27 {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
28 {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
30 rt::SimpleExecutorMemoryManagerDeallocateWrapperName},
31 {SAs.RegisterEHFrame, rt::RegisterEHFrameSectionWrapperName},
32 {SAs.DeregisterEHFrame, rt::DeregisterEHFrameSectionWrapperName}}))
33 return std::move(Err);
34 return std::make_unique<EPCGenericRTDyldMemoryManager>(EPC, std::move(SAs));
37EPCGenericRTDyldMemoryManager::EPCGenericRTDyldMemoryManager(
39 : EPC(EPC), SAs(
std::
move(SAs)) {
40 LLVM_DEBUG(
dbgs() <<
"Created remote allocator " << (
void *)
this <<
"\n");
44 LLVM_DEBUG(
dbgs() <<
"Destroyed remote allocator " << (
void *)
this <<
"\n");
46 errs() <<
"Destroying with existing errors:\n" << ErrMsg <<
"\n";
62 uintptr_t
Size,
unsigned Alignment,
unsigned SectionID,
64 std::lock_guard<std::mutex> Lock(M);
66 dbgs() <<
"Allocator " << (
void *)
this <<
" allocating code section "
68 <<
" bytes, alignment = " << Alignment <<
"\n";
70 auto &Seg = Unmapped.back().CodeAllocs;
71 Seg.emplace_back(
Size, Alignment);
72 return reinterpret_cast<uint8_t *
>(
77 uintptr_t
Size,
unsigned Alignment,
unsigned SectionID,
79 std::lock_guard<std::mutex> Lock(M);
81 dbgs() <<
"Allocator " << (
void *)
this <<
" allocating "
82 << (IsReadOnly ?
"ro" :
"rw") <<
"-data section " <<
SectionName
83 <<
": size = " <<
formatv(
"{0:x}",
Size) <<
" bytes, alignment "
84 << Alignment <<
")\n";
88 IsReadOnly ? Unmapped.back().RODataAllocs : Unmapped.back().RWDataAllocs;
90 Seg.emplace_back(
Size, Alignment);
91 return reinterpret_cast<uint8_t *
>(
96 uintptr_t CodeSize,
Align CodeAlign, uintptr_t RODataSize,
97 Align RODataAlign, uintptr_t RWDataSize,
Align RWDataAlign) {
100 std::lock_guard<std::mutex> Lock(M);
106 ErrMsg =
"Invalid code alignment in reserveAllocationSpace";
110 ErrMsg =
"Invalid ro-data alignment in reserveAllocationSpace";
114 ErrMsg =
"Invalid rw-data alignment in reserveAllocationSpace";
125 dbgs() <<
"Allocator " << (
void *)
this <<
" reserving "
126 <<
formatv(
"{0:x}", TotalSize) <<
" bytes.\n";
133 std::lock_guard<std::mutex> Lock(M);
137 if (!TargetAllocAddr) {
138 std::lock_guard<std::mutex> Lock(M);
139 ErrMsg =
toString(TargetAllocAddr.takeError());
143 std::lock_guard<std::mutex> Lock(M);
144 Unmapped.push_back(SectionAllocGroup());
145 Unmapped.back().RemoteCode = {
147 Unmapped.back().RemoteROData = {
148 Unmapped.back().RemoteCode.End,
150 Unmapped.back().RemoteRWData = {
151 Unmapped.back().RemoteROData.End,
163 dbgs() <<
"Allocator " << (
void *)
this <<
" added unfinalized eh-frame "
164 <<
formatv(
"[ {0:x} {1:x} ]", LoadAddr, LoadAddr +
Size) <<
"\n";
166 std::lock_guard<std::mutex> Lock(M);
173 if (SecAllocGroup.RemoteCode.contains(LA) ||
174 SecAllocGroup.RemoteROData.contains(LA) ||
175 SecAllocGroup.RemoteRWData.contains(LA)) {
176 SecAllocGroup.UnfinalizedEHFrames.push_back({LA,
Size});
180 ErrMsg =
"eh-frame does not lie inside unfinalized alloc";
189 std::lock_guard<std::mutex> Lock(M);
190 LLVM_DEBUG(
dbgs() <<
"Allocator " << (
void *)
this <<
" applied mappings:\n");
191 for (
auto &ObjAllocs : Unmapped) {
192 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs,
193 ObjAllocs.RemoteCode.Start);
194 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RODataAllocs,
195 ObjAllocs.RemoteROData.Start);
196 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RWDataAllocs,
197 ObjAllocs.RemoteRWData.Start);
198 Unfinalized.push_back(std::move(ObjAllocs));
204 LLVM_DEBUG(
dbgs() <<
"Allocator " << (
void *)
this <<
" finalizing:\n");
207 std::vector<SectionAllocGroup> SecAllocGroups;
209 std::lock_guard<std::mutex> Lock(M);
210 if (ErrMsg && !this->ErrMsg.empty()) {
211 *ErrMsg = std::move(this->ErrMsg);
218 for (
auto &SecAllocGroup : SecAllocGroups) {
224 &SecAllocGroup.RemoteROData,
225 &SecAllocGroup.RemoteRWData};
227 std::vector<SectionAlloc> *SegSections[3] = {&SecAllocGroup.CodeAllocs,
228 &SecAllocGroup.RODataAllocs,
229 &SecAllocGroup.RWDataAllocs};
232 std::unique_ptr<char[]> AggregateContents[3];
234 for (
unsigned I = 0;
I != 3; ++
I) {
237 Seg.RAG = SegMemProts[
I];
238 Seg.Addr = RemoteAddrs[
I]->
Start;
239 for (
auto &SecAlloc : *SegSections[
I]) {
240 Seg.Size =
alignTo(Seg.Size, SecAlloc.Align);
241 Seg.Size += SecAlloc.Size;
243 AggregateContents[
I] = std::make_unique<char[]>(Seg.Size);
244 size_t SecOffset = 0;
245 for (
auto &SecAlloc : *SegSections[
I]) {
246 SecOffset =
alignTo(SecOffset, SecAlloc.Align);
247 memcpy(&AggregateContents[
I][SecOffset],
248 reinterpret_cast<const char *
>(
251 SecOffset += SecAlloc.Size;
255 Seg.Content = {AggregateContents[
I].get(), SecOffset};
258 for (
auto &Frame : SecAllocGroup.UnfinalizedEHFrames)
273 std::lock_guard<std::mutex> Lock(M);
274 this->ErrMsg =
toString(std::move(Err));
275 dbgs() <<
"Serialization error: " << this->ErrMsg <<
"\n";
277 *ErrMsg = this->ErrMsg;
281 std::lock_guard<std::mutex> Lock(M);
282 this->ErrMsg =
toString(std::move(FinalizeErr));
283 dbgs() <<
"Finalization error: " << this->ErrMsg <<
"\n";
285 *ErrMsg = this->ErrMsg;
293void EPCGenericRTDyldMemoryManager::mapAllocsToRemoteAddrs(
294 RuntimeDyld &Dyld, std::vector<SectionAlloc> &Allocs,
296 for (
auto &
Alloc : Allocs) {
299 dbgs() <<
" " <<
static_cast<void *
>(
Alloc.Contents.get()) <<
" -> "
305 Alloc.RemoteAddr = NextAddr;
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
StringRef - Represent a constant reference to a string, i.e.
This class is the base class for all object file types.
uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly) override
Allocate a memory block of (at least) the given size suitable for data.
bool finalizeMemory(std::string *ErrMsg=nullptr) override
This method is called when object loading is complete and section page permissions can be applied.
bool needsToReserveAllocationSpace() override
Override to return true to enable the reserveAllocationSpace callback.
~EPCGenericRTDyldMemoryManager()
static Expected< std::unique_ptr< EPCGenericRTDyldMemoryManager > > CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC)
Create an EPCGenericRTDyldMemoryManager using the given EPC, looking up the default symbol names in t...
void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, uintptr_t RODataSize, Align RODataAlign, uintptr_t RWDataSize, Align RWDataAlign) override
Inform the memory manager about the total amount of memory required to allocate all sections to be lo...
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override
Register the EH frames with the runtime so that c++ exceptions work.
void notifyObjectLoaded(RuntimeDyld &Dyld, const object::ObjectFile &Obj) override
This method is called after an object has been loaded into memory but before relocations are applied ...
void deregisterEHFrames() override
uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override
Allocate a memory block of (at least) the given size suitable for executable code.
Represents an address in the executor process.
uint64_t getValue() const
void setValue(uint64_t Addr)
ExecutorProcessControl supports interaction with a JIT target process.
unsigned getPageSize() const
Get the page size for the target process.
Error callSPSWrapper(ExecutorAddr WrapperFnAddr, WrapperCallArgTs &&...WrapperCallArgs)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
Error getBootstrapSymbols(ArrayRef< std::pair< ExecutorAddr &, StringRef > > Pairs) const
For each (ExecutorAddr&, StringRef) pair, looks up the string in the bootstrap symbols map and writes...
A utility class for serializing to a blob from a variadic list.
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, uint64_t) SPSSimpleExecutorMemoryManagerReserveSignature
shared::SPSError(shared::SPSExecutorAddr, shared::SPSFinalizeRequest) SPSSimpleExecutorMemoryManagerFinalizeSignature
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSSimpleExecutorMemoryManagerDeallocateSignature
MemProt
Describes Read/Write/Exec permissions for memory.
uint64_t ExecutorAddrDiff
This is an optimization pass for GlobalISel generic memory operations.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
const char * toString(DWARFSectionKind Kind)
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Symbol addresses for memory access.
ExecutorAddr DeregisterEHFrame
ExecutorAddr RegisterEHFrame
Represents an address range in the exceutor process.
std::vector< SegFinalizeRequest > Segments
shared::AllocActions Actions