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