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