blob: 28c3e5df3bfaa77993edb7c179746708685f74e5 [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 ||
Sean Callanandf565402013-04-27 02:19:33 +000037 allocation.second.m_policy == eAllocationPolicyProcessOnly ||
38 (allocation.second.m_policy == eAllocationPolicyHostOnly && process_sp->CanJIT()))
Sean Callanan5a1af4e2013-04-05 02:22:57 +000039 process_sp->DeallocateMemory(allocation.second.m_process_alloc);
40
41 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
42 {
43 log->Printf("IRMemoryMap::~IRMemoryMap deallocated [0x%llx..0x%llx)",
44 (uint64_t)allocation.second.m_process_start,
45 (uint64_t)allocation.second.m_process_start + (uint64_t)allocation.second.m_size);
46 }
47 }
48 }
49}
50
51lldb::addr_t
52IRMemoryMap::FindSpace (size_t size)
53{
Sean Callananbb9945f2013-04-19 01:51:24 +000054 lldb::TargetSP target_sp = m_target_wp.lock();
55 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callanan5a1af4e2013-04-05 02:22:57 +000056
Sean Callananbb9945f2013-04-19 01:51:24 +000057 lldb::addr_t ret = LLDB_INVALID_ADDRESS;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000058
Sean Callanandf565402013-04-27 02:19:33 +000059 if (process_sp && process_sp->CanJIT())
60 {
61 Error alloc_error;
62
63 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
64
65 if (!alloc_error.Success())
66 return LLDB_INVALID_ADDRESS;
67 else
68 return ret;
69 }
70
Sean Callananbb9945f2013-04-19 01:51:24 +000071 for (int iterations = 0; iterations < 16; ++iterations)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000072 {
Sean Callananbb9945f2013-04-19 01:51:24 +000073 lldb::addr_t candidate;
74
75 switch (target_sp->GetArchitecture().GetAddressByteSize())
76 {
77 case 4:
78 {
79 uint32_t random_data = random();
80 candidate = random_data;
81 candidate &= ~0xfffull;
82 break;
83 }
84 case 8:
85 {
86 uint32_t random_low = random();
87 uint32_t random_high = random();
88 candidate = random_high;
89 candidate <<= 32ull;
90 candidate |= random_low;
91 candidate &= ~0xfffull;
92 break;
93 }
94 }
95
96 if (IntersectsAllocation(candidate, size))
97 continue;
98
99 char buf[1];
100
101 Error err;
102
103 if (process_sp &&
104 (process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
105 process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
106 continue;
107
108 ret = candidate;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000109 }
110
Sean Callananbb9945f2013-04-19 01:51:24 +0000111 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000112}
113
114IRMemoryMap::AllocationMap::iterator
115IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
116{
Sean Callanan1582ee62013-04-18 22:06:33 +0000117 if (addr == LLDB_INVALID_ADDRESS)
118 return m_allocations.end();
119
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000120 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
121
Sean Callanan14b1bae2013-04-16 23:25:35 +0000122 if (iter == m_allocations.end() ||
123 iter->first > addr)
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000124 {
125 if (iter == m_allocations.begin())
126 return m_allocations.end();
127 iter--;
128 }
129
130 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
131 return iter;
132
133 return m_allocations.end();
134}
135
Sean Callananbb9945f2013-04-19 01:51:24 +0000136bool
137IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
138{
139 if (addr == LLDB_INVALID_ADDRESS)
140 return false;
141
142 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
143
144 if (iter == m_allocations.end() ||
145 iter->first > addr)
146 {
147 if (iter == m_allocations.begin())
148 return false;
149
150 iter--;
151 }
152
153 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
154 {
155 if (iter->second.m_process_start + iter->second.m_size > addr)
156 return true;
157
158 ++iter;
159 }
160
161 return false;
162}
163
Sean Callanan35005f72013-04-12 18:10:34 +0000164lldb::ByteOrder
165IRMemoryMap::GetByteOrder()
166{
167 lldb::ProcessSP process_sp = m_process_wp.lock();
168
169 if (process_sp)
170 return process_sp->GetByteOrder();
171
172 lldb::TargetSP target_sp = m_target_wp.lock();
173
174 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000175 return target_sp->GetArchitecture().GetByteOrder();
Sean Callanan35005f72013-04-12 18:10:34 +0000176
177 return lldb::eByteOrderInvalid;
178}
179
180uint32_t
181IRMemoryMap::GetAddressByteSize()
182{
183 lldb::ProcessSP process_sp = m_process_wp.lock();
184
185 if (process_sp)
186 return process_sp->GetAddressByteSize();
187
188 lldb::TargetSP target_sp = m_target_wp.lock();
189
190 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000191 return target_sp->GetArchitecture().GetAddressByteSize();
Sean Callanan35005f72013-04-12 18:10:34 +0000192
193 return UINT32_MAX;
194}
195
196ExecutionContextScope *
197IRMemoryMap::GetBestExecutionContextScope()
198{
199 lldb::ProcessSP process_sp = m_process_wp.lock();
200
201 if (process_sp)
202 return process_sp.get();
203
204 lldb::TargetSP target_sp = m_target_wp.lock();
205
206 if (target_sp)
207 return target_sp.get();
208
209 return NULL;
210}
211
Sean Callanand2562502013-04-19 17:44:40 +0000212IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
213 lldb::addr_t process_start,
214 size_t size,
215 uint32_t permissions,
216 uint8_t alignment,
217 AllocationPolicy policy)
218{
219 m_process_alloc = process_alloc;
220 m_process_start = process_start;
221 m_size = size;
222 m_permissions = permissions;
223 m_alignment = alignment;
224 m_policy = policy;
225
226 switch (policy)
227 {
228 default:
229 assert (0 && "We cannot reach this!");
230 case eAllocationPolicyHostOnly:
231 m_data.SetByteSize(size);
232 memset(m_data.GetBytes(), 0, size);
233 break;
234 case eAllocationPolicyProcessOnly:
235 break;
236 case eAllocationPolicyMirror:
237 m_data.SetByteSize(size);
238 memset(m_data.GetBytes(), 0, size);
239 break;
240 }
241}
242
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000243lldb::addr_t
244IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
245{
Sean Callanan08052af2013-04-17 07:50:58 +0000246 error.Clear();
247
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000248 lldb::ProcessSP process_sp;
249 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
250 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
Matt Kopec750dcc32013-04-26 17:48:01 +0000251
252 size_t alignment_mask = alignment - 1;
253 size_t allocation_size;
254
255 if (size == 0)
256 allocation_size = alignment;
257 else
258 allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000259
260 switch (policy)
261 {
262 default:
263 error.SetErrorToGenericError();
264 error.SetErrorString("Couldn't malloc: invalid allocation policy");
265 return LLDB_INVALID_ADDRESS;
266 case eAllocationPolicyHostOnly:
267 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 break;
275 case eAllocationPolicyMirror:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000276 process_sp = m_process_wp.lock();
Sean Callananbb9945f2013-04-19 01:51:24 +0000277 if (process_sp && process_sp->CanJIT())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000278 {
279 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
280 if (!error.Success())
281 return LLDB_INVALID_ADDRESS;
282 }
283 else
284 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000285 policy = eAllocationPolicyHostOnly;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000286 allocation_address = FindSpace(allocation_size);
287 if (allocation_address == LLDB_INVALID_ADDRESS)
288 {
289 error.SetErrorToGenericError();
290 error.SetErrorString("Couldn't malloc: address space is full");
291 return LLDB_INVALID_ADDRESS;
292 }
293 }
294 break;
295 case eAllocationPolicyProcessOnly:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000296 process_sp = m_process_wp.lock();
297 if (process_sp)
298 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000299 if (process_sp->CanJIT())
300 {
301 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
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");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000309 return LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +0000310 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000311 }
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
Sean Callanand2562502013-04-19 17:44:40 +0000325 m_allocations[aligned_address] = Allocation(allocation_address,
326 aligned_address,
Matt Kopec750dcc32013-04-26 17:48:01 +0000327 allocation_size,
Sean Callanand2562502013-04-19 17:44:40 +0000328 permissions,
329 alignment,
330 policy);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000331
332 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
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 (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
Matt Kopec750dcc32013-04-26 17:48:01 +0000353 (uint64_t)allocation_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000354 (uint64_t)alignment,
355 (uint64_t)permissions,
356 policy_string,
357 aligned_address);
358 }
359
360 return aligned_address;
361}
362
363void
364IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
365{
Sean Callanan08052af2013-04-17 07:50:58 +0000366 error.Clear();
367
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000368 AllocationMap::iterator iter = m_allocations.find(process_address);
369
370 if (iter == m_allocations.end())
371 {
372 error.SetErrorToGenericError();
373 error.SetErrorString("Couldn't free: allocation doesn't exist");
374 return;
375 }
376
377 Allocation &allocation = iter->second;
378
379 switch (allocation.m_policy)
380 {
381 default:
382 case eAllocationPolicyHostOnly:
Sean Callanandf565402013-04-27 02:19:33 +0000383 {
384 lldb::ProcessSP process_sp = m_process_wp.lock();
385 if (process_sp && process_sp->CanJIT())
386 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
387
388 break;
389 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000390 case eAllocationPolicyMirror:
391 case eAllocationPolicyProcessOnly:
Sean Callanandf565402013-04-27 02:19:33 +0000392 {
393 lldb::ProcessSP process_sp = m_process_wp.lock();
394 if (process_sp)
395 process_sp->DeallocateMemory(allocation.m_process_alloc);
396 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000397 }
398
399 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
400 {
401 log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
402 (uint64_t)process_address,
403 iter->second.m_process_start,
404 iter->second.m_process_start + iter->second.m_size);
405 }
406
407 m_allocations.erase(iter);
408}
409
410void
411IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
412{
Sean Callanan08052af2013-04-17 07:50:58 +0000413 error.Clear();
414
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000415 AllocationMap::iterator iter = FindAllocation(process_address, size);
416
417 if (iter == m_allocations.end())
418 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000419 lldb::ProcessSP process_sp = m_process_wp.lock();
420
421 if (process_sp)
422 {
423 process_sp->WriteMemory(process_address, bytes, size, error);
424 return;
425 }
426
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000427 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000428 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000429 return;
430 }
431
432 Allocation &allocation = iter->second;
433
434 uint64_t offset = process_address - allocation.m_process_start;
435
436 lldb::ProcessSP process_sp;
437
438 switch (allocation.m_policy)
439 {
440 default:
441 error.SetErrorToGenericError();
442 error.SetErrorString("Couldn't write: invalid allocation policy");
443 return;
444 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000445 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000446 {
447 error.SetErrorToGenericError();
448 error.SetErrorString("Couldn't write: data buffer is empty");
449 return;
450 }
Sean Callanand2562502013-04-19 17:44:40 +0000451 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000452 break;
453 case eAllocationPolicyMirror:
Sean Callanand2562502013-04-19 17:44:40 +0000454 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000455 {
456 error.SetErrorToGenericError();
457 error.SetErrorString("Couldn't write: data buffer is empty");
458 return;
459 }
Sean Callanand2562502013-04-19 17:44:40 +0000460 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000461 process_sp = m_process_wp.lock();
462 if (process_sp)
463 {
464 process_sp->WriteMemory(process_address, bytes, size, error);
465 if (!error.Success())
466 return;
467 }
468 break;
469 case eAllocationPolicyProcessOnly:
470 process_sp = m_process_wp.lock();
471 if (process_sp)
472 {
473 process_sp->WriteMemory(process_address, bytes, size, error);
474 if (!error.Success())
475 return;
476 }
477 break;
478 }
479
480 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
481 {
482 log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
483 (uint64_t)process_address,
484 (uint64_t)bytes,
485 (uint64_t)size,
486 (uint64_t)allocation.m_process_start,
487 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
488 }
489}
490
491void
Sean Callanan35005f72013-04-12 18:10:34 +0000492IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000493{
494 error.Clear();
495
Sean Callanan35005f72013-04-12 18:10:34 +0000496 if (size == UINT32_MAX)
497 size = scalar.GetByteSize();
498
499 if (size > 0)
500 {
501 uint8_t buf[32];
502 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
503 if (mem_size > 0)
504 {
505 return WriteMemory(process_address, buf, mem_size, error);
506 }
507 else
508 {
509 error.SetErrorToGenericError();
510 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
511 }
512 }
513 else
514 {
515 error.SetErrorToGenericError();
516 error.SetErrorString ("Couldn't write scalar: its size was zero");
517 }
518 return;
519}
520
521void
Sean Callananf8043fa2013-04-12 21:40:34 +0000522IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
523{
Sean Callanan08052af2013-04-17 07:50:58 +0000524 error.Clear();
525
Sean Callananf8043fa2013-04-12 21:40:34 +0000526 Scalar scalar(address);
527
528 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
529}
530
Sean Callananf8043fa2013-04-12 21:40:34 +0000531void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000532IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
533{
Sean Callanan08052af2013-04-17 07:50:58 +0000534 error.Clear();
535
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000536 AllocationMap::iterator iter = FindAllocation(process_address, size);
537
538 if (iter == m_allocations.end())
539 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000540 lldb::ProcessSP process_sp = m_process_wp.lock();
541
542 if (process_sp)
543 {
544 process_sp->ReadMemory(process_address, bytes, size, error);
545 return;
546 }
547
548 lldb::TargetSP target_sp = m_target_wp.lock();
549
550 if (target_sp)
551 {
552 Address absolute_address(process_address);
553 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
554 return;
555 }
556
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000557 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000558 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 +0000559 return;
560 }
561
562 Allocation &allocation = iter->second;
563
564 uint64_t offset = process_address - allocation.m_process_start;
565
566 lldb::ProcessSP process_sp;
567
568 switch (allocation.m_policy)
569 {
570 default:
571 error.SetErrorToGenericError();
572 error.SetErrorString("Couldn't read: invalid allocation policy");
573 return;
574 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000575 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000576 {
577 error.SetErrorToGenericError();
578 error.SetErrorString("Couldn't read: data buffer is empty");
579 return;
580 }
Sean Callanand2562502013-04-19 17:44:40 +0000581 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000582 break;
583 case eAllocationPolicyMirror:
584 process_sp = m_process_wp.lock();
585 if (process_sp)
586 {
587 process_sp->ReadMemory(process_address, bytes, size, error);
588 if (!error.Success())
589 return;
590 }
591 else
592 {
Sean Callanand2562502013-04-19 17:44:40 +0000593 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000594 {
595 error.SetErrorToGenericError();
596 error.SetErrorString("Couldn't read: data buffer is empty");
597 return;
598 }
Sean Callanand2562502013-04-19 17:44:40 +0000599 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000600 }
601 break;
602 case eAllocationPolicyProcessOnly:
603 process_sp = m_process_wp.lock();
604 if (process_sp)
605 {
606 process_sp->ReadMemory(process_address, bytes, size, error);
607 if (!error.Success())
608 return;
609 }
610 break;
611 }
612
613 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
614 {
615 log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
616 (uint64_t)process_address,
617 (uint64_t)bytes,
618 (uint64_t)size,
619 (uint64_t)allocation.m_process_start,
620 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
621 }
622}
Sean Callanan35005f72013-04-12 18:10:34 +0000623
624void
625IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000626{
627 error.Clear();
628
Sean Callanan35005f72013-04-12 18:10:34 +0000629 if (size > 0)
630 {
631 DataBufferHeap buf(size, 0);
632 ReadMemory(buf.GetBytes(), process_address, size, error);
633
634 if (!error.Success())
635 return;
636
637 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
638
639 lldb::offset_t offset = 0;
640
641 switch (size)
642 {
643 default:
644 error.SetErrorToGenericError();
645 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
646 return;
647 case 1: scalar = extractor.GetU8(&offset); break;
648 case 2: scalar = extractor.GetU16(&offset); break;
649 case 4: scalar = extractor.GetU32(&offset); break;
650 case 8: scalar = extractor.GetU64(&offset); break;
651 }
652 }
653 else
654 {
655 error.SetErrorToGenericError();
Sean Callanan458ae1c2013-04-13 02:06:42 +0000656 error.SetErrorString ("Couldn't read scalar: its size was zero");
Sean Callanan35005f72013-04-12 18:10:34 +0000657 }
658 return;
659}
660
Sean Callanan458ae1c2013-04-13 02:06:42 +0000661void
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000662IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
663{
Sean Callanan08052af2013-04-17 07:50:58 +0000664 error.Clear();
665
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000666 Scalar pointer_scalar;
667 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
668
669 if (!error.Success())
670 return;
671
672 *address = pointer_scalar.ULongLong();
673
674 return;
675}
676
677void
Sean Callanan458ae1c2013-04-13 02:06:42 +0000678IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
679{
Sean Callanan08052af2013-04-17 07:50:58 +0000680 error.Clear();
681
Sean Callanan458ae1c2013-04-13 02:06:42 +0000682 if (size > 0)
683 {
684 AllocationMap::iterator iter = FindAllocation(process_address, size);
685
686 if (iter == m_allocations.end())
687 {
688 error.SetErrorToGenericError();
689 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
690 return;
691 }
692
693 Allocation &allocation = iter->second;
694
695 switch (allocation.m_policy)
696 {
697 default:
698 error.SetErrorToGenericError();
699 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
700 return;
701 case eAllocationPolicyProcessOnly:
702 error.SetErrorToGenericError();
703 error.SetErrorString("Couldn't get memory data: memory is only in the target");
704 return;
Sean Callanan458ae1c2013-04-13 02:06:42 +0000705 case eAllocationPolicyMirror:
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000706 {
707 lldb::ProcessSP process_sp = m_process_wp.lock();
708
Sean Callanand2562502013-04-19 17:44:40 +0000709 if (!allocation.m_data.GetByteSize())
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000710 {
711 error.SetErrorToGenericError();
712 error.SetErrorString("Couldn't get memory data: data buffer is empty");
713 return;
714 }
715 if (process_sp)
716 {
Sean Callanand2562502013-04-19 17:44:40 +0000717 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000718 if (!error.Success())
719 return;
720 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000721 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000722 return;
723 }
724 }
725 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000726 if (!allocation.m_data.GetByteSize())
Sean Callanan458ae1c2013-04-13 02:06:42 +0000727 {
728 error.SetErrorToGenericError();
729 error.SetErrorString("Couldn't get memory data: data buffer is empty");
730 return;
731 }
732 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000733 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callanan458ae1c2013-04-13 02:06:42 +0000734 return;
735 }
736 }
737 else
738 {
739 error.SetErrorToGenericError();
740 error.SetErrorString ("Couldn't get memory data: its size was zero");
741 return;
742 }
743}
744
745