1349cc55cSDimitry Andric //===----- EPCGenericRTDyldMemoryManager.cpp - EPC-bbasde MemMgr -----===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
10349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
11349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12349cc55cSDimitry Andric #include "llvm/Support/Alignment.h"
13349cc55cSDimitry Andric #include "llvm/Support/FormatVariadic.h"
14349cc55cSDimitry Andric 
15349cc55cSDimitry Andric #define DEBUG_TYPE "orc"
16349cc55cSDimitry Andric 
1704eeddc0SDimitry Andric using namespace llvm::orc::shared;
1804eeddc0SDimitry Andric 
19349cc55cSDimitry Andric namespace llvm {
20349cc55cSDimitry Andric namespace orc {
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric Expected<std::unique_ptr<EPCGenericRTDyldMemoryManager>>
CreateWithDefaultBootstrapSymbols(ExecutorProcessControl & EPC)23349cc55cSDimitry Andric EPCGenericRTDyldMemoryManager::CreateWithDefaultBootstrapSymbols(
24349cc55cSDimitry Andric     ExecutorProcessControl &EPC) {
25349cc55cSDimitry Andric   SymbolAddrs SAs;
26349cc55cSDimitry Andric   if (auto Err = EPC.getBootstrapSymbols(
27349cc55cSDimitry Andric           {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},
28349cc55cSDimitry Andric            {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
29349cc55cSDimitry Andric            {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
30349cc55cSDimitry Andric            {SAs.Deallocate,
31349cc55cSDimitry Andric             rt::SimpleExecutorMemoryManagerDeallocateWrapperName},
3204eeddc0SDimitry Andric            {SAs.RegisterEHFrame, rt::RegisterEHFrameSectionWrapperName},
3304eeddc0SDimitry Andric            {SAs.DeregisterEHFrame, rt::DeregisterEHFrameSectionWrapperName}}))
34349cc55cSDimitry Andric     return std::move(Err);
35349cc55cSDimitry Andric   return std::make_unique<EPCGenericRTDyldMemoryManager>(EPC, std::move(SAs));
36349cc55cSDimitry Andric }
37349cc55cSDimitry Andric 
EPCGenericRTDyldMemoryManager(ExecutorProcessControl & EPC,SymbolAddrs SAs)38349cc55cSDimitry Andric EPCGenericRTDyldMemoryManager::EPCGenericRTDyldMemoryManager(
39349cc55cSDimitry Andric     ExecutorProcessControl &EPC, SymbolAddrs SAs)
40349cc55cSDimitry Andric     : EPC(EPC), SAs(std::move(SAs)) {
41349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "Created remote allocator " << (void *)this << "\n");
42349cc55cSDimitry Andric }
43349cc55cSDimitry Andric 
~EPCGenericRTDyldMemoryManager()44349cc55cSDimitry Andric EPCGenericRTDyldMemoryManager::~EPCGenericRTDyldMemoryManager() {
45349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << (void *)this << "\n");
46349cc55cSDimitry Andric   if (!ErrMsg.empty())
47349cc55cSDimitry Andric     errs() << "Destroying with existing errors:\n" << ErrMsg << "\n";
48349cc55cSDimitry Andric 
49349cc55cSDimitry Andric   Error Err = Error::success();
50349cc55cSDimitry Andric   if (auto Err2 = EPC.callSPSWrapper<
51349cc55cSDimitry Andric                   rt::SPSSimpleExecutorMemoryManagerDeallocateSignature>(
52349cc55cSDimitry Andric           SAs.Reserve, Err, SAs.Instance, FinalizedAllocs)) {
53349cc55cSDimitry Andric     // FIXME: Report errors through EPC once that functionality is available.
54349cc55cSDimitry Andric     logAllUnhandledErrors(std::move(Err2), errs(), "");
55349cc55cSDimitry Andric     return;
56349cc55cSDimitry Andric   }
57349cc55cSDimitry Andric 
58349cc55cSDimitry Andric   if (Err)
59349cc55cSDimitry Andric     logAllUnhandledErrors(std::move(Err), errs(), "");
60349cc55cSDimitry Andric }
61349cc55cSDimitry Andric 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)62349cc55cSDimitry Andric uint8_t *EPCGenericRTDyldMemoryManager::allocateCodeSection(
63349cc55cSDimitry Andric     uintptr_t Size, unsigned Alignment, unsigned SectionID,
64349cc55cSDimitry Andric     StringRef SectionName) {
65349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
66349cc55cSDimitry Andric   LLVM_DEBUG({
67349cc55cSDimitry Andric     dbgs() << "Allocator " << (void *)this << " allocating code section "
68349cc55cSDimitry Andric            << SectionName << ": size = " << formatv("{0:x}", Size)
69349cc55cSDimitry Andric            << " bytes, alignment = " << Alignment << "\n";
70349cc55cSDimitry Andric   });
71349cc55cSDimitry Andric   auto &Seg = Unmapped.back().CodeAllocs;
72349cc55cSDimitry Andric   Seg.emplace_back(Size, Alignment);
73349cc55cSDimitry Andric   return reinterpret_cast<uint8_t *>(
74349cc55cSDimitry Andric       alignAddr(Seg.back().Contents.get(), Align(Alignment)));
75349cc55cSDimitry Andric }
76349cc55cSDimitry Andric 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)77349cc55cSDimitry Andric uint8_t *EPCGenericRTDyldMemoryManager::allocateDataSection(
78349cc55cSDimitry Andric     uintptr_t Size, unsigned Alignment, unsigned SectionID,
79349cc55cSDimitry Andric     StringRef SectionName, bool IsReadOnly) {
80349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
81349cc55cSDimitry Andric   LLVM_DEBUG({
82349cc55cSDimitry Andric     dbgs() << "Allocator " << (void *)this << " allocating "
83349cc55cSDimitry Andric            << (IsReadOnly ? "ro" : "rw") << "-data section " << SectionName
84349cc55cSDimitry Andric            << ": size = " << formatv("{0:x}", Size) << " bytes, alignment "
85349cc55cSDimitry Andric            << Alignment << ")\n";
86349cc55cSDimitry Andric   });
87349cc55cSDimitry Andric 
88349cc55cSDimitry Andric   auto &Seg =
89349cc55cSDimitry Andric       IsReadOnly ? Unmapped.back().RODataAllocs : Unmapped.back().RWDataAllocs;
90349cc55cSDimitry Andric 
91349cc55cSDimitry Andric   Seg.emplace_back(Size, Alignment);
92349cc55cSDimitry Andric   return reinterpret_cast<uint8_t *>(
93349cc55cSDimitry Andric       alignAddr(Seg.back().Contents.get(), Align(Alignment)));
94349cc55cSDimitry Andric }
95349cc55cSDimitry Andric 
reserveAllocationSpace(uintptr_t CodeSize,Align CodeAlign,uintptr_t RODataSize,Align RODataAlign,uintptr_t RWDataSize,Align RWDataAlign)96349cc55cSDimitry Andric void EPCGenericRTDyldMemoryManager::reserveAllocationSpace(
97bdd1243dSDimitry Andric     uintptr_t CodeSize, Align CodeAlign, uintptr_t RODataSize,
98bdd1243dSDimitry Andric     Align RODataAlign, uintptr_t RWDataSize, Align RWDataAlign) {
99349cc55cSDimitry Andric 
100349cc55cSDimitry Andric   {
101349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(M);
102349cc55cSDimitry Andric     // If there's already an error then bail out.
103349cc55cSDimitry Andric     if (!ErrMsg.empty())
104349cc55cSDimitry Andric       return;
105349cc55cSDimitry Andric 
106bdd1243dSDimitry Andric     if (CodeAlign > EPC.getPageSize()) {
107349cc55cSDimitry Andric       ErrMsg = "Invalid code alignment in reserveAllocationSpace";
108349cc55cSDimitry Andric       return;
109349cc55cSDimitry Andric     }
110bdd1243dSDimitry Andric     if (RODataAlign > EPC.getPageSize()) {
111349cc55cSDimitry Andric       ErrMsg = "Invalid ro-data alignment in reserveAllocationSpace";
112349cc55cSDimitry Andric       return;
113349cc55cSDimitry Andric     }
114bdd1243dSDimitry Andric     if (RWDataAlign > EPC.getPageSize()) {
115349cc55cSDimitry Andric       ErrMsg = "Invalid rw-data alignment in reserveAllocationSpace";
116349cc55cSDimitry Andric       return;
117349cc55cSDimitry Andric     }
118349cc55cSDimitry Andric   }
119349cc55cSDimitry Andric 
120349cc55cSDimitry Andric   uint64_t TotalSize = 0;
121349cc55cSDimitry Andric   TotalSize += alignTo(CodeSize, EPC.getPageSize());
122349cc55cSDimitry Andric   TotalSize += alignTo(RODataSize, EPC.getPageSize());
123349cc55cSDimitry Andric   TotalSize += alignTo(RWDataSize, EPC.getPageSize());
124349cc55cSDimitry Andric 
125349cc55cSDimitry Andric   LLVM_DEBUG({
126349cc55cSDimitry Andric     dbgs() << "Allocator " << (void *)this << " reserving "
127349cc55cSDimitry Andric            << formatv("{0:x}", TotalSize) << " bytes.\n";
128349cc55cSDimitry Andric   });
129349cc55cSDimitry Andric 
130349cc55cSDimitry Andric   Expected<ExecutorAddr> TargetAllocAddr((ExecutorAddr()));
131349cc55cSDimitry Andric   if (auto Err = EPC.callSPSWrapper<
132349cc55cSDimitry Andric                  rt::SPSSimpleExecutorMemoryManagerReserveSignature>(
133349cc55cSDimitry Andric           SAs.Reserve, TargetAllocAddr, SAs.Instance, TotalSize)) {
134349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(M);
135349cc55cSDimitry Andric     ErrMsg = toString(std::move(Err));
136349cc55cSDimitry Andric     return;
137349cc55cSDimitry Andric   }
138349cc55cSDimitry Andric   if (!TargetAllocAddr) {
139349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(M);
140349cc55cSDimitry Andric     ErrMsg = toString(TargetAllocAddr.takeError());
141349cc55cSDimitry Andric     return;
142349cc55cSDimitry Andric   }
143349cc55cSDimitry Andric 
144349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
145bdd1243dSDimitry Andric   Unmapped.push_back(SectionAllocGroup());
146349cc55cSDimitry Andric   Unmapped.back().RemoteCode = {
147349cc55cSDimitry Andric       *TargetAllocAddr, ExecutorAddrDiff(alignTo(CodeSize, EPC.getPageSize()))};
148349cc55cSDimitry Andric   Unmapped.back().RemoteROData = {
149349cc55cSDimitry Andric       Unmapped.back().RemoteCode.End,
150349cc55cSDimitry Andric       ExecutorAddrDiff(alignTo(RODataSize, EPC.getPageSize()))};
151349cc55cSDimitry Andric   Unmapped.back().RemoteRWData = {
152349cc55cSDimitry Andric       Unmapped.back().RemoteROData.End,
153349cc55cSDimitry Andric       ExecutorAddrDiff(alignTo(RWDataSize, EPC.getPageSize()))};
154349cc55cSDimitry Andric }
155349cc55cSDimitry Andric 
needsToReserveAllocationSpace()156349cc55cSDimitry Andric bool EPCGenericRTDyldMemoryManager::needsToReserveAllocationSpace() {
157349cc55cSDimitry Andric   return true;
158349cc55cSDimitry Andric }
159349cc55cSDimitry Andric 
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)160349cc55cSDimitry Andric void EPCGenericRTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
161349cc55cSDimitry Andric                                                      uint64_t LoadAddr,
162349cc55cSDimitry Andric                                                      size_t Size) {
163349cc55cSDimitry Andric   LLVM_DEBUG({
164349cc55cSDimitry Andric     dbgs() << "Allocator " << (void *)this << " added unfinalized eh-frame "
165349cc55cSDimitry Andric            << formatv("[ {0:x} {1:x} ]", LoadAddr, LoadAddr + Size) << "\n";
166349cc55cSDimitry Andric   });
167349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
168349cc55cSDimitry Andric   // Bail out early if there's already an error.
169349cc55cSDimitry Andric   if (!ErrMsg.empty())
170349cc55cSDimitry Andric     return;
171349cc55cSDimitry Andric 
172349cc55cSDimitry Andric   ExecutorAddr LA(LoadAddr);
173bdd1243dSDimitry Andric   for (auto &SecAllocGroup : llvm::reverse(Unfinalized)) {
174bdd1243dSDimitry Andric     if (SecAllocGroup.RemoteCode.contains(LA) ||
175bdd1243dSDimitry Andric         SecAllocGroup.RemoteROData.contains(LA) ||
176bdd1243dSDimitry Andric         SecAllocGroup.RemoteRWData.contains(LA)) {
177bdd1243dSDimitry Andric       SecAllocGroup.UnfinalizedEHFrames.push_back({LA, Size});
178349cc55cSDimitry Andric       return;
179349cc55cSDimitry Andric     }
180349cc55cSDimitry Andric   }
181349cc55cSDimitry Andric   ErrMsg = "eh-frame does not lie inside unfinalized alloc";
182349cc55cSDimitry Andric }
183349cc55cSDimitry Andric 
deregisterEHFrames()184349cc55cSDimitry Andric void EPCGenericRTDyldMemoryManager::deregisterEHFrames() {
185349cc55cSDimitry Andric   // This is a no-op for us: We've registered a deallocation action for it.
186349cc55cSDimitry Andric }
187349cc55cSDimitry Andric 
notifyObjectLoaded(RuntimeDyld & Dyld,const object::ObjectFile & Obj)188349cc55cSDimitry Andric void EPCGenericRTDyldMemoryManager::notifyObjectLoaded(
189349cc55cSDimitry Andric     RuntimeDyld &Dyld, const object::ObjectFile &Obj) {
190349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
191349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "Allocator " << (void *)this << " applied mappings:\n");
192349cc55cSDimitry Andric   for (auto &ObjAllocs : Unmapped) {
193349cc55cSDimitry Andric     mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs,
194349cc55cSDimitry Andric                            ObjAllocs.RemoteCode.Start);
195349cc55cSDimitry Andric     mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RODataAllocs,
196349cc55cSDimitry Andric                            ObjAllocs.RemoteROData.Start);
197349cc55cSDimitry Andric     mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RWDataAllocs,
198349cc55cSDimitry Andric                            ObjAllocs.RemoteRWData.Start);
199349cc55cSDimitry Andric     Unfinalized.push_back(std::move(ObjAllocs));
200349cc55cSDimitry Andric   }
201349cc55cSDimitry Andric   Unmapped.clear();
202349cc55cSDimitry Andric }
203349cc55cSDimitry Andric 
finalizeMemory(std::string * ErrMsg)204349cc55cSDimitry Andric bool EPCGenericRTDyldMemoryManager::finalizeMemory(std::string *ErrMsg) {
205349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "Allocator " << (void *)this << " finalizing:\n");
206349cc55cSDimitry Andric 
207349cc55cSDimitry Andric   // If there's an error then bail out here.
208bdd1243dSDimitry Andric   std::vector<SectionAllocGroup> SecAllocGroups;
209349cc55cSDimitry Andric   {
210349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(M);
211349cc55cSDimitry Andric     if (ErrMsg && !this->ErrMsg.empty()) {
212349cc55cSDimitry Andric       *ErrMsg = std::move(this->ErrMsg);
213349cc55cSDimitry Andric       return true;
214349cc55cSDimitry Andric     }
215bdd1243dSDimitry Andric     std::swap(SecAllocGroups, Unfinalized);
216349cc55cSDimitry Andric   }
217349cc55cSDimitry Andric 
218349cc55cSDimitry Andric   // Loop over unfinalized objects to make finalization requests.
219bdd1243dSDimitry Andric   for (auto &SecAllocGroup : SecAllocGroups) {
220349cc55cSDimitry Andric 
221bdd1243dSDimitry Andric     MemProt SegMemProts[3] = {MemProt::Read | MemProt::Exec, MemProt::Read,
222bdd1243dSDimitry Andric                               MemProt::Read | MemProt::Write};
223349cc55cSDimitry Andric 
224bdd1243dSDimitry Andric     ExecutorAddrRange *RemoteAddrs[3] = {&SecAllocGroup.RemoteCode,
225bdd1243dSDimitry Andric                                          &SecAllocGroup.RemoteROData,
226bdd1243dSDimitry Andric                                          &SecAllocGroup.RemoteRWData};
227349cc55cSDimitry Andric 
228bdd1243dSDimitry Andric     std::vector<SectionAlloc> *SegSections[3] = {&SecAllocGroup.CodeAllocs,
229bdd1243dSDimitry Andric                                                  &SecAllocGroup.RODataAllocs,
230bdd1243dSDimitry Andric                                                  &SecAllocGroup.RWDataAllocs};
231349cc55cSDimitry Andric 
232349cc55cSDimitry Andric     tpctypes::FinalizeRequest FR;
233349cc55cSDimitry Andric     std::unique_ptr<char[]> AggregateContents[3];
234349cc55cSDimitry Andric 
235349cc55cSDimitry Andric     for (unsigned I = 0; I != 3; ++I) {
236349cc55cSDimitry Andric       FR.Segments.push_back({});
237349cc55cSDimitry Andric       auto &Seg = FR.Segments.back();
238*06c3fb27SDimitry Andric       Seg.RAG = SegMemProts[I];
239349cc55cSDimitry Andric       Seg.Addr = RemoteAddrs[I]->Start;
240349cc55cSDimitry Andric       for (auto &SecAlloc : *SegSections[I]) {
241349cc55cSDimitry Andric         Seg.Size = alignTo(Seg.Size, SecAlloc.Align);
242349cc55cSDimitry Andric         Seg.Size += SecAlloc.Size;
243349cc55cSDimitry Andric       }
244349cc55cSDimitry Andric       AggregateContents[I] = std::make_unique<char[]>(Seg.Size);
245349cc55cSDimitry Andric       size_t SecOffset = 0;
246349cc55cSDimitry Andric       for (auto &SecAlloc : *SegSections[I]) {
247349cc55cSDimitry Andric         SecOffset = alignTo(SecOffset, SecAlloc.Align);
248349cc55cSDimitry Andric         memcpy(&AggregateContents[I][SecOffset],
249349cc55cSDimitry Andric                reinterpret_cast<const char *>(
250349cc55cSDimitry Andric                    alignAddr(SecAlloc.Contents.get(), Align(SecAlloc.Align))),
251349cc55cSDimitry Andric                SecAlloc.Size);
252349cc55cSDimitry Andric         SecOffset += SecAlloc.Size;
253349cc55cSDimitry Andric         // FIXME: Can we reset SecAlloc.Content here, now that it's copied into
254349cc55cSDimitry Andric         // the aggregated content?
255349cc55cSDimitry Andric       }
256349cc55cSDimitry Andric       Seg.Content = {AggregateContents[I].get(), SecOffset};
257349cc55cSDimitry Andric     }
258349cc55cSDimitry Andric 
259bdd1243dSDimitry Andric     for (auto &Frame : SecAllocGroup.UnfinalizedEHFrames)
260349cc55cSDimitry Andric       FR.Actions.push_back(
26104eeddc0SDimitry Andric           {cantFail(
26204eeddc0SDimitry Andric                WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
26304eeddc0SDimitry Andric                    SAs.RegisterEHFrame, Frame)),
26404eeddc0SDimitry Andric            cantFail(
26504eeddc0SDimitry Andric                WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
26604eeddc0SDimitry Andric                    SAs.DeregisterEHFrame, Frame))});
267349cc55cSDimitry Andric 
268349cc55cSDimitry Andric     // We'll also need to make an extra allocation for the eh-frame wrapper call
269349cc55cSDimitry Andric     // arguments.
270349cc55cSDimitry Andric     Error FinalizeErr = Error::success();
271349cc55cSDimitry Andric     if (auto Err = EPC.callSPSWrapper<
272349cc55cSDimitry Andric                    rt::SPSSimpleExecutorMemoryManagerFinalizeSignature>(
273349cc55cSDimitry Andric             SAs.Finalize, FinalizeErr, SAs.Instance, std::move(FR))) {
274349cc55cSDimitry Andric       std::lock_guard<std::mutex> Lock(M);
275349cc55cSDimitry Andric       this->ErrMsg = toString(std::move(Err));
276349cc55cSDimitry Andric       dbgs() << "Serialization error: " << this->ErrMsg << "\n";
277349cc55cSDimitry Andric       if (ErrMsg)
278349cc55cSDimitry Andric         *ErrMsg = this->ErrMsg;
279349cc55cSDimitry Andric       return true;
280349cc55cSDimitry Andric     }
281349cc55cSDimitry Andric     if (FinalizeErr) {
282349cc55cSDimitry Andric       std::lock_guard<std::mutex> Lock(M);
283349cc55cSDimitry Andric       this->ErrMsg = toString(std::move(FinalizeErr));
284349cc55cSDimitry Andric       dbgs() << "Finalization error: " << this->ErrMsg << "\n";
285349cc55cSDimitry Andric       if (ErrMsg)
286349cc55cSDimitry Andric         *ErrMsg = this->ErrMsg;
287349cc55cSDimitry Andric       return true;
288349cc55cSDimitry Andric     }
289349cc55cSDimitry Andric   }
290349cc55cSDimitry Andric 
291349cc55cSDimitry Andric   return false;
292349cc55cSDimitry Andric }
293349cc55cSDimitry Andric 
mapAllocsToRemoteAddrs(RuntimeDyld & Dyld,std::vector<SectionAlloc> & Allocs,ExecutorAddr NextAddr)294349cc55cSDimitry Andric void EPCGenericRTDyldMemoryManager::mapAllocsToRemoteAddrs(
295bdd1243dSDimitry Andric     RuntimeDyld &Dyld, std::vector<SectionAlloc> &Allocs,
296bdd1243dSDimitry Andric     ExecutorAddr NextAddr) {
297349cc55cSDimitry Andric   for (auto &Alloc : Allocs) {
298349cc55cSDimitry Andric     NextAddr.setValue(alignTo(NextAddr.getValue(), Alloc.Align));
299349cc55cSDimitry Andric     LLVM_DEBUG({
300349cc55cSDimitry Andric       dbgs() << "     " << static_cast<void *>(Alloc.Contents.get()) << " -> "
301349cc55cSDimitry Andric              << format("0x%016" PRIx64, NextAddr.getValue()) << "\n";
302349cc55cSDimitry Andric     });
303349cc55cSDimitry Andric     Dyld.mapSectionAddress(reinterpret_cast<const void *>(alignAddr(
304349cc55cSDimitry Andric                                Alloc.Contents.get(), Align(Alloc.Align))),
305349cc55cSDimitry Andric                            NextAddr.getValue());
306349cc55cSDimitry Andric     Alloc.RemoteAddr = NextAddr;
307349cc55cSDimitry Andric     // Only advance NextAddr if it was non-null to begin with,
308349cc55cSDimitry Andric     // otherwise leave it as null.
309349cc55cSDimitry Andric     if (NextAddr)
310349cc55cSDimitry Andric       NextAddr += ExecutorAddrDiff(Alloc.Size);
311349cc55cSDimitry Andric   }
312349cc55cSDimitry Andric }
313349cc55cSDimitry Andric 
314349cc55cSDimitry Andric } // end namespace orc
315349cc55cSDimitry Andric } // end namespace llvm
316