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