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