1254721Semaste//===-- IRExecutionUnit.cpp -------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste// C Includes
11254721Semaste// C++ Includes
12254721Semaste// Other libraries and framework includes
13254721Semaste#include "llvm/ExecutionEngine/ExecutionEngine.h"
14254721Semaste#include "llvm/IR/LLVMContext.h"
15254721Semaste#include "llvm/IR/Module.h"
16254721Semaste#include "llvm/Support/SourceMgr.h"
17254721Semaste// Project includes
18254721Semaste#include "lldb/Core/DataBufferHeap.h"
19254721Semaste#include "lldb/Core/DataExtractor.h"
20254721Semaste#include "lldb/Core/Disassembler.h"
21254721Semaste#include "lldb/Core/Log.h"
22254721Semaste#include "lldb/Expression/IRExecutionUnit.h"
23254721Semaste#include "lldb/Target/ExecutionContext.h"
24254721Semaste#include "lldb/Target/Target.h"
25254721Semaste
26254721Semasteusing namespace lldb_private;
27254721Semaste
28254721SemasteIRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
29254721Semaste                                  std::unique_ptr<llvm::Module> &module_ap,
30254721Semaste                                  ConstString &name,
31254721Semaste                                  const lldb::TargetSP &target_sp,
32254721Semaste                                  std::vector<std::string> &cpu_features) :
33254721Semaste    IRMemoryMap(target_sp),
34254721Semaste    m_context_ap(context_ap.release()),
35254721Semaste    m_module_ap(module_ap.release()),
36254721Semaste    m_module(m_module_ap.get()),
37254721Semaste    m_cpu_features(cpu_features),
38254721Semaste    m_name(name),
39254721Semaste    m_did_jit(false),
40254721Semaste    m_function_load_addr(LLDB_INVALID_ADDRESS),
41254721Semaste    m_function_end_load_addr(LLDB_INVALID_ADDRESS)
42254721Semaste{
43254721Semaste}
44254721Semaste
45254721Semastelldb::addr_t
46254721SemasteIRExecutionUnit::WriteNow (const uint8_t *bytes,
47254721Semaste                           size_t size,
48254721Semaste                           Error &error)
49254721Semaste{
50254721Semaste    lldb::addr_t allocation_process_addr = Malloc (size,
51254721Semaste                                                   8,
52254721Semaste                                                   lldb::ePermissionsWritable | lldb::ePermissionsReadable,
53254721Semaste                                                   eAllocationPolicyMirror,
54254721Semaste                                                   error);
55254721Semaste
56254721Semaste    if (!error.Success())
57254721Semaste        return LLDB_INVALID_ADDRESS;
58254721Semaste
59254721Semaste    WriteMemory(allocation_process_addr, bytes, size, error);
60254721Semaste
61254721Semaste    if (!error.Success())
62254721Semaste    {
63254721Semaste        Error err;
64254721Semaste        Free (allocation_process_addr, err);
65254721Semaste
66254721Semaste        return LLDB_INVALID_ADDRESS;
67254721Semaste    }
68254721Semaste
69254721Semaste    if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
70254721Semaste    {
71254721Semaste        DataBufferHeap my_buffer(size, 0);
72254721Semaste        Error err;
73254721Semaste        ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
74254721Semaste
75254721Semaste        if (err.Success())
76254721Semaste        {
77254721Semaste            DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
78269024Semaste            my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), allocation_process_addr, 16, DataExtractor::TypeUInt8);
79254721Semaste        }
80254721Semaste    }
81254721Semaste
82254721Semaste    return allocation_process_addr;
83254721Semaste}
84254721Semaste
85254721Semastevoid
86254721SemasteIRExecutionUnit::FreeNow (lldb::addr_t allocation)
87254721Semaste{
88254721Semaste    if (allocation == LLDB_INVALID_ADDRESS)
89254721Semaste        return;
90254721Semaste
91254721Semaste    Error err;
92254721Semaste
93254721Semaste    Free(allocation, err);
94254721Semaste}
95254721Semaste
96254721SemasteError
97254721SemasteIRExecutionUnit::DisassembleFunction (Stream &stream,
98254721Semaste                                      lldb::ProcessSP &process_wp)
99254721Semaste{
100254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
101254721Semaste
102254721Semaste    ExecutionContext exe_ctx(process_wp);
103254721Semaste
104254721Semaste    Error ret;
105254721Semaste
106254721Semaste    ret.Clear();
107254721Semaste
108254721Semaste    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
109254721Semaste    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
110254721Semaste
111254721Semaste    for (JittedFunction &function : m_jitted_functions)
112254721Semaste    {
113254721Semaste        if (strstr(function.m_name.c_str(), m_name.AsCString()))
114254721Semaste        {
115254721Semaste            func_local_addr = function.m_local_addr;
116254721Semaste            func_remote_addr = function.m_remote_addr;
117254721Semaste        }
118254721Semaste    }
119254721Semaste
120254721Semaste    if (func_local_addr == LLDB_INVALID_ADDRESS)
121254721Semaste    {
122254721Semaste        ret.SetErrorToGenericError();
123254721Semaste        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
124254721Semaste        return ret;
125254721Semaste    }
126254721Semaste
127254721Semaste    if (log)
128254721Semaste        log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
129254721Semaste
130254721Semaste    std::pair <lldb::addr_t, lldb::addr_t> func_range;
131254721Semaste
132254721Semaste    func_range = GetRemoteRangeForLocal(func_local_addr);
133254721Semaste
134254721Semaste    if (func_range.first == 0 && func_range.second == 0)
135254721Semaste    {
136254721Semaste        ret.SetErrorToGenericError();
137254721Semaste        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
138254721Semaste        return ret;
139254721Semaste    }
140254721Semaste
141254721Semaste    if (log)
142254721Semaste        log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
143254721Semaste
144254721Semaste    Target *target = exe_ctx.GetTargetPtr();
145254721Semaste    if (!target)
146254721Semaste    {
147254721Semaste        ret.SetErrorToGenericError();
148254721Semaste        ret.SetErrorString("Couldn't find the target");
149254721Semaste        return ret;
150254721Semaste    }
151254721Semaste
152254721Semaste    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
153254721Semaste
154254721Semaste    Process *process = exe_ctx.GetProcessPtr();
155254721Semaste    Error err;
156254721Semaste    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
157254721Semaste
158254721Semaste    if (!err.Success())
159254721Semaste    {
160254721Semaste        ret.SetErrorToGenericError();
161254721Semaste        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
162254721Semaste        return ret;
163254721Semaste    }
164254721Semaste
165254721Semaste    ArchSpec arch(target->GetArchitecture());
166254721Semaste
167254721Semaste    const char *plugin_name = NULL;
168254721Semaste    const char *flavor_string = NULL;
169254721Semaste    lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
170254721Semaste
171254721Semaste    if (!disassembler_sp)
172254721Semaste    {
173254721Semaste        ret.SetErrorToGenericError();
174254721Semaste        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
175254721Semaste        return ret;
176254721Semaste    }
177254721Semaste
178254721Semaste    if (!process)
179254721Semaste    {
180254721Semaste        ret.SetErrorToGenericError();
181254721Semaste        ret.SetErrorString("Couldn't find the process");
182254721Semaste        return ret;
183254721Semaste    }
184254721Semaste
185254721Semaste    DataExtractor extractor(buffer_sp,
186254721Semaste                            process->GetByteOrder(),
187254721Semaste                            target->GetArchitecture().GetAddressByteSize());
188254721Semaste
189254721Semaste    if (log)
190254721Semaste    {
191254721Semaste        log->Printf("Function data has contents:");
192254721Semaste        extractor.PutToLog (log,
193254721Semaste                            0,
194254721Semaste                            extractor.GetByteSize(),
195254721Semaste                            func_remote_addr,
196254721Semaste                            16,
197254721Semaste                            DataExtractor::TypeUInt8);
198254721Semaste    }
199254721Semaste
200254721Semaste    disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
201254721Semaste
202254721Semaste    InstructionList &instruction_list = disassembler_sp->GetInstructionList();
203254721Semaste    const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
204254721Semaste
205254721Semaste    for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
206254721Semaste         instruction_index < num_instructions;
207254721Semaste         ++instruction_index)
208254721Semaste    {
209254721Semaste        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
210254721Semaste        instruction->Dump (&stream,
211254721Semaste                           max_opcode_byte_size,
212254721Semaste                           true,
213254721Semaste                           true,
214254721Semaste                           &exe_ctx);
215254721Semaste        stream.PutChar('\n');
216254721Semaste    }
217254721Semaste    // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
218254721Semaste    // I'll fix that but for now, just clear the list and it will go away nicely.
219254721Semaste    disassembler_sp->GetInstructionList().Clear();
220254721Semaste    return ret;
221254721Semaste}
222254721Semaste
223254721Semastestatic void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
224254721Semaste{
225254721Semaste    Error *err = static_cast<Error*>(Context);
226254721Semaste
227254721Semaste    if (err && err->Success())
228254721Semaste    {
229254721Semaste        err->SetErrorToGenericError();
230254721Semaste        err->SetErrorStringWithFormat("Inline assembly error: %s", diagnostic.getMessage().str().c_str());
231254721Semaste    }
232254721Semaste}
233254721Semaste
234254721Semastevoid
235254721SemasteIRExecutionUnit::GetRunnableInfo(Error &error,
236254721Semaste                                 lldb::addr_t &func_addr,
237254721Semaste                                 lldb::addr_t &func_end)
238254721Semaste{
239254721Semaste    lldb::ProcessSP process_sp(GetProcessWP().lock());
240254721Semaste
241269024Semaste    static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);
242269024Semaste
243254721Semaste    func_addr = LLDB_INVALID_ADDRESS;
244254721Semaste    func_end = LLDB_INVALID_ADDRESS;
245254721Semaste
246254721Semaste    if (!process_sp)
247254721Semaste    {
248254721Semaste        error.SetErrorToGenericError();
249254721Semaste        error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
250254721Semaste        return;
251254721Semaste    }
252254721Semaste
253254721Semaste    if (m_did_jit)
254254721Semaste    {
255254721Semaste        func_addr = m_function_load_addr;
256254721Semaste        func_end = m_function_end_load_addr;
257254721Semaste
258254721Semaste        return;
259254721Semaste    };
260254721Semaste
261269024Semaste    Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);
262269024Semaste
263254721Semaste    m_did_jit = true;
264254721Semaste
265254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
266254721Semaste
267254721Semaste    std::string error_string;
268254721Semaste
269254721Semaste    if (log)
270254721Semaste    {
271254721Semaste        std::string s;
272254721Semaste        llvm::raw_string_ostream oss(s);
273254721Semaste
274254721Semaste        m_module->print(oss, NULL);
275254721Semaste
276254721Semaste        oss.flush();
277254721Semaste
278254721Semaste        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
279254721Semaste    }
280254721Semaste
281254721Semaste    llvm::Triple triple(m_module->getTargetTriple());
282254721Semaste    llvm::Function *function = m_module->getFunction (m_name.AsCString());
283254721Semaste    llvm::Reloc::Model relocModel;
284254721Semaste    llvm::CodeModel::Model codeModel;
285254721Semaste
286254721Semaste    if (triple.isOSBinFormatELF())
287254721Semaste    {
288254721Semaste        relocModel = llvm::Reloc::Static;
289254721Semaste        // This will be small for 32-bit and large for 64-bit.
290254721Semaste        codeModel = llvm::CodeModel::JITDefault;
291254721Semaste    }
292254721Semaste    else
293254721Semaste    {
294254721Semaste        relocModel = llvm::Reloc::PIC_;
295254721Semaste        codeModel = llvm::CodeModel::Small;
296254721Semaste    }
297254721Semaste
298254721Semaste    m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
299254721Semaste
300254721Semaste    llvm::EngineBuilder builder(m_module_ap.get());
301254721Semaste
302254721Semaste    builder.setEngineKind(llvm::EngineKind::JIT)
303254721Semaste    .setErrorStr(&error_string)
304254721Semaste    .setRelocationModel(relocModel)
305254721Semaste    .setJITMemoryManager(new MemoryManager(*this))
306254721Semaste    .setOptLevel(llvm::CodeGenOpt::Less)
307254721Semaste    .setAllocateGVsWithCode(true)
308254721Semaste    .setCodeModel(codeModel)
309254721Semaste    .setUseMCJIT(true);
310254721Semaste
311254721Semaste    llvm::StringRef mArch;
312254721Semaste    llvm::StringRef mCPU;
313254721Semaste    llvm::SmallVector<std::string, 0> mAttrs;
314254721Semaste
315254721Semaste    for (std::string &feature : m_cpu_features)
316254721Semaste        mAttrs.push_back(feature);
317254721Semaste
318254721Semaste    llvm::TargetMachine *target_machine = builder.selectTarget(triple,
319254721Semaste                                                               mArch,
320254721Semaste                                                               mCPU,
321254721Semaste                                                               mAttrs);
322254721Semaste
323254721Semaste    m_execution_engine_ap.reset(builder.create(target_machine));
324254721Semaste
325254721Semaste    if (!m_execution_engine_ap.get())
326254721Semaste    {
327254721Semaste        error.SetErrorToGenericError();
328254721Semaste        error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
329254721Semaste        return;
330254721Semaste    }
331254721Semaste    else
332254721Semaste    {
333254721Semaste        m_module_ap.release(); // ownership was transferred
334254721Semaste    }
335254721Semaste
336254721Semaste    m_execution_engine_ap->DisableLazyCompilation();
337254721Semaste
338254721Semaste    // We don't actually need the function pointer here, this just forces it to get resolved.
339254721Semaste
340254721Semaste    void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
341254721Semaste
342254721Semaste    if (!error.Success())
343254721Semaste    {
344254721Semaste        // We got an error through our callback!
345254721Semaste        return;
346254721Semaste    }
347254721Semaste
348254721Semaste    if (!function)
349254721Semaste    {
350254721Semaste        error.SetErrorToGenericError();
351254721Semaste        error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
352254721Semaste        return;
353254721Semaste    }
354254721Semaste
355254721Semaste    if (!fun_ptr)
356254721Semaste    {
357254721Semaste        error.SetErrorToGenericError();
358254721Semaste        error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
359254721Semaste        return;
360254721Semaste    }
361254721Semaste
362254721Semaste    m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
363254721Semaste
364254721Semaste    CommitAllocations(process_sp);
365254721Semaste    ReportAllocations(*m_execution_engine_ap);
366254721Semaste    WriteData(process_sp);
367254721Semaste
368254721Semaste    for (JittedFunction &jitted_function : m_jitted_functions)
369254721Semaste    {
370254721Semaste        jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
371254721Semaste
372254721Semaste        if (!jitted_function.m_name.compare(m_name.AsCString()))
373254721Semaste        {
374254721Semaste            AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
375254721Semaste            m_function_end_load_addr = func_range.first + func_range.second;
376254721Semaste            m_function_load_addr = jitted_function.m_remote_addr;
377254721Semaste        }
378254721Semaste    }
379254721Semaste
380254721Semaste    if (log)
381254721Semaste    {
382254721Semaste        log->Printf("Code can be run in the target.");
383254721Semaste
384254721Semaste        StreamString disassembly_stream;
385254721Semaste
386254721Semaste        Error err = DisassembleFunction(disassembly_stream, process_sp);
387254721Semaste
388254721Semaste        if (!err.Success())
389254721Semaste        {
390254721Semaste            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
391254721Semaste        }
392254721Semaste        else
393254721Semaste        {
394254721Semaste            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
395254721Semaste        }
396269024Semaste
397269024Semaste        log->Printf("Sections: ");
398269024Semaste        for (AllocationRecord &record : m_records)
399269024Semaste        {
400269024Semaste            if (record.m_process_address != LLDB_INVALID_ADDRESS)
401269024Semaste            {
402269024Semaste                record.dump(log);
403269024Semaste
404269024Semaste                DataBufferHeap my_buffer(record.m_size, 0);
405269024Semaste                Error err;
406269024Semaste                ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);
407269024Semaste
408269024Semaste                if (err.Success())
409269024Semaste                {
410269024Semaste                    DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
411269024Semaste                    my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), record.m_process_address, 16, DataExtractor::TypeUInt8);
412269024Semaste                }
413269024Semaste            }
414269024Semaste        }
415254721Semaste    }
416254721Semaste
417254721Semaste    func_addr = m_function_load_addr;
418254721Semaste    func_end = m_function_end_load_addr;
419254721Semaste
420254721Semaste    return;
421254721Semaste}
422254721Semaste
423254721SemasteIRExecutionUnit::~IRExecutionUnit ()
424254721Semaste{
425254721Semaste    m_module_ap.reset();
426254721Semaste    m_execution_engine_ap.reset();
427254721Semaste    m_context_ap.reset();
428254721Semaste}
429254721Semaste
430254721SemasteIRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
431254721Semaste    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
432254721Semaste    m_parent (parent)
433254721Semaste{
434254721Semaste}
435254721Semaste
436254721Semastevoid
437254721SemasteIRExecutionUnit::MemoryManager::setMemoryWritable ()
438254721Semaste{
439254721Semaste    m_default_mm_ap->setMemoryWritable();
440254721Semaste}
441254721Semaste
442254721Semastevoid
443254721SemasteIRExecutionUnit::MemoryManager::setMemoryExecutable ()
444254721Semaste{
445254721Semaste    m_default_mm_ap->setMemoryExecutable();
446254721Semaste}
447254721Semaste
448254721Semaste
449254721Semasteuint8_t *
450254721SemasteIRExecutionUnit::MemoryManager::startFunctionBody(const llvm::Function *F,
451254721Semaste                                                  uintptr_t &ActualSize)
452254721Semaste{
453254721Semaste    return m_default_mm_ap->startFunctionBody(F, ActualSize);
454254721Semaste}
455254721Semaste
456254721Semasteuint8_t *
457254721SemasteIRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F,
458254721Semaste                                             unsigned StubSize,
459254721Semaste                                             unsigned Alignment)
460254721Semaste{
461254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
462254721Semaste
463254721Semaste    uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
464254721Semaste
465254721Semaste    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
466254721Semaste                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
467254721Semaste                                                  StubSize,
468254721Semaste                                                  Alignment));
469254721Semaste
470254721Semaste    if (log)
471254721Semaste    {
472254721Semaste        log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
473254721Semaste                    F, StubSize, Alignment, return_value);
474254721Semaste    }
475254721Semaste
476254721Semaste    return return_value;
477254721Semaste}
478254721Semaste
479254721Semastevoid
480254721SemasteIRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F,
481254721Semaste                                                uint8_t *FunctionStart,
482254721Semaste                                                uint8_t *FunctionEnd)
483254721Semaste{
484254721Semaste    m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
485254721Semaste}
486254721Semaste
487254721Semasteuint8_t *
488254721SemasteIRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
489254721Semaste{
490254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
491254721Semaste
492254721Semaste    uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
493254721Semaste
494254721Semaste    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
495254721Semaste                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
496254721Semaste                                                  Size,
497254721Semaste                                                  Alignment));
498254721Semaste
499254721Semaste    if (log)
500254721Semaste    {
501254721Semaste        log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
502254721Semaste                               (uint64_t)Size, Alignment, return_value);
503254721Semaste    }
504254721Semaste
505254721Semaste    return return_value;
506254721Semaste}
507254721Semaste
508254721Semasteuint8_t *
509254721SemasteIRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
510254721Semaste                                                    unsigned Alignment,
511263508Sdim                                                    unsigned SectionID,
512263508Sdim                                                    llvm::StringRef SectionName)
513254721Semaste{
514254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
515254721Semaste
516263508Sdim    uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID, SectionName);
517254721Semaste
518254721Semaste    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
519254721Semaste                                                  lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
520254721Semaste                                                  Size,
521254721Semaste                                                  Alignment,
522254721Semaste                                                  SectionID));
523254721Semaste
524254721Semaste    if (log)
525254721Semaste    {
526254721Semaste        log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
527254721Semaste                    (uint64_t)Size, Alignment, SectionID, return_value);
528254721Semaste    }
529254721Semaste
530254721Semaste    return return_value;
531254721Semaste}
532254721Semaste
533254721Semasteuint8_t *
534254721SemasteIRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
535254721Semaste                                                    unsigned Alignment,
536254721Semaste                                                    unsigned SectionID,
537263508Sdim                                                    llvm::StringRef SectionName,
538254721Semaste                                                    bool IsReadOnly)
539254721Semaste{
540254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
541254721Semaste
542263508Sdim    uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
543254721Semaste
544254721Semaste    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
545254721Semaste                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
546254721Semaste                                                  Size,
547254721Semaste                                                  Alignment,
548254721Semaste                                                  SectionID));
549254721Semaste    if (log)
550254721Semaste    {
551254721Semaste        log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
552254721Semaste                    (uint64_t)Size, Alignment, SectionID, return_value);
553254721Semaste    }
554254721Semaste
555254721Semaste    return return_value;
556254721Semaste}
557254721Semaste
558254721Semasteuint8_t *
559254721SemasteIRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size,
560254721Semaste                                               unsigned Alignment)
561254721Semaste{
562254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
563254721Semaste
564254721Semaste    uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
565254721Semaste
566254721Semaste    m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
567254721Semaste                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
568254721Semaste                                                  Size,
569254721Semaste                                                  Alignment));
570254721Semaste
571254721Semaste    if (log)
572254721Semaste    {
573254721Semaste        log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
574254721Semaste                    (uint64_t)Size, Alignment, return_value);
575254721Semaste    }
576254721Semaste
577254721Semaste    return return_value;
578254721Semaste}
579254721Semaste
580254721Semastevoid
581254721SemasteIRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body)
582254721Semaste{
583254721Semaste    m_default_mm_ap->deallocateFunctionBody(Body);
584254721Semaste}
585254721Semaste
586254721Semastelldb::addr_t
587254721SemasteIRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
588254721Semaste{
589254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
590254721Semaste
591254721Semaste    for (AllocationRecord &record : m_records)
592254721Semaste    {
593254721Semaste        if (local_address >= record.m_host_address &&
594254721Semaste            local_address < record.m_host_address + record.m_size)
595254721Semaste        {
596254721Semaste            if (record.m_process_address == LLDB_INVALID_ADDRESS)
597254721Semaste                return LLDB_INVALID_ADDRESS;
598254721Semaste
599254721Semaste            lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
600254721Semaste
601254721Semaste            if (log)
602254721Semaste            {
603254721Semaste                log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
604254721Semaste                            local_address,
605254721Semaste                            (uint64_t)record.m_host_address,
606254721Semaste                            (uint64_t)record.m_host_address + (uint64_t)record.m_size,
607254721Semaste                            ret,
608254721Semaste                            record.m_process_address,
609254721Semaste                            record.m_process_address + record.m_size);
610254721Semaste            }
611254721Semaste
612254721Semaste            return ret;
613254721Semaste        }
614254721Semaste    }
615254721Semaste
616254721Semaste    return LLDB_INVALID_ADDRESS;
617254721Semaste}
618254721Semaste
619254721SemasteIRExecutionUnit::AddrRange
620254721SemasteIRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
621254721Semaste{
622254721Semaste    for (AllocationRecord &record : m_records)
623254721Semaste    {
624254721Semaste        if (local_address >= record.m_host_address &&
625254721Semaste            local_address < record.m_host_address + record.m_size)
626254721Semaste        {
627254721Semaste            if (record.m_process_address == LLDB_INVALID_ADDRESS)
628254721Semaste                return AddrRange(0, 0);
629254721Semaste
630254721Semaste            return AddrRange(record.m_process_address, record.m_size);
631254721Semaste        }
632254721Semaste    }
633254721Semaste
634254721Semaste    return AddrRange (0, 0);
635254721Semaste}
636254721Semaste
637254721Semastebool
638254721SemasteIRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
639254721Semaste{
640254721Semaste    bool ret = true;
641254721Semaste
642254721Semaste    lldb_private::Error err;
643254721Semaste
644254721Semaste    for (AllocationRecord &record : m_records)
645254721Semaste    {
646254721Semaste        if (record.m_process_address != LLDB_INVALID_ADDRESS)
647254721Semaste            continue;
648254721Semaste
649254721Semaste
650254721Semaste        record.m_process_address = Malloc(record.m_size,
651254721Semaste                                          record.m_alignment,
652254721Semaste                                          record.m_permissions,
653254721Semaste                                          eAllocationPolicyProcessOnly,
654254721Semaste                                          err);
655254721Semaste
656254721Semaste        if (!err.Success())
657254721Semaste        {
658254721Semaste            ret = false;
659254721Semaste            break;
660254721Semaste        }
661254721Semaste    }
662254721Semaste
663254721Semaste    if (!ret)
664254721Semaste    {
665254721Semaste        for (AllocationRecord &record : m_records)
666254721Semaste        {
667254721Semaste            if (record.m_process_address != LLDB_INVALID_ADDRESS)
668254721Semaste            {
669254721Semaste                Free(record.m_process_address, err);
670254721Semaste                record.m_process_address = LLDB_INVALID_ADDRESS;
671254721Semaste            }
672254721Semaste        }
673254721Semaste    }
674254721Semaste
675254721Semaste    return ret;
676254721Semaste}
677254721Semaste
678254721Semastevoid
679254721SemasteIRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
680254721Semaste{
681254721Semaste    for (AllocationRecord &record : m_records)
682254721Semaste    {
683254721Semaste        if (record.m_process_address == LLDB_INVALID_ADDRESS)
684254721Semaste            continue;
685254721Semaste
686254721Semaste        if (record.m_section_id == eSectionIDInvalid)
687254721Semaste            continue;
688254721Semaste
689254721Semaste        engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
690254721Semaste    }
691254721Semaste
692254721Semaste    // Trigger re-application of relocations.
693254721Semaste    engine.finalizeObject();
694254721Semaste}
695254721Semaste
696254721Semastebool
697254721SemasteIRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
698254721Semaste{
699254721Semaste    for (AllocationRecord &record : m_records)
700254721Semaste    {
701254721Semaste        if (record.m_process_address == LLDB_INVALID_ADDRESS)
702254721Semaste            return false;
703254721Semaste
704254721Semaste        lldb_private::Error err;
705254721Semaste
706254721Semaste        WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
707254721Semaste    }
708254721Semaste
709254721Semaste    return true;
710254721Semaste}
711254721Semaste
712254721Semastevoid
713254721SemasteIRExecutionUnit::AllocationRecord::dump (Log *log)
714254721Semaste{
715254721Semaste    if (!log)
716254721Semaste        return;
717254721Semaste
718254721Semaste    log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
719254721Semaste                (unsigned long long)m_host_address,
720254721Semaste                (unsigned long long)m_size,
721254721Semaste                (unsigned long long)m_process_address,
722254721Semaste                (unsigned)m_alignment,
723254721Semaste                (unsigned)m_section_id);
724254721Semaste}
725