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