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