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 void 422 IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error) 423 { 424 error.Clear(); 425 426 AllocationMap::iterator iter = FindAllocation(process_address, size); 427 428 if (iter == m_allocations.end()) 429 { 430 lldb::ProcessSP process_sp = m_process_wp.lock(); 431 432 if (process_sp) 433 { 434 process_sp->WriteMemory(process_address, bytes, size, error); 435 return; 436 } 437 438 error.SetErrorToGenericError(); 439 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist"); 440 return; 441 } 442 443 Allocation &allocation = iter->second; 444 445 uint64_t offset = process_address - allocation.m_process_start; 446 447 lldb::ProcessSP process_sp; 448 449 switch (allocation.m_policy) 450 { 451 default: 452 error.SetErrorToGenericError(); 453 error.SetErrorString("Couldn't write: invalid allocation policy"); 454 return; 455 case eAllocationPolicyHostOnly: 456 if (!allocation.m_data.GetByteSize()) 457 { 458 error.SetErrorToGenericError(); 459 error.SetErrorString("Couldn't write: data buffer is empty"); 460 return; 461 } 462 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 463 break; 464 case eAllocationPolicyMirror: 465 if (!allocation.m_data.GetByteSize()) 466 { 467 error.SetErrorToGenericError(); 468 error.SetErrorString("Couldn't write: data buffer is empty"); 469 return; 470 } 471 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 472 process_sp = m_process_wp.lock(); 473 if (process_sp) 474 { 475 process_sp->WriteMemory(process_address, bytes, size, error); 476 if (!error.Success()) 477 return; 478 } 479 break; 480 case eAllocationPolicyProcessOnly: 481 process_sp = m_process_wp.lock(); 482 if (process_sp) 483 { 484 process_sp->WriteMemory(process_address, bytes, size, error); 485 if (!error.Success()) 486 return; 487 } 488 break; 489 } 490 491 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 492 { 493 log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", 494 (uint64_t)process_address, 495 (uint64_t)bytes, 496 (uint64_t)size, 497 (uint64_t)allocation.m_process_start, 498 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 499 } 500 } 501 502 void 503 IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error) 504 { 505 error.Clear(); 506 507 if (size == UINT32_MAX) 508 size = scalar.GetByteSize(); 509 510 if (size > 0) 511 { 512 uint8_t buf[32]; 513 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error); 514 if (mem_size > 0) 515 { 516 return WriteMemory(process_address, buf, mem_size, error); 517 } 518 else 519 { 520 error.SetErrorToGenericError(); 521 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data"); 522 } 523 } 524 else 525 { 526 error.SetErrorToGenericError(); 527 error.SetErrorString ("Couldn't write scalar: its size was zero"); 528 } 529 return; 530 } 531 532 void 533 IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error) 534 { 535 error.Clear(); 536 537 Scalar scalar(address); 538 539 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error); 540 } 541 542 void 543 IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error) 544 { 545 error.Clear(); 546 547 AllocationMap::iterator iter = FindAllocation(process_address, size); 548 549 if (iter == m_allocations.end()) 550 { 551 lldb::ProcessSP process_sp = m_process_wp.lock(); 552 553 if (process_sp) 554 { 555 process_sp->ReadMemory(process_address, bytes, size, error); 556 return; 557 } 558 559 lldb::TargetSP target_sp = m_target_wp.lock(); 560 561 if (target_sp) 562 { 563 Address absolute_address(process_address); 564 target_sp->ReadMemory(absolute_address, false, bytes, size, error); 565 return; 566 } 567 568 error.SetErrorToGenericError(); 569 error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist"); 570 return; 571 } 572 573 Allocation &allocation = iter->second; 574 575 uint64_t offset = process_address - allocation.m_process_start; 576 577 if (offset > allocation.m_size) 578 { 579 error.SetErrorToGenericError(); 580 error.SetErrorString("Couldn't read: data is not in the allocation"); 581 return; 582 } 583 584 lldb::ProcessSP process_sp; 585 586 switch (allocation.m_policy) 587 { 588 default: 589 error.SetErrorToGenericError(); 590 error.SetErrorString("Couldn't read: invalid allocation policy"); 591 return; 592 case eAllocationPolicyHostOnly: 593 if (!allocation.m_data.GetByteSize()) 594 { 595 error.SetErrorToGenericError(); 596 error.SetErrorString("Couldn't read: data buffer is empty"); 597 return; 598 } 599 if (allocation.m_data.GetByteSize() < offset + size) 600 { 601 error.SetErrorToGenericError(); 602 error.SetErrorString("Couldn't read: not enough underlying data"); 603 return; 604 } 605 606 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 607 break; 608 case eAllocationPolicyMirror: 609 process_sp = m_process_wp.lock(); 610 if (process_sp) 611 { 612 process_sp->ReadMemory(process_address, bytes, size, error); 613 if (!error.Success()) 614 return; 615 } 616 else 617 { 618 if (!allocation.m_data.GetByteSize()) 619 { 620 error.SetErrorToGenericError(); 621 error.SetErrorString("Couldn't read: data buffer is empty"); 622 return; 623 } 624 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 625 } 626 break; 627 case eAllocationPolicyProcessOnly: 628 process_sp = m_process_wp.lock(); 629 if (process_sp) 630 { 631 process_sp->ReadMemory(process_address, bytes, size, error); 632 if (!error.Success()) 633 return; 634 } 635 break; 636 } 637 638 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 639 { 640 log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", 641 (uint64_t)process_address, 642 (uint64_t)bytes, 643 (uint64_t)size, 644 (uint64_t)allocation.m_process_start, 645 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 646 } 647 } 648 649 void 650 IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error) 651 { 652 error.Clear(); 653 654 if (size > 0) 655 { 656 DataBufferHeap buf(size, 0); 657 ReadMemory(buf.GetBytes(), process_address, size, error); 658 659 if (!error.Success()) 660 return; 661 662 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize()); 663 664 lldb::offset_t offset = 0; 665 666 switch (size) 667 { 668 default: 669 error.SetErrorToGenericError(); 670 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size); 671 return; 672 case 1: scalar = extractor.GetU8(&offset); break; 673 case 2: scalar = extractor.GetU16(&offset); break; 674 case 4: scalar = extractor.GetU32(&offset); break; 675 case 8: scalar = extractor.GetU64(&offset); break; 676 } 677 } 678 else 679 { 680 error.SetErrorToGenericError(); 681 error.SetErrorString ("Couldn't read scalar: its size was zero"); 682 } 683 return; 684 } 685 686 void 687 IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error) 688 { 689 error.Clear(); 690 691 Scalar pointer_scalar; 692 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error); 693 694 if (!error.Success()) 695 return; 696 697 *address = pointer_scalar.ULongLong(); 698 699 return; 700 } 701 702 void 703 IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error) 704 { 705 error.Clear(); 706 707 if (size > 0) 708 { 709 AllocationMap::iterator iter = FindAllocation(process_address, size); 710 711 if (iter == m_allocations.end()) 712 { 713 error.SetErrorToGenericError(); 714 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size); 715 return; 716 } 717 718 Allocation &allocation = iter->second; 719 720 switch (allocation.m_policy) 721 { 722 default: 723 error.SetErrorToGenericError(); 724 error.SetErrorString("Couldn't get memory data: invalid allocation policy"); 725 return; 726 case eAllocationPolicyProcessOnly: 727 error.SetErrorToGenericError(); 728 error.SetErrorString("Couldn't get memory data: memory is only in the target"); 729 return; 730 case eAllocationPolicyMirror: 731 { 732 lldb::ProcessSP process_sp = m_process_wp.lock(); 733 734 if (!allocation.m_data.GetByteSize()) 735 { 736 error.SetErrorToGenericError(); 737 error.SetErrorString("Couldn't get memory data: data buffer is empty"); 738 return; 739 } 740 if (process_sp) 741 { 742 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error); 743 if (!error.Success()) 744 return; 745 uint64_t offset = process_address - allocation.m_process_start; 746 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 747 return; 748 } 749 } 750 case eAllocationPolicyHostOnly: 751 if (!allocation.m_data.GetByteSize()) 752 { 753 error.SetErrorToGenericError(); 754 error.SetErrorString("Couldn't get memory data: data buffer is empty"); 755 return; 756 } 757 uint64_t offset = process_address - allocation.m_process_start; 758 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 759 return; 760 } 761 } 762 else 763 { 764 error.SetErrorToGenericError(); 765 error.SetErrorString ("Couldn't get memory data: its size was zero"); 766 return; 767 } 768 } 769