blob: 28a2fc1e0de6a02bd7687c2f2b0b402b6748d83f [file] [log] [blame]
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001//===-- 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
Sean Callanan35005f72013-04-12 18:10:34 +000010#include "lldb/Core/DataBufferHeap.h"
11#include "lldb/Core/DataExtractor.h"
Sean Callanan5a1af4e2013-04-05 02:22:57 +000012#include "lldb/Core/Error.h"
13#include "lldb/Core/Log.h"
Sean Callanan35005f72013-04-12 18:10:34 +000014#include "lldb/Core/Scalar.h"
Sean Callanan5a1af4e2013-04-05 02:22:57 +000015#include "lldb/Expression/IRMemoryMap.h"
16#include "lldb/Target/Process.h"
Sean Callanan35005f72013-04-12 18:10:34 +000017#include "lldb/Target/Target.h"
Sean Callanan5a1af4e2013-04-05 02:22:57 +000018
19using namespace lldb_private;
20
Sean Callanan35005f72013-04-12 18:10:34 +000021IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
Sean Callanan35005f72013-04-12 18:10:34 +000022 m_target_wp(target_sp)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000023{
Sean Callananb024d872013-04-15 17:12:47 +000024 if (target_sp)
25 m_process_wp = target_sp->GetProcessSP();
Sean Callanan5a1af4e2013-04-05 02:22:57 +000026}
27
28IRMemoryMap::~IRMemoryMap ()
29{
30 lldb::ProcessSP process_sp = m_process_wp.lock();
31
32 if (process_sp)
33 {
34 for (AllocationMap::value_type &allocation : m_allocations)
35 {
36 if (allocation.second.m_policy == eAllocationPolicyMirror ||
37 allocation.second.m_policy == eAllocationPolicyHostOnly)
38 process_sp->DeallocateMemory(allocation.second.m_process_alloc);
39
40 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
41 {
42 log->Printf("IRMemoryMap::~IRMemoryMap deallocated [0x%llx..0x%llx)",
43 (uint64_t)allocation.second.m_process_start,
44 (uint64_t)allocation.second.m_process_start + (uint64_t)allocation.second.m_size);
45 }
46 }
47 }
48}
49
50lldb::addr_t
51IRMemoryMap::FindSpace (size_t size)
52{
53 // Yup, this is just plain O(n) insertion. We'll use a range tree if we
54 // start caring.
55
56 lldb::addr_t remote_address = 0x1000; // skip first page of memory
57
58 for (AllocationMap::value_type &allocation : m_allocations)
59 {
60 if (remote_address < allocation.second.m_process_start &&
61 remote_address + size <= allocation.second.m_process_start)
62 return remote_address;
63
Sean Callanan08052af2013-04-17 07:50:58 +000064 remote_address = allocation.second.m_process_start + allocation.second.m_size;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000065 }
66
67 if (remote_address + size < remote_address)
68 return LLDB_INVALID_ADDRESS; // massively unlikely
69
70 return remote_address;
71}
72
73bool
74IRMemoryMap::ContainsHostOnlyAllocations ()
75{
76 for (AllocationMap::value_type &allocation : m_allocations)
77 {
78 if (allocation.second.m_policy == eAllocationPolicyHostOnly)
79 return true;
80 }
81
82 return false;
83}
84
85IRMemoryMap::AllocationMap::iterator
86IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
87{
Sean Callanan1582ee62013-04-18 22:06:33 +000088 if (addr == LLDB_INVALID_ADDRESS)
89 return m_allocations.end();
90
Sean Callanan5a1af4e2013-04-05 02:22:57 +000091 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
92
Sean Callanan14b1bae2013-04-16 23:25:35 +000093 if (iter == m_allocations.end() ||
94 iter->first > addr)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000095 {
96 if (iter == m_allocations.begin())
97 return m_allocations.end();
98 iter--;
99 }
100
101 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
102 return iter;
103
104 return m_allocations.end();
105}
106
Sean Callanan35005f72013-04-12 18:10:34 +0000107lldb::ByteOrder
108IRMemoryMap::GetByteOrder()
109{
110 lldb::ProcessSP process_sp = m_process_wp.lock();
111
112 if (process_sp)
113 return process_sp->GetByteOrder();
114
115 lldb::TargetSP target_sp = m_target_wp.lock();
116
117 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000118 return target_sp->GetArchitecture().GetByteOrder();
Sean Callanan35005f72013-04-12 18:10:34 +0000119
120 return lldb::eByteOrderInvalid;
121}
122
123uint32_t
124IRMemoryMap::GetAddressByteSize()
125{
126 lldb::ProcessSP process_sp = m_process_wp.lock();
127
128 if (process_sp)
129 return process_sp->GetAddressByteSize();
130
131 lldb::TargetSP target_sp = m_target_wp.lock();
132
133 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000134 return target_sp->GetArchitecture().GetAddressByteSize();
Sean Callanan35005f72013-04-12 18:10:34 +0000135
136 return UINT32_MAX;
137}
138
139ExecutionContextScope *
140IRMemoryMap::GetBestExecutionContextScope()
141{
142 lldb::ProcessSP process_sp = m_process_wp.lock();
143
144 if (process_sp)
145 return process_sp.get();
146
147 lldb::TargetSP target_sp = m_target_wp.lock();
148
149 if (target_sp)
150 return target_sp.get();
151
152 return NULL;
153}
154
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000155lldb::addr_t
156IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
157{
Sean Callanan08052af2013-04-17 07:50:58 +0000158 error.Clear();
159
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000160 lldb::ProcessSP process_sp;
161 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
162 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
163
164 size_t allocation_size = (size ? size : 1) + alignment - 1;
165
166 switch (policy)
167 {
168 default:
169 error.SetErrorToGenericError();
170 error.SetErrorString("Couldn't malloc: invalid allocation policy");
171 return LLDB_INVALID_ADDRESS;
172 case eAllocationPolicyHostOnly:
173 allocation_address = FindSpace(allocation_size);
174 if (allocation_address == LLDB_INVALID_ADDRESS)
175 {
176 error.SetErrorToGenericError();
177 error.SetErrorString("Couldn't malloc: address space is full");
178 return LLDB_INVALID_ADDRESS;
179 }
180 break;
181 case eAllocationPolicyMirror:
182 if (ContainsHostOnlyAllocations())
183 {
184 error.SetErrorToGenericError();
185 error.SetErrorString("Couldn't malloc: host-only allocations are polluting the address space");
186 return LLDB_INVALID_ADDRESS;
187 }
188 process_sp = m_process_wp.lock();
189 if (process_sp)
190 {
191 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
192 if (!error.Success())
193 return LLDB_INVALID_ADDRESS;
194 }
195 else
196 {
197 allocation_address = FindSpace(allocation_size);
198 if (allocation_address == LLDB_INVALID_ADDRESS)
199 {
200 error.SetErrorToGenericError();
201 error.SetErrorString("Couldn't malloc: address space is full");
202 return LLDB_INVALID_ADDRESS;
203 }
204 }
205 break;
206 case eAllocationPolicyProcessOnly:
207 if (ContainsHostOnlyAllocations())
208 {
209 error.SetErrorToGenericError();
210 error.SetErrorString("Couldn't malloc: host-only allocations are polluting the address space");
211 return LLDB_INVALID_ADDRESS;
212 }
213 process_sp = m_process_wp.lock();
214 if (process_sp)
215 {
216 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
217 if (!error.Success())
218 return LLDB_INVALID_ADDRESS;
219 }
220 else
221 {
222 error.SetErrorToGenericError();
223 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
224 return LLDB_INVALID_ADDRESS;
225 }
226 break;
227 }
228
229
230 lldb::addr_t mask = alignment - 1;
231 aligned_address = (allocation_address + mask) & (~mask);
232
Greg Claytond8506852013-04-18 22:59:51 +0000233 Allocation allocation;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000234
235 allocation.m_process_alloc = allocation_address;
236 allocation.m_process_start = aligned_address;
237 allocation.m_size = size;
238 allocation.m_permissions = permissions;
239 allocation.m_alignment = alignment;
240 allocation.m_policy = policy;
241
Greg Claytond8506852013-04-18 22:59:51 +0000242 m_allocations[aligned_address] = std::move(allocation);
243
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000244 switch (policy)
245 {
246 default:
247 assert (0 && "We cannot reach this!");
248 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000249 allocation.m_data_ap.reset(new DataBufferHeap(size, 0));
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000250 break;
251 case eAllocationPolicyProcessOnly:
252 break;
253 case eAllocationPolicyMirror:
Greg Claytone0c64e12013-04-18 22:01:06 +0000254 allocation.m_data_ap.reset(new DataBufferHeap(size, 0));
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000255 break;
256 }
257
258 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
259 {
260 const char * policy_string;
261
262 switch (policy)
263 {
264 default:
265 policy_string = "<invalid policy>";
266 break;
267 case eAllocationPolicyHostOnly:
268 policy_string = "eAllocationPolicyHostOnly";
269 break;
270 case eAllocationPolicyProcessOnly:
271 policy_string = "eAllocationPolicyProcessOnly";
272 break;
273 case eAllocationPolicyMirror:
274 policy_string = "eAllocationPolicyMirror";
275 break;
276 }
277
278 log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
279 (uint64_t)size,
280 (uint64_t)alignment,
281 (uint64_t)permissions,
282 policy_string,
283 aligned_address);
284 }
285
286 return aligned_address;
287}
288
289void
290IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
291{
Sean Callanan08052af2013-04-17 07:50:58 +0000292 error.Clear();
293
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000294 AllocationMap::iterator iter = m_allocations.find(process_address);
295
296 if (iter == m_allocations.end())
297 {
298 error.SetErrorToGenericError();
299 error.SetErrorString("Couldn't free: allocation doesn't exist");
300 return;
301 }
302
303 Allocation &allocation = iter->second;
304
305 switch (allocation.m_policy)
306 {
307 default:
308 case eAllocationPolicyHostOnly:
309 break;
310 case eAllocationPolicyMirror:
311 case eAllocationPolicyProcessOnly:
312 lldb::ProcessSP process_sp = m_process_wp.lock();
313 if (process_sp)
314 process_sp->DeallocateMemory(allocation.m_process_alloc);
315 }
316
317 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
318 {
319 log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
320 (uint64_t)process_address,
321 iter->second.m_process_start,
322 iter->second.m_process_start + iter->second.m_size);
323 }
324
325 m_allocations.erase(iter);
326}
327
328void
329IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
330{
Sean Callanan08052af2013-04-17 07:50:58 +0000331 error.Clear();
332
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000333 AllocationMap::iterator iter = FindAllocation(process_address, size);
334
335 if (iter == m_allocations.end())
336 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000337 lldb::ProcessSP process_sp = m_process_wp.lock();
338
339 if (process_sp)
340 {
341 process_sp->WriteMemory(process_address, bytes, size, error);
342 return;
343 }
344
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000345 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000346 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000347 return;
348 }
349
350 Allocation &allocation = iter->second;
351
352 uint64_t offset = process_address - allocation.m_process_start;
353
354 lldb::ProcessSP process_sp;
355
356 switch (allocation.m_policy)
357 {
358 default:
359 error.SetErrorToGenericError();
360 error.SetErrorString("Couldn't write: invalid allocation policy");
361 return;
362 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000363 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000364 {
365 error.SetErrorToGenericError();
366 error.SetErrorString("Couldn't write: data buffer is empty");
367 return;
368 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000369 ::memcpy (allocation.m_data_ap->GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000370 break;
371 case eAllocationPolicyMirror:
Greg Claytone0c64e12013-04-18 22:01:06 +0000372 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000373 {
374 error.SetErrorToGenericError();
375 error.SetErrorString("Couldn't write: data buffer is empty");
376 return;
377 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000378 ::memcpy (allocation.m_data_ap->GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000379 process_sp = m_process_wp.lock();
380 if (process_sp)
381 {
382 process_sp->WriteMemory(process_address, bytes, size, error);
383 if (!error.Success())
384 return;
385 }
386 break;
387 case eAllocationPolicyProcessOnly:
388 process_sp = m_process_wp.lock();
389 if (process_sp)
390 {
391 process_sp->WriteMemory(process_address, bytes, size, error);
392 if (!error.Success())
393 return;
394 }
395 break;
396 }
397
398 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
399 {
400 log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
401 (uint64_t)process_address,
402 (uint64_t)bytes,
403 (uint64_t)size,
404 (uint64_t)allocation.m_process_start,
405 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
406 }
407}
408
409void
Sean Callanan35005f72013-04-12 18:10:34 +0000410IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000411{
412 error.Clear();
413
Sean Callanan35005f72013-04-12 18:10:34 +0000414 if (size == UINT32_MAX)
415 size = scalar.GetByteSize();
416
417 if (size > 0)
418 {
419 uint8_t buf[32];
420 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
421 if (mem_size > 0)
422 {
423 return WriteMemory(process_address, buf, mem_size, error);
424 }
425 else
426 {
427 error.SetErrorToGenericError();
428 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
429 }
430 }
431 else
432 {
433 error.SetErrorToGenericError();
434 error.SetErrorString ("Couldn't write scalar: its size was zero");
435 }
436 return;
437}
438
439void
Sean Callananf8043fa2013-04-12 21:40:34 +0000440IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
441{
Sean Callanan08052af2013-04-17 07:50:58 +0000442 error.Clear();
443
Sean Callananf8043fa2013-04-12 21:40:34 +0000444 Scalar scalar(address);
445
446 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
447}
448
Sean Callananf8043fa2013-04-12 21:40:34 +0000449void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000450IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
451{
Sean Callanan08052af2013-04-17 07:50:58 +0000452 error.Clear();
453
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000454 AllocationMap::iterator iter = FindAllocation(process_address, size);
455
456 if (iter == m_allocations.end())
457 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000458 lldb::ProcessSP process_sp = m_process_wp.lock();
459
460 if (process_sp)
461 {
462 process_sp->ReadMemory(process_address, bytes, size, error);
463 return;
464 }
465
466 lldb::TargetSP target_sp = m_target_wp.lock();
467
468 if (target_sp)
469 {
470 Address absolute_address(process_address);
471 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
472 return;
473 }
474
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000475 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000476 error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000477 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 read: invalid allocation policy");
491 return;
492 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000493 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000494 {
495 error.SetErrorToGenericError();
496 error.SetErrorString("Couldn't read: data buffer is empty");
497 return;
498 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000499 ::memcpy (bytes, allocation.m_data_ap->GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000500 break;
501 case eAllocationPolicyMirror:
502 process_sp = m_process_wp.lock();
503 if (process_sp)
504 {
505 process_sp->ReadMemory(process_address, bytes, size, error);
506 if (!error.Success())
507 return;
508 }
509 else
510 {
Greg Claytone0c64e12013-04-18 22:01:06 +0000511 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000512 {
513 error.SetErrorToGenericError();
514 error.SetErrorString("Couldn't read: data buffer is empty");
515 return;
516 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000517 ::memcpy (bytes, allocation.m_data_ap->GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000518 }
519 break;
520 case eAllocationPolicyProcessOnly:
521 process_sp = m_process_wp.lock();
522 if (process_sp)
523 {
524 process_sp->ReadMemory(process_address, bytes, size, error);
525 if (!error.Success())
526 return;
527 }
528 break;
529 }
530
531 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
532 {
533 log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
534 (uint64_t)process_address,
535 (uint64_t)bytes,
536 (uint64_t)size,
537 (uint64_t)allocation.m_process_start,
538 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
539 }
540}
Sean Callanan35005f72013-04-12 18:10:34 +0000541
542void
543IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000544{
545 error.Clear();
546
Sean Callanan35005f72013-04-12 18:10:34 +0000547 if (size > 0)
548 {
549 DataBufferHeap buf(size, 0);
550 ReadMemory(buf.GetBytes(), process_address, size, error);
551
552 if (!error.Success())
553 return;
554
555 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
556
557 lldb::offset_t offset = 0;
558
559 switch (size)
560 {
561 default:
562 error.SetErrorToGenericError();
563 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
564 return;
565 case 1: scalar = extractor.GetU8(&offset); break;
566 case 2: scalar = extractor.GetU16(&offset); break;
567 case 4: scalar = extractor.GetU32(&offset); break;
568 case 8: scalar = extractor.GetU64(&offset); break;
569 }
570 }
571 else
572 {
573 error.SetErrorToGenericError();
Sean Callanan458ae1c2013-04-13 02:06:42 +0000574 error.SetErrorString ("Couldn't read scalar: its size was zero");
Sean Callanan35005f72013-04-12 18:10:34 +0000575 }
576 return;
577}
578
Sean Callanan458ae1c2013-04-13 02:06:42 +0000579void
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000580IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
581{
Sean Callanan08052af2013-04-17 07:50:58 +0000582 error.Clear();
583
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000584 Scalar pointer_scalar;
585 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
586
587 if (!error.Success())
588 return;
589
590 *address = pointer_scalar.ULongLong();
591
592 return;
593}
594
595void
Sean Callanan458ae1c2013-04-13 02:06:42 +0000596IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
597{
Sean Callanan08052af2013-04-17 07:50:58 +0000598 error.Clear();
599
Sean Callanan458ae1c2013-04-13 02:06:42 +0000600 if (size > 0)
601 {
602 AllocationMap::iterator iter = FindAllocation(process_address, size);
603
604 if (iter == m_allocations.end())
605 {
606 error.SetErrorToGenericError();
607 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
608 return;
609 }
610
611 Allocation &allocation = iter->second;
612
613 switch (allocation.m_policy)
614 {
615 default:
616 error.SetErrorToGenericError();
617 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
618 return;
619 case eAllocationPolicyProcessOnly:
620 error.SetErrorToGenericError();
621 error.SetErrorString("Couldn't get memory data: memory is only in the target");
622 return;
Sean Callanan458ae1c2013-04-13 02:06:42 +0000623 case eAllocationPolicyMirror:
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000624 {
625 lldb::ProcessSP process_sp = m_process_wp.lock();
626
Greg Claytone0c64e12013-04-18 22:01:06 +0000627 if (!allocation.m_data_ap.get())
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000628 {
629 error.SetErrorToGenericError();
630 error.SetErrorString("Couldn't get memory data: data buffer is empty");
631 return;
632 }
633 if (process_sp)
634 {
Greg Claytone0c64e12013-04-18 22:01:06 +0000635 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data_ap->GetBytes(), allocation.m_data_ap->GetByteSize(), error);
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000636 if (!error.Success())
637 return;
638 uint64_t offset = process_address - allocation.m_process_start;
Greg Claytone0c64e12013-04-18 22:01:06 +0000639 extractor = DataExtractor(allocation.m_data_ap->GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000640 return;
641 }
642 }
643 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000644 if (!allocation.m_data_ap.get())
Sean Callanan458ae1c2013-04-13 02:06:42 +0000645 {
646 error.SetErrorToGenericError();
647 error.SetErrorString("Couldn't get memory data: data buffer is empty");
648 return;
649 }
650 uint64_t offset = process_address - allocation.m_process_start;
Greg Claytone0c64e12013-04-18 22:01:06 +0000651 extractor = DataExtractor(allocation.m_data_ap->GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callanan458ae1c2013-04-13 02:06:42 +0000652 return;
653 }
654 }
655 else
656 {
657 error.SetErrorToGenericError();
658 error.SetErrorString ("Couldn't get memory data: its size was zero");
659 return;
660 }
661}
662
663