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
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
90void
91IRExecutionUnit::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
101Error
102IRExecutionUnit::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_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
175
176    if (!disassembler_sp)
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_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
206
207    InstructionList &instruction_list = disassembler_sp->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    // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
223    // I'll fix that but for now, just clear the list and it will go away nicely.
224    disassembler_sp->GetInstructionList().Clear();
225    return ret;
226}
227
228static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
229{
230    Error *err = static_cast<Error*>(Context);
231
232    if (err && err->Success())
233    {
234        err->SetErrorToGenericError();
235        err->SetErrorStringWithFormat("Inline assembly error: %s", diagnostic.getMessage().str().c_str());
236    }
237}
238
239void
240IRExecutionUnit::GetRunnableInfo(Error &error,
241                                 lldb::addr_t &func_addr,
242                                 lldb::addr_t &func_end)
243{
244    lldb::ProcessSP process_sp(GetProcessWP().lock());
245
246    func_addr = LLDB_INVALID_ADDRESS;
247    func_end = LLDB_INVALID_ADDRESS;
248
249    if (!process_sp)
250    {
251        error.SetErrorToGenericError();
252        error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
253        return;
254    }
255
256    if (m_did_jit)
257    {
258        func_addr = m_function_load_addr;
259        func_end = m_function_end_load_addr;
260
261        return;
262    };
263
264    m_did_jit = true;
265
266    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
267
268    std::string error_string;
269
270    if (log)
271    {
272        std::string s;
273        llvm::raw_string_ostream oss(s);
274
275        m_module->print(oss, NULL);
276
277        oss.flush();
278
279        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
280    }
281
282    llvm::Triple triple(m_module->getTargetTriple());
283    llvm::Function *function = m_module->getFunction (m_name.AsCString());
284    llvm::Reloc::Model relocModel;
285    llvm::CodeModel::Model codeModel;
286
287    if (triple.isOSBinFormatELF())
288    {
289        relocModel = llvm::Reloc::Static;
290        // This will be small for 32-bit and large for 64-bit.
291        codeModel = llvm::CodeModel::JITDefault;
292    }
293    else
294    {
295        relocModel = llvm::Reloc::PIC_;
296        codeModel = llvm::CodeModel::Small;
297    }
298
299    m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
300
301    llvm::EngineBuilder builder(m_module_ap.get());
302
303    builder.setEngineKind(llvm::EngineKind::JIT)
304    .setErrorStr(&error_string)
305    .setRelocationModel(relocModel)
306    .setJITMemoryManager(new MemoryManager(*this))
307    .setOptLevel(llvm::CodeGenOpt::Less)
308    .setAllocateGVsWithCode(true)
309    .setCodeModel(codeModel)
310    .setUseMCJIT(true);
311
312    llvm::StringRef mArch;
313    llvm::StringRef mCPU;
314    llvm::SmallVector<std::string, 0> mAttrs;
315
316    for (std::string &feature : m_cpu_features)
317        mAttrs.push_back(feature);
318
319    llvm::TargetMachine *target_machine = builder.selectTarget(triple,
320                                                               mArch,
321                                                               mCPU,
322                                                               mAttrs);
323
324    m_execution_engine_ap.reset(builder.create(target_machine));
325
326    if (!m_execution_engine_ap.get())
327    {
328        error.SetErrorToGenericError();
329        error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
330        return;
331    }
332    else
333    {
334        m_module_ap.release(); // ownership was transferred
335    }
336
337    m_execution_engine_ap->DisableLazyCompilation();
338
339    // We don't actually need the function pointer here, this just forces it to get resolved.
340
341    void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
342
343    if (!error.Success())
344    {
345        // We got an error through our callback!
346        return;
347    }
348
349    if (!function)
350    {
351        error.SetErrorToGenericError();
352        error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
353        return;
354    }
355
356    if (!fun_ptr)
357    {
358        error.SetErrorToGenericError();
359        error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
360        return;
361    }
362
363    m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
364
365    CommitAllocations(process_sp);
366    ReportAllocations(*m_execution_engine_ap);
367    WriteData(process_sp);
368
369    for (JittedFunction &jitted_function : m_jitted_functions)
370    {
371        jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
372
373        if (!jitted_function.m_name.compare(m_name.AsCString()))
374        {
375            AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
376            m_function_end_load_addr = func_range.first + func_range.second;
377            m_function_load_addr = jitted_function.m_remote_addr;
378        }
379    }
380
381    if (log)
382    {
383        log->Printf("Code can be run in the target.");
384
385        StreamString disassembly_stream;
386
387        Error err = DisassembleFunction(disassembly_stream, process_sp);
388
389        if (!err.Success())
390        {
391            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
392        }
393        else
394        {
395            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
396        }
397    }
398
399    func_addr = m_function_load_addr;
400    func_end = m_function_end_load_addr;
401
402    return;
403}
404
405IRExecutionUnit::~IRExecutionUnit ()
406{
407    m_module_ap.reset();
408    m_execution_engine_ap.reset();
409    m_context_ap.reset();
410}
411
412IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
413    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
414    m_parent (parent)
415{
416}
417
418void
419IRExecutionUnit::MemoryManager::setMemoryWritable ()
420{
421    m_default_mm_ap->setMemoryWritable();
422}
423
424void
425IRExecutionUnit::MemoryManager::setMemoryExecutable ()
426{
427    m_default_mm_ap->setMemoryExecutable();
428}
429
430
431uint8_t *
432IRExecutionUnit::MemoryManager::startFunctionBody(const llvm::Function *F,
433                                                  uintptr_t &ActualSize)
434{
435    return m_default_mm_ap->startFunctionBody(F, ActualSize);
436}
437
438uint8_t *
439IRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F,
440                                             unsigned StubSize,
441                                             unsigned Alignment)
442{
443    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
444
445    uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
446
447    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
448                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
449                                                  StubSize,
450                                                  Alignment));
451
452    if (log)
453    {
454        log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
455                    F, StubSize, Alignment, return_value);
456    }
457
458    return return_value;
459}
460
461void
462IRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F,
463                                                uint8_t *FunctionStart,
464                                                uint8_t *FunctionEnd)
465{
466    m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
467}
468
469uint8_t *
470IRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
471{
472    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
473
474    uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
475
476    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
477                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
478                                                  Size,
479                                                  Alignment));
480
481    if (log)
482    {
483        log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
484                               (uint64_t)Size, Alignment, return_value);
485    }
486
487    return return_value;
488}
489
490uint8_t *
491IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
492                                                    unsigned Alignment,
493                                                    unsigned SectionID)
494{
495    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
496
497    uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
498
499    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
500                                                  lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
501                                                  Size,
502                                                  Alignment,
503                                                  SectionID));
504
505    if (log)
506    {
507        log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
508                    (uint64_t)Size, Alignment, SectionID, return_value);
509    }
510
511    return return_value;
512}
513
514uint8_t *
515IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
516                                                    unsigned Alignment,
517                                                    unsigned SectionID,
518                                                    bool IsReadOnly)
519{
520    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
521
522    uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
523
524    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
525                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
526                                                  Size,
527                                                  Alignment,
528                                                  SectionID));
529    if (log)
530    {
531        log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
532                    (uint64_t)Size, Alignment, SectionID, return_value);
533    }
534
535    return return_value;
536}
537
538uint8_t *
539IRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size,
540                                               unsigned Alignment)
541{
542    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
543
544    uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
545
546    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
547                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
548                                                  Size,
549                                                  Alignment));
550
551    if (log)
552    {
553        log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
554                    (uint64_t)Size, Alignment, return_value);
555    }
556
557    return return_value;
558}
559
560void
561IRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body)
562{
563    m_default_mm_ap->deallocateFunctionBody(Body);
564}
565
566lldb::addr_t
567IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
568{
569    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
570
571    for (AllocationRecord &record : m_records)
572    {
573        if (local_address >= record.m_host_address &&
574            local_address < record.m_host_address + record.m_size)
575        {
576            if (record.m_process_address == LLDB_INVALID_ADDRESS)
577                return LLDB_INVALID_ADDRESS;
578
579            lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
580
581            if (log)
582            {
583                log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
584                            local_address,
585                            (uint64_t)record.m_host_address,
586                            (uint64_t)record.m_host_address + (uint64_t)record.m_size,
587                            ret,
588                            record.m_process_address,
589                            record.m_process_address + record.m_size);
590            }
591
592            return ret;
593        }
594    }
595
596    return LLDB_INVALID_ADDRESS;
597}
598
599IRExecutionUnit::AddrRange
600IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
601{
602    for (AllocationRecord &record : m_records)
603    {
604        if (local_address >= record.m_host_address &&
605            local_address < record.m_host_address + record.m_size)
606        {
607            if (record.m_process_address == LLDB_INVALID_ADDRESS)
608                return AddrRange(0, 0);
609
610            return AddrRange(record.m_process_address, record.m_size);
611        }
612    }
613
614    return AddrRange (0, 0);
615}
616
617bool
618IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
619{
620    bool ret = true;
621
622    lldb_private::Error err;
623
624    for (AllocationRecord &record : m_records)
625    {
626        if (record.m_process_address != LLDB_INVALID_ADDRESS)
627            continue;
628
629
630        record.m_process_address = Malloc(record.m_size,
631                                          record.m_alignment,
632                                          record.m_permissions,
633                                          eAllocationPolicyProcessOnly,
634                                          err);
635
636        if (!err.Success())
637        {
638            ret = false;
639            break;
640        }
641    }
642
643    if (!ret)
644    {
645        for (AllocationRecord &record : m_records)
646        {
647            if (record.m_process_address != LLDB_INVALID_ADDRESS)
648            {
649                Free(record.m_process_address, err);
650                record.m_process_address = LLDB_INVALID_ADDRESS;
651            }
652        }
653    }
654
655    return ret;
656}
657
658void
659IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
660{
661    for (AllocationRecord &record : m_records)
662    {
663        if (record.m_process_address == LLDB_INVALID_ADDRESS)
664            continue;
665
666        if (record.m_section_id == eSectionIDInvalid)
667            continue;
668
669        engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
670    }
671
672    // Trigger re-application of relocations.
673    engine.finalizeObject();
674}
675
676bool
677IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
678{
679    for (AllocationRecord &record : m_records)
680    {
681        if (record.m_process_address == LLDB_INVALID_ADDRESS)
682            return false;
683
684        lldb_private::Error err;
685
686        WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
687    }
688
689    return true;
690}
691
692void
693IRExecutionUnit::AllocationRecord::dump (Log *log)
694{
695    if (!log)
696        return;
697
698    log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
699                (unsigned long long)m_host_address,
700                (unsigned long long)m_size,
701                (unsigned long long)m_process_address,
702                (unsigned)m_alignment,
703                (unsigned)m_section_id);
704}
705