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