1 //===-- IRExecutionUnit.cpp ------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 #include "llvm/ExecutionEngine/ExecutionEngine.h"
14 #include "llvm/IR/Module.h"
15 // Project includes
16 #include "lldb/Core/DataBufferHeap.h"
17 #include "lldb/Core/DataExtractor.h"
18 #include "lldb/Core/Disassembler.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Expression/IRExecutionUnit.h"
21 #include "lldb/Target/ExecutionContext.h"
22 #include "lldb/Target/Target.h"
23 
24 using namespace lldb_private;
25 
26 IRExecutionUnit::IRExecutionUnit (std::auto_ptr<llvm::Module> &module_ap,
27                                   ConstString &name,
28                                   lldb::ProcessSP process_sp,
29                                   std::vector<std::string> &cpu_features) :
30     m_process_wp(process_sp),
31     m_module_ap(module_ap),
32     m_module(m_module_ap.get()),
33     m_cpu_features(),
34     m_name(name),
35     m_did_jit(false),
36     m_function_load_addr(LLDB_INVALID_ADDRESS),
37     m_function_end_load_addr(LLDB_INVALID_ADDRESS)
38 {
39     for (std::string &feature : cpu_features)
40     {
41         m_cpu_features.push_back(std::string(feature.c_str()));
42     }
43 }
44 
45 lldb::addr_t
46 IRExecutionUnit::WriteNow (const uint8_t *bytes,
47                            size_t size,
48                            Error &error)
49 {
50     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
51 
52     Allocation allocation;
53     allocation.m_size = size;
54     allocation.m_alignment = 8;
55     allocation.m_local_start = LLDB_INVALID_ADDRESS;
56     allocation.m_section_id = Allocation::eSectionIDNone;
57 
58     lldb_private::Error err;
59 
60     size_t allocation_size = (allocation.m_size ? allocation.m_size : 1) + allocation.m_alignment - 1;
61 
62     if (allocation_size == 0)
63         allocation_size = 1;
64 
65     lldb::ProcessSP process_sp = m_process_wp.lock();
66 
67     if (!process_sp)
68     {
69         err.SetErrorToGenericError();
70         err.SetErrorString("Couldn't find the process");
71     }
72 
73     allocation.m_remote_allocation = process_sp->AllocateMemory(allocation_size,
74                                                                 (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
75                                                                 err);
76 
77     if (!err.Success())
78         return LLDB_INVALID_ADDRESS;
79 
80     process_sp->WriteMemory(allocation.m_remote_allocation, bytes, size, err);
81 
82     if (!err.Success())
83     {
84         process_sp->DeallocateMemory(allocation.m_remote_allocation);
85         allocation.m_remote_allocation = LLDB_INVALID_ADDRESS;
86         return LLDB_INVALID_ADDRESS;
87     }
88 
89     uint64_t mask = allocation.m_alignment - 1;
90 
91     allocation.m_remote_start = (allocation.m_remote_allocation + mask) & (~mask);
92 
93     allocation.m_allocated = true;
94 
95     if (log)
96     {
97         log->Printf("IRExecutionUnit::WriteNow() wrote to 0x%llx", allocation.m_remote_start);
98         allocation.dump(log);
99     }
100 
101     m_allocations.push_back(allocation);
102 
103     return allocation.m_remote_start;
104 }
105 
106 void
107 IRExecutionUnit::FreeNow (lldb::addr_t allocation)
108 {
109     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
110 
111     if (allocation == LLDB_INVALID_ADDRESS)
112         return;
113 
114     lldb::ProcessSP process_sp = m_process_wp.lock();
115 
116     if (!process_sp)
117         return;
118 
119     for (auto ai = m_allocations.begin(), ae = m_allocations.end();
120          ai != ae;
121          ++ai)
122     {
123         if (ai->m_remote_allocation == allocation)
124         {
125             m_allocations.erase(ai);
126             log->Printf("IRExecutionUnit::FreeNow() freed 0x%llx", allocation);
127             return;
128         }
129     }
130 }
131 
132 Error
133 IRExecutionUnit::DisassembleFunction (Stream &stream,
134                                       lldb::ProcessSP &process_wp)
135 {
136     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
137 
138     ExecutionContext exe_ctx(process_wp);
139 
140     Error ret;
141 
142     ret.Clear();
143 
144     lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
145     lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
146 
147     for (JittedFunction &function : m_jitted_functions)
148     {
149         if (strstr(function.m_name.c_str(), m_name.AsCString()))
150         {
151             func_local_addr = function.m_local_addr;
152             func_remote_addr = function.m_remote_addr;
153         }
154     }
155 
156     if (func_local_addr == LLDB_INVALID_ADDRESS)
157     {
158         ret.SetErrorToGenericError();
159         ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
160         return ret;
161     }
162 
163     if (log)
164         log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
165 
166     std::pair <lldb::addr_t, lldb::addr_t> func_range;
167 
168     func_range = GetRemoteRangeForLocal(func_local_addr);
169 
170     if (func_range.first == 0 && func_range.second == 0)
171     {
172         ret.SetErrorToGenericError();
173         ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
174         return ret;
175     }
176 
177     if (log)
178         log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
179 
180     Target *target = exe_ctx.GetTargetPtr();
181     if (!target)
182     {
183         ret.SetErrorToGenericError();
184         ret.SetErrorString("Couldn't find the target");
185         return ret;
186     }
187 
188     lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
189 
190     Process *process = exe_ctx.GetProcessPtr();
191     Error err;
192     process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
193 
194     if (!err.Success())
195     {
196         ret.SetErrorToGenericError();
197         ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
198         return ret;
199     }
200 
201     ArchSpec arch(target->GetArchitecture());
202 
203     const char *plugin_name = NULL;
204     const char *flavor_string = NULL;
205     lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
206 
207     if (!disassembler)
208     {
209         ret.SetErrorToGenericError();
210         ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
211         return ret;
212     }
213 
214     if (!process)
215     {
216         ret.SetErrorToGenericError();
217         ret.SetErrorString("Couldn't find the process");
218         return ret;
219     }
220 
221     DataExtractor extractor(buffer_sp,
222                             process->GetByteOrder(),
223                             target->GetArchitecture().GetAddressByteSize());
224 
225     if (log)
226     {
227         log->Printf("Function data has contents:");
228         extractor.PutToLog (log.get(),
229                             0,
230                             extractor.GetByteSize(),
231                             func_remote_addr,
232                             16,
233                             DataExtractor::TypeUInt8);
234     }
235 
236     disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false);
237 
238     InstructionList &instruction_list = disassembler->GetInstructionList();
239     const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
240 
241     for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
242          instruction_index < num_instructions;
243          ++instruction_index)
244     {
245         Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
246         instruction->Dump (&stream,
247                            max_opcode_byte_size,
248                            true,
249                            true,
250                            &exe_ctx);
251         stream.PutChar('\n');
252     }
253 
254     return ret;
255 }
256 
257 void
258 IRExecutionUnit::GetRunnableInfo(Error &error,
259                                  lldb::addr_t &func_addr,
260                                  lldb::addr_t &func_end)
261 {
262     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
263     lldb::ProcessSP process_sp(m_process_wp.lock());
264 
265     func_addr = LLDB_INVALID_ADDRESS;
266     func_end = LLDB_INVALID_ADDRESS;
267 
268     if (!process_sp)
269     {
270         error.SetErrorToGenericError();
271         error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
272         return;
273     }
274 
275     if (m_did_jit)
276     {
277         func_addr = m_function_load_addr;
278         func_end = m_function_end_load_addr;
279 
280         return;
281     }; // someone else may have gotten the mutex first
282 
283     {
284         Mutex::Locker jit_mutex_locker(m_jit_mutex);
285 
286         if (m_did_jit)
287         {
288             func_addr = m_function_load_addr;
289             func_end = m_function_end_load_addr;
290 
291             return;
292         }; // someone else may have gotten the mutex first
293 
294         m_did_jit = true;
295 
296         lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
297 
298         std::string error_string;
299 
300         if (log)
301         {
302             std::string s;
303             llvm::raw_string_ostream oss(s);
304 
305             m_module->print(oss, NULL);
306 
307             oss.flush();
308 
309             log->Printf ("Module being sent to JIT: \n%s", s.c_str());
310         }
311 
312         llvm::Triple triple(m_module->getTargetTriple());
313         llvm::Function *function = m_module->getFunction (m_name.AsCString());
314         llvm::Reloc::Model relocModel;
315         llvm::CodeModel::Model codeModel;
316 
317         if (triple.isOSBinFormatELF())
318         {
319             relocModel = llvm::Reloc::Static;
320             // This will be small for 32-bit and large for 64-bit.
321             codeModel = llvm::CodeModel::JITDefault;
322         }
323         else
324         {
325             relocModel = llvm::Reloc::PIC_;
326             codeModel = llvm::CodeModel::Small;
327         }
328 
329         llvm::EngineBuilder builder(m_module_ap.get());
330 
331         builder.setEngineKind(llvm::EngineKind::JIT)
332         .setErrorStr(&error_string)
333         .setRelocationModel(relocModel)
334         .setJITMemoryManager(new MemoryManager(*this))
335         .setOptLevel(llvm::CodeGenOpt::Less)
336         .setAllocateGVsWithCode(true)
337         .setCodeModel(codeModel)
338         .setUseMCJIT(true);
339 
340         llvm::StringRef mArch;
341         llvm::StringRef mCPU;
342         llvm::SmallVector<std::string, 0> mAttrs;
343 
344         for (std::string &feature : m_cpu_features)
345             mAttrs.push_back(feature);
346 
347         llvm::TargetMachine *target_machine = builder.selectTarget(triple,
348                                                                    mArch,
349                                                                    mCPU,
350                                                                    mAttrs);
351 
352         m_execution_engine_ap.reset(builder.create(target_machine));
353 
354         if (!m_execution_engine_ap.get())
355         {
356             error.SetErrorToGenericError();
357             error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
358             return;
359         }
360         else
361         {
362             m_module_ap.release(); // ownership was transferred
363         }
364 
365         m_execution_engine_ap->DisableLazyCompilation();
366 
367         // We don't actually need the function pointer here, this just forces it to get resolved.
368 
369         void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
370 
371         // Errors usually cause failures in the JIT, but if we're lucky we get here.
372 
373         if (!function)
374         {
375             error.SetErrorToGenericError();
376             error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
377             return;
378         }
379 
380         if (!fun_ptr)
381         {
382             error.SetErrorToGenericError();
383             error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
384             return;
385         }
386 
387         m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
388 
389         CommitAllocations(process_sp);
390         ReportAllocations(*m_execution_engine_ap);
391         WriteData(process_sp);
392 
393         for (JittedFunction &jitted_function : m_jitted_functions)
394         {
395             jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
396 
397             if (!jitted_function.m_name.compare(m_name.AsCString()))
398             {
399                 AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
400                 m_function_end_load_addr = func_range.first + func_range.second;
401                 m_function_load_addr = jitted_function.m_remote_addr;
402             }
403         }
404 
405         if (log)
406         {
407             log->Printf("Code can be run in the target.");
408 
409             StreamString disassembly_stream;
410 
411             Error err = DisassembleFunction(disassembly_stream, process_sp);
412 
413             if (!err.Success())
414             {
415                 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
416             }
417             else
418             {
419                 log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
420             }
421         }
422 
423         func_addr = m_function_load_addr;
424         func_end = m_function_end_load_addr;
425 
426         return;
427     }
428 }
429 
430 IRExecutionUnit::~IRExecutionUnit ()
431 {
432 }
433 
434 IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
435     m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
436     m_parent (parent)
437 {
438 }
439 
440 void
441 IRExecutionUnit::MemoryManager::setMemoryWritable ()
442 {
443     m_default_mm_ap->setMemoryWritable();
444 }
445 
446 void
447 IRExecutionUnit::MemoryManager::setMemoryExecutable ()
448 {
449     m_default_mm_ap->setMemoryExecutable();
450 }
451 
452 
453 uint8_t *
454 IRExecutionUnit::MemoryManager::startFunctionBody(const llvm::Function *F,
455                                                   uintptr_t &ActualSize)
456 {
457     return m_default_mm_ap->startFunctionBody(F, ActualSize);
458 }
459 
460 uint8_t *
461 IRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F,
462                                              unsigned StubSize,
463                                              unsigned Alignment)
464 {
465     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
466 
467     uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
468 
469     Allocation allocation;
470     allocation.m_size = StubSize;
471     allocation.m_alignment = Alignment;
472     allocation.m_local_start = (uintptr_t)return_value;
473 
474     if (log)
475     {
476         log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
477                     F, StubSize, Alignment, return_value);
478         allocation.dump(log);
479     }
480 
481     m_parent.m_allocations.push_back(allocation);
482 
483     return return_value;
484 }
485 
486 void
487 IRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F,
488                                                 uint8_t *FunctionStart,
489                                                 uint8_t *FunctionEnd)
490 {
491     m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
492 }
493 
494 uint8_t *
495 IRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
496 {
497     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
498 
499     uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
500 
501     Allocation allocation;
502     allocation.m_size = Size;
503     allocation.m_alignment = Alignment;
504     allocation.m_local_start = (uintptr_t)return_value;
505 
506     if (log)
507     {
508         log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
509                                (uint64_t)Size, Alignment, return_value);
510         allocation.dump(log);
511     }
512 
513     m_parent.m_allocations.push_back(allocation);
514 
515     return return_value;
516 }
517 
518 uint8_t *
519 IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
520                                                     unsigned Alignment,
521                                                     unsigned SectionID)
522 {
523     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
524 
525     uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
526 
527     Allocation allocation;
528     allocation.m_size = Size;
529     allocation.m_alignment = Alignment;
530     allocation.m_local_start = (uintptr_t)return_value;
531     allocation.m_section_id = SectionID;
532     allocation.m_executable = true;
533 
534     if (log)
535     {
536         log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
537                     (uint64_t)Size, Alignment, SectionID, return_value);
538         allocation.dump(log);
539     }
540 
541     m_parent.m_allocations.push_back(allocation);
542 
543     return return_value;
544 }
545 
546 uint8_t *
547 IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
548                                                     unsigned Alignment,
549                                                     unsigned SectionID,
550                                                     bool IsReadOnly)
551 {
552     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
553 
554     uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
555 
556     Allocation allocation;
557     allocation.m_size = Size;
558     allocation.m_alignment = Alignment;
559     allocation.m_local_start = (uintptr_t)return_value;
560     allocation.m_section_id = SectionID;
561 
562     if (log)
563     {
564         log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
565                     (uint64_t)Size, Alignment, SectionID, return_value);
566         allocation.dump(log);
567     }
568 
569     m_parent.m_allocations.push_back(allocation);
570 
571     return return_value;
572 }
573 
574 uint8_t *
575 IRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size,
576                                                unsigned Alignment)
577 {
578     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
579 
580     uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
581 
582     Allocation allocation;
583     allocation.m_size = Size;
584     allocation.m_alignment = Alignment;
585     allocation.m_local_start = (uintptr_t)return_value;
586 
587     if (log)
588     {
589         log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
590                     (uint64_t)Size, Alignment, return_value);
591         allocation.dump(log);
592     }
593 
594     m_parent.m_allocations.push_back(allocation);
595 
596     return return_value;
597 }
598 
599 void
600 IRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body)
601 {
602     m_default_mm_ap->deallocateFunctionBody(Body);
603 }
604 
605 uint8_t*
606 IRExecutionUnit::MemoryManager::startExceptionTable(const llvm::Function* F,
607                                                     uintptr_t &ActualSize)
608 {
609     return m_default_mm_ap->startExceptionTable(F, ActualSize);
610 }
611 
612 void
613 IRExecutionUnit::MemoryManager::endExceptionTable(const llvm::Function *F,
614                                                   uint8_t *TableStart,
615                                                   uint8_t *TableEnd,
616                                                   uint8_t* FrameRegister)
617 {
618     m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
619 }
620 
621 void
622 IRExecutionUnit::MemoryManager::deallocateExceptionTable(void *ET)
623 {
624     m_default_mm_ap->deallocateExceptionTable (ET);
625 }
626 
627 lldb::addr_t
628 IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
629 {
630     for (Allocation &allocation : m_allocations)
631     {
632         if (local_address >= allocation.m_local_start &&
633             local_address < allocation.m_local_start + allocation.m_size)
634             return allocation.m_remote_start + (local_address - allocation.m_local_start);
635     }
636 
637     return LLDB_INVALID_ADDRESS;
638 }
639 
640 IRExecutionUnit::AddrRange
641 IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
642 {
643     for (Allocation &allocation : m_allocations)
644     {
645         if (local_address >= allocation.m_local_start &&
646             local_address < allocation.m_local_start + allocation.m_size)
647             return AddrRange(allocation.m_remote_start, allocation.m_size);
648     }
649 
650     return AddrRange (0, 0);
651 }
652 
653 bool
654 IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
655 {
656     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
657 
658     bool ret = true;
659 
660     for (Allocation &allocation : m_allocations)
661     {
662         if (allocation.m_allocated)
663             continue;
664 
665         lldb_private::Error err;
666 
667         size_t allocation_size = (allocation.m_size ? allocation.m_size : 1) + allocation.m_alignment - 1;
668 
669         if (allocation_size == 0)
670             allocation_size = 1;
671 
672         allocation.m_remote_allocation = process_sp->AllocateMemory(
673             allocation_size,
674             allocation.m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable)
675                                     : (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
676             err);
677 
678         uint64_t mask = allocation.m_alignment - 1;
679 
680         allocation.m_remote_start = (allocation.m_remote_allocation + mask) & (~mask);
681 
682         if (!err.Success())
683         {
684             ret = false;
685             break;
686         }
687 
688         allocation.m_allocated = true;
689 
690         if (log)
691         {
692             log->Printf("IRExecutionUnit::CommitAllocations() committed an allocation");
693             allocation.dump(log);
694         }
695     }
696 
697     if (!ret)
698     {
699         for (Allocation &allocation : m_allocations)
700         {
701             if (allocation.m_allocated)
702                 process_sp->DeallocateMemory(allocation.m_remote_start);
703         }
704     }
705 
706     return ret;
707 }
708 
709 void
710 IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
711 {
712     for (Allocation &allocation : m_allocations)
713     {
714         if (!allocation.m_allocated)
715             continue;
716 
717         if (allocation.m_local_start == LLDB_INVALID_ADDRESS)
718             continue;
719 
720         engine.mapSectionAddress((void*)allocation.m_local_start, allocation.m_remote_start);
721     }
722     // Trigger re-application of relocations.
723     engine.finalizeObject();
724 }
725 
726 bool
727 IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
728 {
729     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
730 
731     for (Allocation &allocation : m_allocations)
732     {
733         if (!allocation.m_allocated)
734             return false;
735 
736         if (allocation.m_local_start == LLDB_INVALID_ADDRESS)
737             continue;
738 
739         lldb_private::Error err;
740 
741         if (process_sp->WriteMemory(allocation.m_remote_start,
742                                     (void*)allocation.m_local_start,
743                                     allocation.m_size,
744                                     err) != allocation.m_size ||
745             !err.Success())
746             return false;
747 
748         if (log)
749         {
750             log->Printf("IRExecutionUnit::CommitAllocations() wrote an allocation");
751             allocation.dump(log);
752         }
753     }
754 
755     return true;
756 }
757 
758 void
759 IRExecutionUnit::Allocation::dump (lldb::LogSP log)
760 {
761     if (!log)
762         return;
763 
764     log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
765                 (unsigned long long)m_local_start,
766                 (unsigned long long)m_size,
767                 (unsigned long long)m_remote_start,
768                 (unsigned)m_alignment,
769                 (unsigned)m_section_id);
770 }
771