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