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