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