blob: db5b96fb993a902f9e5d5753cdd33ef98cad938f [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{
Sean Callananbb9945f2013-04-19 01:51:24 +000053 lldb::TargetSP target_sp = m_target_wp.lock();
54 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callanan5a1af4e2013-04-05 02:22:57 +000055
Sean Callananbb9945f2013-04-19 01:51:24 +000056 lldb::addr_t ret = LLDB_INVALID_ADDRESS;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000057
Sean Callananbb9945f2013-04-19 01:51:24 +000058 for (int iterations = 0; iterations < 16; ++iterations)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000059 {
Sean Callananbb9945f2013-04-19 01:51:24 +000060 lldb::addr_t candidate;
61
62 switch (target_sp->GetArchitecture().GetAddressByteSize())
63 {
64 case 4:
65 {
66 uint32_t random_data = random();
67 candidate = random_data;
68 candidate &= ~0xfffull;
69 break;
70 }
71 case 8:
72 {
73 uint32_t random_low = random();
74 uint32_t random_high = random();
75 candidate = random_high;
76 candidate <<= 32ull;
77 candidate |= random_low;
78 candidate &= ~0xfffull;
79 break;
80 }
81 }
82
83 if (IntersectsAllocation(candidate, size))
84 continue;
85
86 char buf[1];
87
88 Error err;
89
90 if (process_sp &&
91 (process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
92 process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
93 continue;
94
95 ret = candidate;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000096 }
97
Sean Callananbb9945f2013-04-19 01:51:24 +000098 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000099}
100
101IRMemoryMap::AllocationMap::iterator
102IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
103{
Sean Callanan1582ee62013-04-18 22:06:33 +0000104 if (addr == LLDB_INVALID_ADDRESS)
105 return m_allocations.end();
106
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000107 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
108
Sean Callanan14b1bae2013-04-16 23:25:35 +0000109 if (iter == m_allocations.end() ||
110 iter->first > addr)
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000111 {
112 if (iter == m_allocations.begin())
113 return m_allocations.end();
114 iter--;
115 }
116
117 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
118 return iter;
119
120 return m_allocations.end();
121}
122
Sean Callananbb9945f2013-04-19 01:51:24 +0000123bool
124IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
125{
126 if (addr == LLDB_INVALID_ADDRESS)
127 return false;
128
129 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
130
131 if (iter == m_allocations.end() ||
132 iter->first > addr)
133 {
134 if (iter == m_allocations.begin())
135 return false;
136
137 iter--;
138 }
139
140 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
141 {
142 if (iter->second.m_process_start + iter->second.m_size > addr)
143 return true;
144
145 ++iter;
146 }
147
148 return false;
149}
150
Sean Callanan35005f72013-04-12 18:10:34 +0000151lldb::ByteOrder
152IRMemoryMap::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)
Sean Callanan08052af2013-04-17 07:50:58 +0000162 return target_sp->GetArchitecture().GetByteOrder();
Sean Callanan35005f72013-04-12 18:10:34 +0000163
164 return lldb::eByteOrderInvalid;
165}
166
167uint32_t
168IRMemoryMap::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)
Sean Callanan08052af2013-04-17 07:50:58 +0000178 return target_sp->GetArchitecture().GetAddressByteSize();
Sean Callanan35005f72013-04-12 18:10:34 +0000179
180 return UINT32_MAX;
181}
182
183ExecutionContextScope *
184IRMemoryMap::GetBestExecutionContextScope()
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
Sean Callanand2562502013-04-19 17:44:40 +0000199IRMemoryMap::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{
206 m_process_alloc = process_alloc;
207 m_process_start = process_start;
208 m_size = size;
209 m_permissions = permissions;
210 m_alignment = alignment;
211 m_policy = policy;
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
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000230lldb::addr_t
231IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
232{
Sean Callanan08052af2013-04-17 07:50:58 +0000233 error.Clear();
234
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000235 lldb::ProcessSP process_sp;
236 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
237 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
238
239 size_t allocation_size = (size ? size : 1) + alignment - 1;
240
241 switch (policy)
242 {
243 default:
244 error.SetErrorToGenericError();
245 error.SetErrorString("Couldn't malloc: invalid allocation policy");
246 return LLDB_INVALID_ADDRESS;
247 case eAllocationPolicyHostOnly:
248 allocation_address = FindSpace(allocation_size);
249 if (allocation_address == LLDB_INVALID_ADDRESS)
250 {
251 error.SetErrorToGenericError();
252 error.SetErrorString("Couldn't malloc: address space is full");
253 return LLDB_INVALID_ADDRESS;
254 }
255 break;
256 case eAllocationPolicyMirror:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000257 process_sp = m_process_wp.lock();
Sean Callananbb9945f2013-04-19 01:51:24 +0000258 if (process_sp && process_sp->CanJIT())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000259 {
260 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
261 if (!error.Success())
262 return LLDB_INVALID_ADDRESS;
263 }
264 else
265 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000266 policy = eAllocationPolicyHostOnly;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000267 allocation_address = FindSpace(allocation_size);
268 if (allocation_address == LLDB_INVALID_ADDRESS)
269 {
270 error.SetErrorToGenericError();
271 error.SetErrorString("Couldn't malloc: address space is full");
272 return LLDB_INVALID_ADDRESS;
273 }
274 }
275 break;
276 case eAllocationPolicyProcessOnly:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000277 process_sp = m_process_wp.lock();
278 if (process_sp)
279 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000280 if (process_sp->CanJIT())
281 {
282 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
283 if (!error.Success())
284 return LLDB_INVALID_ADDRESS;
285 }
286 else
287 {
288 error.SetErrorToGenericError();
289 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000290 return LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +0000291 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000292 }
293 else
294 {
295 error.SetErrorToGenericError();
296 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
297 return LLDB_INVALID_ADDRESS;
298 }
299 break;
300 }
301
302
303 lldb::addr_t mask = alignment - 1;
304 aligned_address = (allocation_address + mask) & (~mask);
305
Sean Callanand2562502013-04-19 17:44:40 +0000306 m_allocations[aligned_address] = Allocation(allocation_address,
307 aligned_address,
308 size,
309 permissions,
310 alignment,
311 policy);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000312
313 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
314 {
315 const char * policy_string;
316
317 switch (policy)
318 {
319 default:
320 policy_string = "<invalid policy>";
321 break;
322 case eAllocationPolicyHostOnly:
323 policy_string = "eAllocationPolicyHostOnly";
324 break;
325 case eAllocationPolicyProcessOnly:
326 policy_string = "eAllocationPolicyProcessOnly";
327 break;
328 case eAllocationPolicyMirror:
329 policy_string = "eAllocationPolicyMirror";
330 break;
331 }
332
333 log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
334 (uint64_t)size,
335 (uint64_t)alignment,
336 (uint64_t)permissions,
337 policy_string,
338 aligned_address);
339 }
340
341 return aligned_address;
342}
343
344void
345IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
346{
Sean Callanan08052af2013-04-17 07:50:58 +0000347 error.Clear();
348
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000349 AllocationMap::iterator iter = m_allocations.find(process_address);
350
351 if (iter == m_allocations.end())
352 {
353 error.SetErrorToGenericError();
354 error.SetErrorString("Couldn't free: allocation doesn't exist");
355 return;
356 }
357
358 Allocation &allocation = iter->second;
359
360 switch (allocation.m_policy)
361 {
362 default:
363 case eAllocationPolicyHostOnly:
364 break;
365 case eAllocationPolicyMirror:
366 case eAllocationPolicyProcessOnly:
367 lldb::ProcessSP process_sp = m_process_wp.lock();
368 if (process_sp)
369 process_sp->DeallocateMemory(allocation.m_process_alloc);
370 }
371
372 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
373 {
374 log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
375 (uint64_t)process_address,
376 iter->second.m_process_start,
377 iter->second.m_process_start + iter->second.m_size);
378 }
379
380 m_allocations.erase(iter);
381}
382
383void
384IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
385{
Sean Callanan08052af2013-04-17 07:50:58 +0000386 error.Clear();
387
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000388 AllocationMap::iterator iter = FindAllocation(process_address, size);
389
390 if (iter == m_allocations.end())
391 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000392 lldb::ProcessSP process_sp = m_process_wp.lock();
393
394 if (process_sp)
395 {
396 process_sp->WriteMemory(process_address, bytes, size, error);
397 return;
398 }
399
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000400 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000401 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000402 return;
403 }
404
405 Allocation &allocation = iter->second;
406
407 uint64_t offset = process_address - allocation.m_process_start;
408
409 lldb::ProcessSP process_sp;
410
411 switch (allocation.m_policy)
412 {
413 default:
414 error.SetErrorToGenericError();
415 error.SetErrorString("Couldn't write: invalid allocation policy");
416 return;
417 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000418 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000419 {
420 error.SetErrorToGenericError();
421 error.SetErrorString("Couldn't write: data buffer is empty");
422 return;
423 }
Sean Callanand2562502013-04-19 17:44:40 +0000424 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000425 break;
426 case eAllocationPolicyMirror:
Sean Callanand2562502013-04-19 17:44:40 +0000427 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000428 {
429 error.SetErrorToGenericError();
430 error.SetErrorString("Couldn't write: data buffer is empty");
431 return;
432 }
Sean Callanand2562502013-04-19 17:44:40 +0000433 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000434 process_sp = m_process_wp.lock();
435 if (process_sp)
436 {
437 process_sp->WriteMemory(process_address, bytes, size, error);
438 if (!error.Success())
439 return;
440 }
441 break;
442 case eAllocationPolicyProcessOnly:
443 process_sp = m_process_wp.lock();
444 if (process_sp)
445 {
446 process_sp->WriteMemory(process_address, bytes, size, error);
447 if (!error.Success())
448 return;
449 }
450 break;
451 }
452
453 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
454 {
455 log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
456 (uint64_t)process_address,
457 (uint64_t)bytes,
458 (uint64_t)size,
459 (uint64_t)allocation.m_process_start,
460 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
461 }
462}
463
464void
Sean Callanan35005f72013-04-12 18:10:34 +0000465IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000466{
467 error.Clear();
468
Sean Callanan35005f72013-04-12 18:10:34 +0000469 if (size == UINT32_MAX)
470 size = scalar.GetByteSize();
471
472 if (size > 0)
473 {
474 uint8_t buf[32];
475 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
476 if (mem_size > 0)
477 {
478 return WriteMemory(process_address, buf, mem_size, error);
479 }
480 else
481 {
482 error.SetErrorToGenericError();
483 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
484 }
485 }
486 else
487 {
488 error.SetErrorToGenericError();
489 error.SetErrorString ("Couldn't write scalar: its size was zero");
490 }
491 return;
492}
493
494void
Sean Callananf8043fa2013-04-12 21:40:34 +0000495IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
496{
Sean Callanan08052af2013-04-17 07:50:58 +0000497 error.Clear();
498
Sean Callananf8043fa2013-04-12 21:40:34 +0000499 Scalar scalar(address);
500
501 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
502}
503
Sean Callananf8043fa2013-04-12 21:40:34 +0000504void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000505IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
506{
Sean Callanan08052af2013-04-17 07:50:58 +0000507 error.Clear();
508
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000509 AllocationMap::iterator iter = FindAllocation(process_address, size);
510
511 if (iter == m_allocations.end())
512 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000513 lldb::ProcessSP process_sp = m_process_wp.lock();
514
515 if (process_sp)
516 {
517 process_sp->ReadMemory(process_address, bytes, size, error);
518 return;
519 }
520
521 lldb::TargetSP target_sp = m_target_wp.lock();
522
523 if (target_sp)
524 {
525 Address absolute_address(process_address);
526 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
527 return;
528 }
529
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000530 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000531 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 +0000532 return;
533 }
534
535 Allocation &allocation = iter->second;
536
537 uint64_t offset = process_address - allocation.m_process_start;
538
539 lldb::ProcessSP process_sp;
540
541 switch (allocation.m_policy)
542 {
543 default:
544 error.SetErrorToGenericError();
545 error.SetErrorString("Couldn't read: invalid allocation policy");
546 return;
547 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000548 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000549 {
550 error.SetErrorToGenericError();
551 error.SetErrorString("Couldn't read: data buffer is empty");
552 return;
553 }
Sean Callanand2562502013-04-19 17:44:40 +0000554 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000555 break;
556 case eAllocationPolicyMirror:
557 process_sp = m_process_wp.lock();
558 if (process_sp)
559 {
560 process_sp->ReadMemory(process_address, bytes, size, error);
561 if (!error.Success())
562 return;
563 }
564 else
565 {
Sean Callanand2562502013-04-19 17:44:40 +0000566 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000567 {
568 error.SetErrorToGenericError();
569 error.SetErrorString("Couldn't read: data buffer is empty");
570 return;
571 }
Sean Callanand2562502013-04-19 17:44:40 +0000572 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000573 }
574 break;
575 case eAllocationPolicyProcessOnly:
576 process_sp = m_process_wp.lock();
577 if (process_sp)
578 {
579 process_sp->ReadMemory(process_address, bytes, size, error);
580 if (!error.Success())
581 return;
582 }
583 break;
584 }
585
586 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
587 {
588 log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
589 (uint64_t)process_address,
590 (uint64_t)bytes,
591 (uint64_t)size,
592 (uint64_t)allocation.m_process_start,
593 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
594 }
595}
Sean Callanan35005f72013-04-12 18:10:34 +0000596
597void
598IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000599{
600 error.Clear();
601
Sean Callanan35005f72013-04-12 18:10:34 +0000602 if (size > 0)
603 {
604 DataBufferHeap buf(size, 0);
605 ReadMemory(buf.GetBytes(), process_address, size, error);
606
607 if (!error.Success())
608 return;
609
610 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
611
612 lldb::offset_t offset = 0;
613
614 switch (size)
615 {
616 default:
617 error.SetErrorToGenericError();
618 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
619 return;
620 case 1: scalar = extractor.GetU8(&offset); break;
621 case 2: scalar = extractor.GetU16(&offset); break;
622 case 4: scalar = extractor.GetU32(&offset); break;
623 case 8: scalar = extractor.GetU64(&offset); break;
624 }
625 }
626 else
627 {
628 error.SetErrorToGenericError();
Sean Callanan458ae1c2013-04-13 02:06:42 +0000629 error.SetErrorString ("Couldn't read scalar: its size was zero");
Sean Callanan35005f72013-04-12 18:10:34 +0000630 }
631 return;
632}
633
Sean Callanan458ae1c2013-04-13 02:06:42 +0000634void
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000635IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
636{
Sean Callanan08052af2013-04-17 07:50:58 +0000637 error.Clear();
638
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000639 Scalar pointer_scalar;
640 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
641
642 if (!error.Success())
643 return;
644
645 *address = pointer_scalar.ULongLong();
646
647 return;
648}
649
650void
Sean Callanan458ae1c2013-04-13 02:06:42 +0000651IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
652{
Sean Callanan08052af2013-04-17 07:50:58 +0000653 error.Clear();
654
Sean Callanan458ae1c2013-04-13 02:06:42 +0000655 if (size > 0)
656 {
657 AllocationMap::iterator iter = FindAllocation(process_address, size);
658
659 if (iter == m_allocations.end())
660 {
661 error.SetErrorToGenericError();
662 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
663 return;
664 }
665
666 Allocation &allocation = iter->second;
667
668 switch (allocation.m_policy)
669 {
670 default:
671 error.SetErrorToGenericError();
672 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
673 return;
674 case eAllocationPolicyProcessOnly:
675 error.SetErrorToGenericError();
676 error.SetErrorString("Couldn't get memory data: memory is only in the target");
677 return;
Sean Callanan458ae1c2013-04-13 02:06:42 +0000678 case eAllocationPolicyMirror:
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000679 {
680 lldb::ProcessSP process_sp = m_process_wp.lock();
681
Sean Callanand2562502013-04-19 17:44:40 +0000682 if (!allocation.m_data.GetByteSize())
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000683 {
684 error.SetErrorToGenericError();
685 error.SetErrorString("Couldn't get memory data: data buffer is empty");
686 return;
687 }
688 if (process_sp)
689 {
Sean Callanand2562502013-04-19 17:44:40 +0000690 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000691 if (!error.Success())
692 return;
693 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000694 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000695 return;
696 }
697 }
698 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000699 if (!allocation.m_data.GetByteSize())
Sean Callanan458ae1c2013-04-13 02:06:42 +0000700 {
701 error.SetErrorToGenericError();
702 error.SetErrorString("Couldn't get memory data: data buffer is empty");
703 return;
704 }
705 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000706 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callanan458ae1c2013-04-13 02:06:42 +0000707 return;
708 }
709 }
710 else
711 {
712 error.SetErrorToGenericError();
713 error.SetErrorString ("Couldn't get memory data: its size was zero");
714 return;
715 }
716}
717
718