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