blob: 9a6f4479a54825058376ed143a675b59fc648a83 [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 Callanan5a1af4e2013-04-05 02:22:57 +0000199lldb::addr_t
200IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
201{
Sean Callanan08052af2013-04-17 07:50:58 +0000202 error.Clear();
203
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000204 lldb::ProcessSP process_sp;
205 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
206 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
207
208 size_t allocation_size = (size ? size : 1) + alignment - 1;
209
210 switch (policy)
211 {
212 default:
213 error.SetErrorToGenericError();
214 error.SetErrorString("Couldn't malloc: invalid allocation policy");
215 return LLDB_INVALID_ADDRESS;
216 case eAllocationPolicyHostOnly:
217 allocation_address = FindSpace(allocation_size);
218 if (allocation_address == LLDB_INVALID_ADDRESS)
219 {
220 error.SetErrorToGenericError();
221 error.SetErrorString("Couldn't malloc: address space is full");
222 return LLDB_INVALID_ADDRESS;
223 }
224 break;
225 case eAllocationPolicyMirror:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000226 process_sp = m_process_wp.lock();
Sean Callananbb9945f2013-04-19 01:51:24 +0000227 if (process_sp && process_sp->CanJIT())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000228 {
229 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
230 if (!error.Success())
231 return LLDB_INVALID_ADDRESS;
232 }
233 else
234 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000235 policy = eAllocationPolicyHostOnly;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000236 allocation_address = FindSpace(allocation_size);
237 if (allocation_address == LLDB_INVALID_ADDRESS)
238 {
239 error.SetErrorToGenericError();
240 error.SetErrorString("Couldn't malloc: address space is full");
241 return LLDB_INVALID_ADDRESS;
242 }
243 }
244 break;
245 case eAllocationPolicyProcessOnly:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000246 process_sp = m_process_wp.lock();
247 if (process_sp)
248 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000249 if (process_sp->CanJIT())
250 {
251 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
252 if (!error.Success())
253 return LLDB_INVALID_ADDRESS;
254 }
255 else
256 {
257 error.SetErrorToGenericError();
258 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000259 return LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +0000260 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000261 }
262 else
263 {
264 error.SetErrorToGenericError();
265 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
266 return LLDB_INVALID_ADDRESS;
267 }
268 break;
269 }
270
271
272 lldb::addr_t mask = alignment - 1;
273 aligned_address = (allocation_address + mask) & (~mask);
274
Greg Claytond8506852013-04-18 22:59:51 +0000275 Allocation allocation;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000276
277 allocation.m_process_alloc = allocation_address;
278 allocation.m_process_start = aligned_address;
279 allocation.m_size = size;
280 allocation.m_permissions = permissions;
281 allocation.m_alignment = alignment;
282 allocation.m_policy = policy;
283
Greg Claytond8506852013-04-18 22:59:51 +0000284 m_allocations[aligned_address] = std::move(allocation);
285
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000286 switch (policy)
287 {
288 default:
289 assert (0 && "We cannot reach this!");
290 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000291 allocation.m_data_ap.reset(new DataBufferHeap(size, 0));
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000292 break;
293 case eAllocationPolicyProcessOnly:
294 break;
295 case eAllocationPolicyMirror:
Greg Claytone0c64e12013-04-18 22:01:06 +0000296 allocation.m_data_ap.reset(new DataBufferHeap(size, 0));
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000297 break;
298 }
299
300 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
301 {
302 const char * policy_string;
303
304 switch (policy)
305 {
306 default:
307 policy_string = "<invalid policy>";
308 break;
309 case eAllocationPolicyHostOnly:
310 policy_string = "eAllocationPolicyHostOnly";
311 break;
312 case eAllocationPolicyProcessOnly:
313 policy_string = "eAllocationPolicyProcessOnly";
314 break;
315 case eAllocationPolicyMirror:
316 policy_string = "eAllocationPolicyMirror";
317 break;
318 }
319
320 log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
321 (uint64_t)size,
322 (uint64_t)alignment,
323 (uint64_t)permissions,
324 policy_string,
325 aligned_address);
326 }
327
328 return aligned_address;
329}
330
331void
332IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
333{
Sean Callanan08052af2013-04-17 07:50:58 +0000334 error.Clear();
335
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000336 AllocationMap::iterator iter = m_allocations.find(process_address);
337
338 if (iter == m_allocations.end())
339 {
340 error.SetErrorToGenericError();
341 error.SetErrorString("Couldn't free: allocation doesn't exist");
342 return;
343 }
344
345 Allocation &allocation = iter->second;
346
347 switch (allocation.m_policy)
348 {
349 default:
350 case eAllocationPolicyHostOnly:
351 break;
352 case eAllocationPolicyMirror:
353 case eAllocationPolicyProcessOnly:
354 lldb::ProcessSP process_sp = m_process_wp.lock();
355 if (process_sp)
356 process_sp->DeallocateMemory(allocation.m_process_alloc);
357 }
358
359 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
360 {
361 log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
362 (uint64_t)process_address,
363 iter->second.m_process_start,
364 iter->second.m_process_start + iter->second.m_size);
365 }
366
367 m_allocations.erase(iter);
368}
369
370void
371IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
372{
Sean Callanan08052af2013-04-17 07:50:58 +0000373 error.Clear();
374
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000375 AllocationMap::iterator iter = FindAllocation(process_address, size);
376
377 if (iter == m_allocations.end())
378 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000379 lldb::ProcessSP process_sp = m_process_wp.lock();
380
381 if (process_sp)
382 {
383 process_sp->WriteMemory(process_address, bytes, size, error);
384 return;
385 }
386
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000387 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000388 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000389 return;
390 }
391
392 Allocation &allocation = iter->second;
393
394 uint64_t offset = process_address - allocation.m_process_start;
395
396 lldb::ProcessSP process_sp;
397
398 switch (allocation.m_policy)
399 {
400 default:
401 error.SetErrorToGenericError();
402 error.SetErrorString("Couldn't write: invalid allocation policy");
403 return;
404 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000405 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000406 {
407 error.SetErrorToGenericError();
408 error.SetErrorString("Couldn't write: data buffer is empty");
409 return;
410 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000411 ::memcpy (allocation.m_data_ap->GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000412 break;
413 case eAllocationPolicyMirror:
Greg Claytone0c64e12013-04-18 22:01:06 +0000414 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000415 {
416 error.SetErrorToGenericError();
417 error.SetErrorString("Couldn't write: data buffer is empty");
418 return;
419 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000420 ::memcpy (allocation.m_data_ap->GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000421 process_sp = m_process_wp.lock();
422 if (process_sp)
423 {
424 process_sp->WriteMemory(process_address, bytes, size, error);
425 if (!error.Success())
426 return;
427 }
428 break;
429 case eAllocationPolicyProcessOnly:
430 process_sp = m_process_wp.lock();
431 if (process_sp)
432 {
433 process_sp->WriteMemory(process_address, bytes, size, error);
434 if (!error.Success())
435 return;
436 }
437 break;
438 }
439
440 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
441 {
442 log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
443 (uint64_t)process_address,
444 (uint64_t)bytes,
445 (uint64_t)size,
446 (uint64_t)allocation.m_process_start,
447 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
448 }
449}
450
451void
Sean Callanan35005f72013-04-12 18:10:34 +0000452IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000453{
454 error.Clear();
455
Sean Callanan35005f72013-04-12 18:10:34 +0000456 if (size == UINT32_MAX)
457 size = scalar.GetByteSize();
458
459 if (size > 0)
460 {
461 uint8_t buf[32];
462 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
463 if (mem_size > 0)
464 {
465 return WriteMemory(process_address, buf, mem_size, error);
466 }
467 else
468 {
469 error.SetErrorToGenericError();
470 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
471 }
472 }
473 else
474 {
475 error.SetErrorToGenericError();
476 error.SetErrorString ("Couldn't write scalar: its size was zero");
477 }
478 return;
479}
480
481void
Sean Callananf8043fa2013-04-12 21:40:34 +0000482IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
483{
Sean Callanan08052af2013-04-17 07:50:58 +0000484 error.Clear();
485
Sean Callananf8043fa2013-04-12 21:40:34 +0000486 Scalar scalar(address);
487
488 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
489}
490
Sean Callananf8043fa2013-04-12 21:40:34 +0000491void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000492IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
493{
Sean Callanan08052af2013-04-17 07:50:58 +0000494 error.Clear();
495
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000496 AllocationMap::iterator iter = FindAllocation(process_address, size);
497
498 if (iter == m_allocations.end())
499 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000500 lldb::ProcessSP process_sp = m_process_wp.lock();
501
502 if (process_sp)
503 {
504 process_sp->ReadMemory(process_address, bytes, size, error);
505 return;
506 }
507
508 lldb::TargetSP target_sp = m_target_wp.lock();
509
510 if (target_sp)
511 {
512 Address absolute_address(process_address);
513 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
514 return;
515 }
516
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000517 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000518 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 +0000519 return;
520 }
521
522 Allocation &allocation = iter->second;
523
524 uint64_t offset = process_address - allocation.m_process_start;
525
526 lldb::ProcessSP process_sp;
527
528 switch (allocation.m_policy)
529 {
530 default:
531 error.SetErrorToGenericError();
532 error.SetErrorString("Couldn't read: invalid allocation policy");
533 return;
534 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000535 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000536 {
537 error.SetErrorToGenericError();
538 error.SetErrorString("Couldn't read: data buffer is empty");
539 return;
540 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000541 ::memcpy (bytes, allocation.m_data_ap->GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000542 break;
543 case eAllocationPolicyMirror:
544 process_sp = m_process_wp.lock();
545 if (process_sp)
546 {
547 process_sp->ReadMemory(process_address, bytes, size, error);
548 if (!error.Success())
549 return;
550 }
551 else
552 {
Greg Claytone0c64e12013-04-18 22:01:06 +0000553 if (!allocation.m_data_ap.get())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000554 {
555 error.SetErrorToGenericError();
556 error.SetErrorString("Couldn't read: data buffer is empty");
557 return;
558 }
Greg Claytone0c64e12013-04-18 22:01:06 +0000559 ::memcpy (bytes, allocation.m_data_ap->GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000560 }
561 break;
562 case eAllocationPolicyProcessOnly:
563 process_sp = m_process_wp.lock();
564 if (process_sp)
565 {
566 process_sp->ReadMemory(process_address, bytes, size, error);
567 if (!error.Success())
568 return;
569 }
570 break;
571 }
572
573 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
574 {
575 log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
576 (uint64_t)process_address,
577 (uint64_t)bytes,
578 (uint64_t)size,
579 (uint64_t)allocation.m_process_start,
580 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
581 }
582}
Sean Callanan35005f72013-04-12 18:10:34 +0000583
584void
585IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000586{
587 error.Clear();
588
Sean Callanan35005f72013-04-12 18:10:34 +0000589 if (size > 0)
590 {
591 DataBufferHeap buf(size, 0);
592 ReadMemory(buf.GetBytes(), process_address, size, error);
593
594 if (!error.Success())
595 return;
596
597 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
598
599 lldb::offset_t offset = 0;
600
601 switch (size)
602 {
603 default:
604 error.SetErrorToGenericError();
605 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
606 return;
607 case 1: scalar = extractor.GetU8(&offset); break;
608 case 2: scalar = extractor.GetU16(&offset); break;
609 case 4: scalar = extractor.GetU32(&offset); break;
610 case 8: scalar = extractor.GetU64(&offset); break;
611 }
612 }
613 else
614 {
615 error.SetErrorToGenericError();
Sean Callanan458ae1c2013-04-13 02:06:42 +0000616 error.SetErrorString ("Couldn't read scalar: its size was zero");
Sean Callanan35005f72013-04-12 18:10:34 +0000617 }
618 return;
619}
620
Sean Callanan458ae1c2013-04-13 02:06:42 +0000621void
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000622IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
623{
Sean Callanan08052af2013-04-17 07:50:58 +0000624 error.Clear();
625
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000626 Scalar pointer_scalar;
627 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
628
629 if (!error.Success())
630 return;
631
632 *address = pointer_scalar.ULongLong();
633
634 return;
635}
636
637void
Sean Callanan458ae1c2013-04-13 02:06:42 +0000638IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
639{
Sean Callanan08052af2013-04-17 07:50:58 +0000640 error.Clear();
641
Sean Callanan458ae1c2013-04-13 02:06:42 +0000642 if (size > 0)
643 {
644 AllocationMap::iterator iter = FindAllocation(process_address, size);
645
646 if (iter == m_allocations.end())
647 {
648 error.SetErrorToGenericError();
649 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
650 return;
651 }
652
653 Allocation &allocation = iter->second;
654
655 switch (allocation.m_policy)
656 {
657 default:
658 error.SetErrorToGenericError();
659 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
660 return;
661 case eAllocationPolicyProcessOnly:
662 error.SetErrorToGenericError();
663 error.SetErrorString("Couldn't get memory data: memory is only in the target");
664 return;
Sean Callanan458ae1c2013-04-13 02:06:42 +0000665 case eAllocationPolicyMirror:
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000666 {
667 lldb::ProcessSP process_sp = m_process_wp.lock();
668
Greg Claytone0c64e12013-04-18 22:01:06 +0000669 if (!allocation.m_data_ap.get())
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000670 {
671 error.SetErrorToGenericError();
672 error.SetErrorString("Couldn't get memory data: data buffer is empty");
673 return;
674 }
675 if (process_sp)
676 {
Greg Claytone0c64e12013-04-18 22:01:06 +0000677 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 +0000678 if (!error.Success())
679 return;
680 uint64_t offset = process_address - allocation.m_process_start;
Greg Claytone0c64e12013-04-18 22:01:06 +0000681 extractor = DataExtractor(allocation.m_data_ap->GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000682 return;
683 }
684 }
685 case eAllocationPolicyHostOnly:
Greg Claytone0c64e12013-04-18 22:01:06 +0000686 if (!allocation.m_data_ap.get())
Sean Callanan458ae1c2013-04-13 02:06:42 +0000687 {
688 error.SetErrorToGenericError();
689 error.SetErrorString("Couldn't get memory data: data buffer is empty");
690 return;
691 }
692 uint64_t offset = process_address - allocation.m_process_start;
Greg Claytone0c64e12013-04-18 22:01:06 +0000693 extractor = DataExtractor(allocation.m_data_ap->GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callanan458ae1c2013-04-13 02:06:42 +0000694 return;
695 }
696 }
697 else
698 {
699 error.SetErrorToGenericError();
700 error.SetErrorString ("Couldn't get memory data: its size was zero");
701 return;
702 }
703}
704
705