1 //===-- IRMemoryMap.cpp ---------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Expression/IRMemoryMap.h" 10 #include "lldb/Target/MemoryRegionInfo.h" 11 #include "lldb/Target/Process.h" 12 #include "lldb/Target/Target.h" 13 #include "lldb/Utility/DataBufferHeap.h" 14 #include "lldb/Utility/DataExtractor.h" 15 #include "lldb/Utility/LLDBAssert.h" 16 #include "lldb/Utility/LLDBLog.h" 17 #include "lldb/Utility/Log.h" 18 #include "lldb/Utility/Scalar.h" 19 #include "lldb/Utility/Status.h" 20 21 using namespace lldb_private; 22 23 IRMemoryMap::IRMemoryMap(lldb::TargetSP target_sp) : m_target_wp(target_sp) { 24 if (target_sp) 25 m_process_wp = target_sp->GetProcessSP(); 26 } 27 28 IRMemoryMap::~IRMemoryMap() { 29 lldb::ProcessSP process_sp = m_process_wp.lock(); 30 31 if (process_sp) { 32 AllocationMap::iterator iter; 33 34 Status err; 35 36 while ((iter = m_allocations.begin()) != m_allocations.end()) { 37 err.Clear(); 38 if (iter->second.m_leak) 39 m_allocations.erase(iter); 40 else 41 Free(iter->first, err); 42 } 43 } 44 } 45 46 lldb::addr_t IRMemoryMap::FindSpace(size_t size) { 47 // The FindSpace algorithm's job is to find a region of memory that the 48 // underlying process is unlikely to be using. 49 // 50 // The memory returned by this function will never be written to. The only 51 // point is that it should not shadow process memory if possible, so that 52 // expressions processing real values from the process do not use the wrong 53 // data. 54 // 55 // If the process can in fact allocate memory (CanJIT() lets us know this) 56 // then this can be accomplished just be allocating memory in the inferior. 57 // Then no guessing is required. 58 59 lldb::TargetSP target_sp = m_target_wp.lock(); 60 lldb::ProcessSP process_sp = m_process_wp.lock(); 61 62 const bool process_is_alive = process_sp && process_sp->IsAlive(); 63 64 lldb::addr_t ret = LLDB_INVALID_ADDRESS; 65 if (size == 0) 66 return ret; 67 68 if (process_is_alive && process_sp->CanJIT()) { 69 Status alloc_error; 70 71 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | 72 lldb::ePermissionsWritable, 73 alloc_error); 74 75 if (!alloc_error.Success()) 76 return LLDB_INVALID_ADDRESS; 77 else 78 return ret; 79 } 80 81 // At this point we know that we need to hunt. 82 // 83 // First, go to the end of the existing allocations we've made if there are 84 // any allocations. Otherwise start at the beginning of memory. 85 86 if (m_allocations.empty()) { 87 ret = 0; 88 } else { 89 auto back = m_allocations.rbegin(); 90 lldb::addr_t addr = back->first; 91 size_t alloc_size = back->second.m_size; 92 ret = llvm::alignTo(addr + alloc_size, 4096); 93 } 94 95 uint64_t end_of_memory; 96 switch (GetAddressByteSize()) { 97 case 2: 98 end_of_memory = 0xffffull; 99 break; 100 case 4: 101 end_of_memory = 0xffffffffull; 102 break; 103 case 8: 104 end_of_memory = 0xffffffffffffffffull; 105 break; 106 default: 107 lldbassert(false && "Invalid address size."); 108 return LLDB_INVALID_ADDRESS; 109 } 110 111 // Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped 112 // regions, walk forward through memory until a region is found that has 113 // adequate space for our allocation. 114 if (process_is_alive) { 115 MemoryRegionInfo region_info; 116 Status err = process_sp->GetMemoryRegionInfo(ret, region_info); 117 if (err.Success()) { 118 while (true) { 119 if (region_info.GetRange().GetRangeBase() == 0 && 120 region_info.GetRange().GetRangeEnd() < end_of_memory) { 121 // Don't use a region that starts at address 0, 122 // it can make it harder to debug null dereference crashes 123 // in the inferior. 124 ret = region_info.GetRange().GetRangeEnd(); 125 } else if (region_info.GetReadable() != 126 MemoryRegionInfo::OptionalBool::eNo || 127 region_info.GetWritable() != 128 MemoryRegionInfo::OptionalBool::eNo || 129 region_info.GetExecutable() != 130 MemoryRegionInfo::OptionalBool::eNo) { 131 if (region_info.GetRange().GetRangeEnd() - 1 >= end_of_memory) { 132 ret = LLDB_INVALID_ADDRESS; 133 break; 134 } else { 135 ret = region_info.GetRange().GetRangeEnd(); 136 } 137 } else if (ret + size < region_info.GetRange().GetRangeEnd()) { 138 return ret; 139 } else { 140 // ret stays the same. We just need to walk a bit further. 141 } 142 143 err = process_sp->GetMemoryRegionInfo( 144 region_info.GetRange().GetRangeEnd(), region_info); 145 if (err.Fail()) { 146 lldbassert(0 && "GetMemoryRegionInfo() succeeded, then failed"); 147 ret = LLDB_INVALID_ADDRESS; 148 break; 149 } 150 } 151 } 152 } 153 154 // We've tried our algorithm, and it didn't work. Now we have to reset back 155 // to the end of the allocations we've already reported, or use a 'sensible' 156 // default if this is our first allocation. 157 if (m_allocations.empty()) { 158 uint64_t alloc_address = target_sp->GetExprAllocAddress(); 159 if (alloc_address > 0) { 160 if (alloc_address >= end_of_memory) { 161 lldbassert(0 && "The allocation address for expression evaluation must " 162 "be within process address space"); 163 return LLDB_INVALID_ADDRESS; 164 } 165 ret = alloc_address; 166 } else { 167 uint32_t address_byte_size = GetAddressByteSize(); 168 if (address_byte_size != UINT32_MAX) { 169 switch (address_byte_size) { 170 case 2: 171 ret = 0x8000ull; 172 break; 173 case 4: 174 ret = 0xee000000ull; 175 break; 176 case 8: 177 ret = 0xdead0fff00000000ull; 178 break; 179 default: 180 lldbassert(false && "Invalid address size."); 181 return LLDB_INVALID_ADDRESS; 182 } 183 } 184 } 185 } else { 186 auto back = m_allocations.rbegin(); 187 lldb::addr_t addr = back->first; 188 size_t alloc_size = back->second.m_size; 189 uint64_t align = target_sp->GetExprAllocAlign(); 190 if (align == 0) 191 align = 4096; 192 ret = llvm::alignTo(addr + alloc_size, align); 193 } 194 195 return ret; 196 } 197 198 IRMemoryMap::AllocationMap::iterator 199 IRMemoryMap::FindAllocation(lldb::addr_t addr, size_t size) { 200 if (addr == LLDB_INVALID_ADDRESS) 201 return m_allocations.end(); 202 203 AllocationMap::iterator iter = m_allocations.lower_bound(addr); 204 205 if (iter == m_allocations.end() || iter->first > addr) { 206 if (iter == m_allocations.begin()) 207 return m_allocations.end(); 208 iter--; 209 } 210 211 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size) 212 return iter; 213 214 return m_allocations.end(); 215 } 216 217 bool IRMemoryMap::IntersectsAllocation(lldb::addr_t addr, size_t size) const { 218 if (addr == LLDB_INVALID_ADDRESS) 219 return false; 220 221 AllocationMap::const_iterator iter = m_allocations.lower_bound(addr); 222 223 // Since we only know that the returned interval begins at a location greater 224 // than or equal to where the given interval begins, it's possible that the 225 // given interval intersects either the returned interval or the previous 226 // interval. Thus, we need to check both. Note that we only need to check 227 // these two intervals. Since all intervals are disjoint it is not possible 228 // that an adjacent interval does not intersect, but a non-adjacent interval 229 // does intersect. 230 if (iter != m_allocations.end()) { 231 if (AllocationsIntersect(addr, size, iter->second.m_process_start, 232 iter->second.m_size)) 233 return true; 234 } 235 236 if (iter != m_allocations.begin()) { 237 --iter; 238 if (AllocationsIntersect(addr, size, iter->second.m_process_start, 239 iter->second.m_size)) 240 return true; 241 } 242 243 return false; 244 } 245 246 bool IRMemoryMap::AllocationsIntersect(lldb::addr_t addr1, size_t size1, 247 lldb::addr_t addr2, size_t size2) { 248 // Given two half open intervals [A, B) and [X, Y), the only 6 permutations 249 // that satisfy A<B and X<Y are the following: 250 // A B X Y 251 // A X B Y (intersects) 252 // A X Y B (intersects) 253 // X A B Y (intersects) 254 // X A Y B (intersects) 255 // X Y A B 256 // The first is B <= X, and the last is Y <= A. So the condition is !(B <= X 257 // || Y <= A)), or (X < B && A < Y) 258 return (addr2 < (addr1 + size1)) && (addr1 < (addr2 + size2)); 259 } 260 261 lldb::ByteOrder IRMemoryMap::GetByteOrder() { 262 lldb::ProcessSP process_sp = m_process_wp.lock(); 263 264 if (process_sp) 265 return process_sp->GetByteOrder(); 266 267 lldb::TargetSP target_sp = m_target_wp.lock(); 268 269 if (target_sp) 270 return target_sp->GetArchitecture().GetByteOrder(); 271 272 return lldb::eByteOrderInvalid; 273 } 274 275 uint32_t IRMemoryMap::GetAddressByteSize() { 276 lldb::ProcessSP process_sp = m_process_wp.lock(); 277 278 if (process_sp) 279 return process_sp->GetAddressByteSize(); 280 281 lldb::TargetSP target_sp = m_target_wp.lock(); 282 283 if (target_sp) 284 return target_sp->GetArchitecture().GetAddressByteSize(); 285 286 return UINT32_MAX; 287 } 288 289 ExecutionContextScope *IRMemoryMap::GetBestExecutionContextScope() const { 290 lldb::ProcessSP process_sp = m_process_wp.lock(); 291 292 if (process_sp) 293 return process_sp.get(); 294 295 lldb::TargetSP target_sp = m_target_wp.lock(); 296 297 if (target_sp) 298 return target_sp.get(); 299 300 return nullptr; 301 } 302 303 IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc, 304 lldb::addr_t process_start, size_t size, 305 uint32_t permissions, uint8_t alignment, 306 AllocationPolicy policy) 307 : m_process_alloc(process_alloc), m_process_start(process_start), 308 m_size(size), m_policy(policy), m_leak(false), m_permissions(permissions), 309 m_alignment(alignment) { 310 switch (policy) { 311 default: 312 llvm_unreachable("Invalid AllocationPolicy"); 313 case eAllocationPolicyHostOnly: 314 case eAllocationPolicyMirror: 315 m_data.SetByteSize(size); 316 break; 317 case eAllocationPolicyProcessOnly: 318 break; 319 } 320 } 321 322 lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment, 323 uint32_t permissions, AllocationPolicy policy, 324 bool zero_memory, Status &error) { 325 lldb_private::Log *log(GetLog(LLDBLog::Expressions)); 326 error.Clear(); 327 328 lldb::ProcessSP process_sp; 329 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS; 330 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS; 331 332 size_t allocation_size; 333 334 if (size == 0) { 335 // FIXME: Malloc(0) should either return an invalid address or assert, in 336 // order to cut down on unnecessary allocations. 337 allocation_size = alignment; 338 } else { 339 // Round up the requested size to an aligned value. 340 allocation_size = llvm::alignTo(size, alignment); 341 342 // The process page cache does not see the requested alignment. We can't 343 // assume its result will be any more than 1-byte aligned. To work around 344 // this, request `alignment - 1` additional bytes. 345 allocation_size += alignment - 1; 346 } 347 348 switch (policy) { 349 default: 350 error = 351 Status::FromErrorString("Couldn't malloc: invalid allocation policy"); 352 return LLDB_INVALID_ADDRESS; 353 case eAllocationPolicyHostOnly: 354 allocation_address = FindSpace(allocation_size); 355 if (allocation_address == LLDB_INVALID_ADDRESS) { 356 error = Status::FromErrorString("Couldn't malloc: address space is full"); 357 return LLDB_INVALID_ADDRESS; 358 } 359 break; 360 case eAllocationPolicyMirror: 361 process_sp = m_process_wp.lock(); 362 LLDB_LOGF(log, 363 "IRMemoryMap::%s process_sp=0x%" PRIxPTR 364 ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s", 365 __FUNCTION__, reinterpret_cast<uintptr_t>(process_sp.get()), 366 process_sp && process_sp->CanJIT() ? "true" : "false", 367 process_sp && process_sp->IsAlive() ? "true" : "false"); 368 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) { 369 if (!zero_memory) 370 allocation_address = 371 process_sp->AllocateMemory(allocation_size, permissions, error); 372 else 373 allocation_address = 374 process_sp->CallocateMemory(allocation_size, permissions, error); 375 376 if (!error.Success()) 377 return LLDB_INVALID_ADDRESS; 378 } else { 379 LLDB_LOGF(log, 380 "IRMemoryMap::%s switching to eAllocationPolicyHostOnly " 381 "due to failed condition (see previous expr log message)", 382 __FUNCTION__); 383 policy = eAllocationPolicyHostOnly; 384 allocation_address = FindSpace(allocation_size); 385 if (allocation_address == LLDB_INVALID_ADDRESS) { 386 error = 387 Status::FromErrorString("Couldn't malloc: address space is full"); 388 return LLDB_INVALID_ADDRESS; 389 } 390 } 391 break; 392 case eAllocationPolicyProcessOnly: 393 process_sp = m_process_wp.lock(); 394 if (process_sp) { 395 if (process_sp->CanJIT() && process_sp->IsAlive()) { 396 if (!zero_memory) 397 allocation_address = 398 process_sp->AllocateMemory(allocation_size, permissions, error); 399 else 400 allocation_address = 401 process_sp->CallocateMemory(allocation_size, permissions, error); 402 403 if (!error.Success()) 404 return LLDB_INVALID_ADDRESS; 405 } else { 406 error = Status::FromErrorString( 407 "Couldn't malloc: process doesn't support allocating memory"); 408 return LLDB_INVALID_ADDRESS; 409 } 410 } else { 411 error = Status::FromErrorString( 412 "Couldn't malloc: process doesn't exist, and this " 413 "memory must be in the process"); 414 return LLDB_INVALID_ADDRESS; 415 } 416 break; 417 } 418 419 lldb::addr_t mask = alignment - 1; 420 aligned_address = (allocation_address + mask) & (~mask); 421 422 m_allocations.emplace( 423 std::piecewise_construct, std::forward_as_tuple(aligned_address), 424 std::forward_as_tuple(allocation_address, aligned_address, 425 allocation_size, permissions, alignment, policy)); 426 427 if (zero_memory) { 428 Status write_error; 429 std::vector<uint8_t> zero_buf(size, 0); 430 WriteMemory(aligned_address, zero_buf.data(), size, write_error); 431 } 432 433 if (log) { 434 const char *policy_string; 435 436 switch (policy) { 437 default: 438 policy_string = "<invalid policy>"; 439 break; 440 case eAllocationPolicyHostOnly: 441 policy_string = "eAllocationPolicyHostOnly"; 442 break; 443 case eAllocationPolicyProcessOnly: 444 policy_string = "eAllocationPolicyProcessOnly"; 445 break; 446 case eAllocationPolicyMirror: 447 policy_string = "eAllocationPolicyMirror"; 448 break; 449 } 450 451 LLDB_LOGF(log, 452 "IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 453 ", %s) -> 0x%" PRIx64, 454 (uint64_t)allocation_size, (uint64_t)alignment, 455 (uint64_t)permissions, policy_string, aligned_address); 456 } 457 458 return aligned_address; 459 } 460 461 void IRMemoryMap::Leak(lldb::addr_t process_address, Status &error) { 462 error.Clear(); 463 464 AllocationMap::iterator iter = m_allocations.find(process_address); 465 466 if (iter == m_allocations.end()) { 467 error = Status::FromErrorString("Couldn't leak: allocation doesn't exist"); 468 return; 469 } 470 471 Allocation &allocation = iter->second; 472 473 allocation.m_leak = true; 474 } 475 476 void IRMemoryMap::Free(lldb::addr_t process_address, Status &error) { 477 error.Clear(); 478 479 AllocationMap::iterator iter = m_allocations.find(process_address); 480 481 if (iter == m_allocations.end()) { 482 error = Status::FromErrorString("Couldn't free: allocation doesn't exist"); 483 return; 484 } 485 486 Allocation &allocation = iter->second; 487 488 switch (allocation.m_policy) { 489 default: 490 case eAllocationPolicyHostOnly: { 491 lldb::ProcessSP process_sp = m_process_wp.lock(); 492 if (process_sp) { 493 if (process_sp->CanJIT() && process_sp->IsAlive()) 494 process_sp->DeallocateMemory( 495 allocation.m_process_alloc); // FindSpace allocated this for real 496 } 497 498 break; 499 } 500 case eAllocationPolicyMirror: 501 case eAllocationPolicyProcessOnly: { 502 lldb::ProcessSP process_sp = m_process_wp.lock(); 503 if (process_sp) 504 process_sp->DeallocateMemory(allocation.m_process_alloc); 505 } 506 } 507 508 if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { 509 LLDB_LOGF(log, 510 "IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 511 "..0x%" PRIx64 ")", 512 (uint64_t)process_address, iter->second.m_process_start, 513 iter->second.m_process_start + iter->second.m_size); 514 } 515 516 m_allocations.erase(iter); 517 } 518 519 bool IRMemoryMap::GetAllocSize(lldb::addr_t address, size_t &size) { 520 AllocationMap::iterator iter = FindAllocation(address, size); 521 if (iter == m_allocations.end()) 522 return false; 523 524 Allocation &al = iter->second; 525 526 if (address > (al.m_process_start + al.m_size)) { 527 size = 0; 528 return false; 529 } 530 531 if (address > al.m_process_start) { 532 int dif = address - al.m_process_start; 533 size = al.m_size - dif; 534 return true; 535 } 536 537 size = al.m_size; 538 return true; 539 } 540 541 void IRMemoryMap::WriteMemory(lldb::addr_t process_address, 542 const uint8_t *bytes, size_t size, 543 Status &error) { 544 error.Clear(); 545 546 AllocationMap::iterator iter = FindAllocation(process_address, size); 547 548 if (iter == m_allocations.end()) { 549 lldb::ProcessSP process_sp = m_process_wp.lock(); 550 551 if (process_sp) { 552 process_sp->WriteMemory(process_address, bytes, size, error); 553 return; 554 } 555 556 error = Status::FromErrorString( 557 "Couldn't write: no allocation contains the target " 558 "range and the process doesn't exist"); 559 return; 560 } 561 562 Allocation &allocation = iter->second; 563 564 uint64_t offset = process_address - allocation.m_process_start; 565 566 lldb::ProcessSP process_sp; 567 568 switch (allocation.m_policy) { 569 default: 570 error = 571 Status::FromErrorString("Couldn't write: invalid allocation policy"); 572 return; 573 case eAllocationPolicyHostOnly: 574 if (!allocation.m_data.GetByteSize()) { 575 error = Status::FromErrorString("Couldn't write: data buffer is empty"); 576 return; 577 } 578 ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size); 579 break; 580 case eAllocationPolicyMirror: 581 if (!allocation.m_data.GetByteSize()) { 582 error = Status::FromErrorString("Couldn't write: data buffer is empty"); 583 return; 584 } 585 ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size); 586 process_sp = m_process_wp.lock(); 587 if (process_sp) { 588 process_sp->WriteMemory(process_address, bytes, size, error); 589 if (!error.Success()) 590 return; 591 } 592 break; 593 case eAllocationPolicyProcessOnly: 594 process_sp = m_process_wp.lock(); 595 if (process_sp) { 596 process_sp->WriteMemory(process_address, bytes, size, error); 597 if (!error.Success()) 598 return; 599 } 600 break; 601 } 602 603 if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { 604 LLDB_LOGF(log, 605 "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIxPTR 606 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", 607 (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size, 608 (uint64_t)allocation.m_process_start, 609 (uint64_t)allocation.m_process_start + 610 (uint64_t)allocation.m_size); 611 } 612 } 613 614 void IRMemoryMap::WriteScalarToMemory(lldb::addr_t process_address, 615 Scalar &scalar, size_t size, 616 Status &error) { 617 error.Clear(); 618 619 if (size == UINT32_MAX) 620 size = scalar.GetByteSize(); 621 622 if (size > 0) { 623 uint8_t buf[32]; 624 const size_t mem_size = 625 scalar.GetAsMemoryData(buf, size, GetByteOrder(), error); 626 if (mem_size > 0) { 627 return WriteMemory(process_address, buf, mem_size, error); 628 } else { 629 error = Status::FromErrorString( 630 "Couldn't write scalar: failed to get scalar as memory data"); 631 } 632 } else { 633 error = Status::FromErrorString("Couldn't write scalar: its size was zero"); 634 } 635 } 636 637 void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address, 638 lldb::addr_t address, Status &error) { 639 error.Clear(); 640 641 Scalar scalar(address); 642 643 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error); 644 } 645 646 void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address, 647 size_t size, Status &error) { 648 error.Clear(); 649 650 AllocationMap::iterator iter = FindAllocation(process_address, size); 651 652 if (iter == m_allocations.end()) { 653 lldb::ProcessSP process_sp = m_process_wp.lock(); 654 655 if (process_sp) { 656 process_sp->ReadMemory(process_address, bytes, size, error); 657 return; 658 } 659 660 lldb::TargetSP target_sp = m_target_wp.lock(); 661 662 if (target_sp) { 663 Address absolute_address(process_address); 664 target_sp->ReadMemory(absolute_address, bytes, size, error, true); 665 return; 666 } 667 668 error = Status::FromErrorString( 669 "Couldn't read: no allocation contains the target " 670 "range, and neither the process nor the target exist"); 671 return; 672 } 673 674 Allocation &allocation = iter->second; 675 676 uint64_t offset = process_address - allocation.m_process_start; 677 678 if (offset > allocation.m_size) { 679 error = 680 Status::FromErrorString("Couldn't read: data is not in the allocation"); 681 return; 682 } 683 684 lldb::ProcessSP process_sp; 685 686 switch (allocation.m_policy) { 687 default: 688 error = Status::FromErrorString("Couldn't read: invalid allocation policy"); 689 return; 690 case eAllocationPolicyHostOnly: 691 if (!allocation.m_data.GetByteSize()) { 692 error = Status::FromErrorString("Couldn't read: data buffer is empty"); 693 return; 694 } 695 if (allocation.m_data.GetByteSize() < offset + size) { 696 error = 697 Status::FromErrorString("Couldn't read: not enough underlying data"); 698 return; 699 } 700 701 ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size); 702 break; 703 case eAllocationPolicyMirror: 704 process_sp = m_process_wp.lock(); 705 if (process_sp) { 706 process_sp->ReadMemory(process_address, bytes, size, error); 707 if (!error.Success()) 708 return; 709 } else { 710 if (!allocation.m_data.GetByteSize()) { 711 error = Status::FromErrorString("Couldn't read: data buffer is empty"); 712 return; 713 } 714 ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size); 715 } 716 break; 717 case eAllocationPolicyProcessOnly: 718 process_sp = m_process_wp.lock(); 719 if (process_sp) { 720 process_sp->ReadMemory(process_address, bytes, size, error); 721 if (!error.Success()) 722 return; 723 } 724 break; 725 } 726 727 if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) { 728 LLDB_LOGF(log, 729 "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIxPTR 730 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", 731 (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size, 732 (uint64_t)allocation.m_process_start, 733 (uint64_t)allocation.m_process_start + 734 (uint64_t)allocation.m_size); 735 } 736 } 737 738 void IRMemoryMap::ReadScalarFromMemory(Scalar &scalar, 739 lldb::addr_t process_address, 740 size_t size, Status &error) { 741 error.Clear(); 742 743 if (size > 0) { 744 DataBufferHeap buf(size, 0); 745 ReadMemory(buf.GetBytes(), process_address, size, error); 746 747 if (!error.Success()) 748 return; 749 750 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), 751 GetAddressByteSize()); 752 753 lldb::offset_t offset = 0; 754 755 switch (size) { 756 default: 757 error = Status::FromErrorStringWithFormat( 758 "Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size); 759 return; 760 case 1: 761 scalar = extractor.GetU8(&offset); 762 break; 763 case 2: 764 scalar = extractor.GetU16(&offset); 765 break; 766 case 4: 767 scalar = extractor.GetU32(&offset); 768 break; 769 case 8: 770 scalar = extractor.GetU64(&offset); 771 break; 772 } 773 } else { 774 error = Status::FromErrorString("Couldn't read scalar: its size was zero"); 775 } 776 } 777 778 void IRMemoryMap::ReadPointerFromMemory(lldb::addr_t *address, 779 lldb::addr_t process_address, 780 Status &error) { 781 error.Clear(); 782 783 Scalar pointer_scalar; 784 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), 785 error); 786 787 if (!error.Success()) 788 return; 789 790 *address = pointer_scalar.ULongLong(); 791 } 792 793 void IRMemoryMap::GetMemoryData(DataExtractor &extractor, 794 lldb::addr_t process_address, size_t size, 795 Status &error) { 796 error.Clear(); 797 798 if (size > 0) { 799 AllocationMap::iterator iter = FindAllocation(process_address, size); 800 801 if (iter == m_allocations.end()) { 802 error = Status::FromErrorStringWithFormat( 803 "Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 804 ")", 805 process_address, process_address + size); 806 return; 807 } 808 809 Allocation &allocation = iter->second; 810 811 switch (allocation.m_policy) { 812 default: 813 error = Status::FromErrorString( 814 "Couldn't get memory data: invalid allocation policy"); 815 return; 816 case eAllocationPolicyProcessOnly: 817 error = Status::FromErrorString( 818 "Couldn't get memory data: memory is only in the target"); 819 return; 820 case eAllocationPolicyMirror: { 821 lldb::ProcessSP process_sp = m_process_wp.lock(); 822 823 if (!allocation.m_data.GetByteSize()) { 824 error = Status::FromErrorString( 825 "Couldn't get memory data: data buffer is empty"); 826 return; 827 } 828 if (process_sp) { 829 process_sp->ReadMemory(allocation.m_process_start, 830 allocation.m_data.GetBytes(), 831 allocation.m_data.GetByteSize(), error); 832 if (!error.Success()) 833 return; 834 uint64_t offset = process_address - allocation.m_process_start; 835 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, 836 GetByteOrder(), GetAddressByteSize()); 837 return; 838 } 839 } break; 840 case eAllocationPolicyHostOnly: 841 if (!allocation.m_data.GetByteSize()) { 842 error = Status::FromErrorString( 843 "Couldn't get memory data: data buffer is empty"); 844 return; 845 } 846 uint64_t offset = process_address - allocation.m_process_start; 847 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, 848 GetByteOrder(), GetAddressByteSize()); 849 return; 850 } 851 } else { 852 error = 853 Status::FromErrorString("Couldn't get memory data: its size was zero"); 854 return; 855 } 856 } 857