blob: 4c4cef41572ecadde5e253905df0f716e2cf4dd6 [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 {
Sean Callananbb777042013-05-16 17:30:37 +000034 AllocationMap::iterator iter;
35
36 Error err;
37
38 while ((iter = m_allocations.begin()) != m_allocations.end())
Sean Callanan5a1af4e2013-04-05 02:22:57 +000039 {
Sean Callananbb777042013-05-16 17:30:37 +000040 err.Clear();
41 Free(iter->first, err);
Sean Callanan5a1af4e2013-04-05 02:22:57 +000042 }
43 }
44}
45
46lldb::addr_t
47IRMemoryMap::FindSpace (size_t size)
48{
Sean Callananbb9945f2013-04-19 01:51:24 +000049 lldb::TargetSP target_sp = m_target_wp.lock();
50 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callanan5a1af4e2013-04-05 02:22:57 +000051
Sean Callananbb9945f2013-04-19 01:51:24 +000052 lldb::addr_t ret = LLDB_INVALID_ADDRESS;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000053
Sean Callanandf565402013-04-27 02:19:33 +000054 if (process_sp && process_sp->CanJIT())
55 {
56 Error alloc_error;
57
58 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
59
60 if (!alloc_error.Success())
61 return LLDB_INVALID_ADDRESS;
62 else
63 return ret;
64 }
65
Sean Callananbb777042013-05-16 17:30:37 +000066 if (process_sp)
67 {
68 ret = process_sp->GetReservationCache().Find(size);
69
70 if (ret != LLDB_INVALID_ADDRESS)
71 return ret;
72 }
73
Sean Callananbb9945f2013-04-19 01:51:24 +000074 for (int iterations = 0; iterations < 16; ++iterations)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000075 {
Jim Ingham5c42d8a2013-05-15 18:27:08 +000076 lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +000077
78 switch (target_sp->GetArchitecture().GetAddressByteSize())
79 {
80 case 4:
81 {
82 uint32_t random_data = random();
83 candidate = random_data;
84 candidate &= ~0xfffull;
85 break;
86 }
87 case 8:
88 {
89 uint32_t random_low = random();
90 uint32_t random_high = random();
91 candidate = random_high;
92 candidate <<= 32ull;
93 candidate |= random_low;
94 candidate &= ~0xfffull;
95 break;
96 }
97 }
98
99 if (IntersectsAllocation(candidate, size))
100 continue;
101
102 char buf[1];
103
104 Error err;
105
106 if (process_sp &&
107 (process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
108 process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
109 continue;
110
111 ret = candidate;
Sean Callananbb777042013-05-16 17:30:37 +0000112
113 if (process_sp)
114 process_sp->GetReservationCache().Reserve(candidate, size);
115
116 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000117 }
118
Sean Callananbb9945f2013-04-19 01:51:24 +0000119 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000120}
121
122IRMemoryMap::AllocationMap::iterator
123IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
124{
Sean Callanan1582ee62013-04-18 22:06:33 +0000125 if (addr == LLDB_INVALID_ADDRESS)
126 return m_allocations.end();
127
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000128 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
129
Sean Callanan14b1bae2013-04-16 23:25:35 +0000130 if (iter == m_allocations.end() ||
131 iter->first > addr)
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000132 {
133 if (iter == m_allocations.begin())
134 return m_allocations.end();
135 iter--;
136 }
137
138 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
139 return iter;
140
141 return m_allocations.end();
142}
143
Sean Callananbb9945f2013-04-19 01:51:24 +0000144bool
145IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
146{
147 if (addr == LLDB_INVALID_ADDRESS)
148 return false;
149
150 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
151
152 if (iter == m_allocations.end() ||
153 iter->first > addr)
154 {
155 if (iter == m_allocations.begin())
156 return false;
157
158 iter--;
159 }
160
161 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
162 {
163 if (iter->second.m_process_start + iter->second.m_size > addr)
164 return true;
165
166 ++iter;
167 }
168
169 return false;
170}
171
Sean Callanan35005f72013-04-12 18:10:34 +0000172lldb::ByteOrder
173IRMemoryMap::GetByteOrder()
174{
175 lldb::ProcessSP process_sp = m_process_wp.lock();
176
177 if (process_sp)
178 return process_sp->GetByteOrder();
179
180 lldb::TargetSP target_sp = m_target_wp.lock();
181
182 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000183 return target_sp->GetArchitecture().GetByteOrder();
Sean Callanan35005f72013-04-12 18:10:34 +0000184
185 return lldb::eByteOrderInvalid;
186}
187
188uint32_t
189IRMemoryMap::GetAddressByteSize()
190{
191 lldb::ProcessSP process_sp = m_process_wp.lock();
192
193 if (process_sp)
194 return process_sp->GetAddressByteSize();
195
196 lldb::TargetSP target_sp = m_target_wp.lock();
197
198 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000199 return target_sp->GetArchitecture().GetAddressByteSize();
Sean Callanan35005f72013-04-12 18:10:34 +0000200
201 return UINT32_MAX;
202}
203
204ExecutionContextScope *
205IRMemoryMap::GetBestExecutionContextScope()
206{
207 lldb::ProcessSP process_sp = m_process_wp.lock();
208
209 if (process_sp)
210 return process_sp.get();
211
212 lldb::TargetSP target_sp = m_target_wp.lock();
213
214 if (target_sp)
215 return target_sp.get();
216
217 return NULL;
218}
219
Sean Callanand2562502013-04-19 17:44:40 +0000220IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
221 lldb::addr_t process_start,
222 size_t size,
223 uint32_t permissions,
224 uint8_t alignment,
225 AllocationPolicy policy)
226{
227 m_process_alloc = process_alloc;
228 m_process_start = process_start;
229 m_size = size;
230 m_permissions = permissions;
231 m_alignment = alignment;
232 m_policy = policy;
233
234 switch (policy)
235 {
236 default:
237 assert (0 && "We cannot reach this!");
238 case eAllocationPolicyHostOnly:
239 m_data.SetByteSize(size);
240 memset(m_data.GetBytes(), 0, size);
241 break;
242 case eAllocationPolicyProcessOnly:
243 break;
244 case eAllocationPolicyMirror:
245 m_data.SetByteSize(size);
246 memset(m_data.GetBytes(), 0, size);
247 break;
248 }
249}
250
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000251lldb::addr_t
252IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
253{
Sean Callanan08052af2013-04-17 07:50:58 +0000254 error.Clear();
255
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000256 lldb::ProcessSP process_sp;
257 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
258 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
Matt Kopec750dcc32013-04-26 17:48:01 +0000259
260 size_t alignment_mask = alignment - 1;
261 size_t allocation_size;
262
263 if (size == 0)
264 allocation_size = alignment;
265 else
266 allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000267
268 switch (policy)
269 {
270 default:
271 error.SetErrorToGenericError();
272 error.SetErrorString("Couldn't malloc: invalid allocation policy");
273 return LLDB_INVALID_ADDRESS;
274 case eAllocationPolicyHostOnly:
275 allocation_address = FindSpace(allocation_size);
276 if (allocation_address == LLDB_INVALID_ADDRESS)
277 {
278 error.SetErrorToGenericError();
279 error.SetErrorString("Couldn't malloc: address space is full");
280 return LLDB_INVALID_ADDRESS;
281 }
282 break;
283 case eAllocationPolicyMirror:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000284 process_sp = m_process_wp.lock();
Sean Callananbb9945f2013-04-19 01:51:24 +0000285 if (process_sp && process_sp->CanJIT())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000286 {
287 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
288 if (!error.Success())
289 return LLDB_INVALID_ADDRESS;
290 }
291 else
292 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000293 policy = eAllocationPolicyHostOnly;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000294 allocation_address = FindSpace(allocation_size);
295 if (allocation_address == LLDB_INVALID_ADDRESS)
296 {
297 error.SetErrorToGenericError();
298 error.SetErrorString("Couldn't malloc: address space is full");
299 return LLDB_INVALID_ADDRESS;
300 }
301 }
302 break;
303 case eAllocationPolicyProcessOnly:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000304 process_sp = m_process_wp.lock();
305 if (process_sp)
306 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000307 if (process_sp->CanJIT())
308 {
309 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
310 if (!error.Success())
311 return LLDB_INVALID_ADDRESS;
312 }
313 else
314 {
315 error.SetErrorToGenericError();
316 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000317 return LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +0000318 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000319 }
320 else
321 {
322 error.SetErrorToGenericError();
323 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
324 return LLDB_INVALID_ADDRESS;
325 }
326 break;
327 }
328
329
330 lldb::addr_t mask = alignment - 1;
331 aligned_address = (allocation_address + mask) & (~mask);
332
Sean Callanand2562502013-04-19 17:44:40 +0000333 m_allocations[aligned_address] = Allocation(allocation_address,
334 aligned_address,
Matt Kopec750dcc32013-04-26 17:48:01 +0000335 allocation_size,
Sean Callanand2562502013-04-19 17:44:40 +0000336 permissions,
337 alignment,
338 policy);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000339
340 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
341 {
342 const char * policy_string;
343
344 switch (policy)
345 {
346 default:
347 policy_string = "<invalid policy>";
348 break;
349 case eAllocationPolicyHostOnly:
350 policy_string = "eAllocationPolicyHostOnly";
351 break;
352 case eAllocationPolicyProcessOnly:
353 policy_string = "eAllocationPolicyProcessOnly";
354 break;
355 case eAllocationPolicyMirror:
356 policy_string = "eAllocationPolicyMirror";
357 break;
358 }
359
360 log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
Matt Kopec750dcc32013-04-26 17:48:01 +0000361 (uint64_t)allocation_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000362 (uint64_t)alignment,
363 (uint64_t)permissions,
364 policy_string,
365 aligned_address);
366 }
367
368 return aligned_address;
369}
370
371void
372IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
373{
Sean Callanan08052af2013-04-17 07:50:58 +0000374 error.Clear();
375
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000376 AllocationMap::iterator iter = m_allocations.find(process_address);
377
378 if (iter == m_allocations.end())
379 {
380 error.SetErrorToGenericError();
381 error.SetErrorString("Couldn't free: allocation doesn't exist");
382 return;
383 }
384
385 Allocation &allocation = iter->second;
386
387 switch (allocation.m_policy)
388 {
389 default:
390 case eAllocationPolicyHostOnly:
Sean Callanandf565402013-04-27 02:19:33 +0000391 {
392 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callananbb777042013-05-16 17:30:37 +0000393 if (process_sp)
394 {
395 if (process_sp->CanJIT())
396 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
397 else
398 process_sp->GetReservationCache().Unreserve(allocation.m_process_alloc); // FindSpace registered this memory
399 }
400
Sean Callanandf565402013-04-27 02:19:33 +0000401 break;
402 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000403 case eAllocationPolicyMirror:
404 case eAllocationPolicyProcessOnly:
Sean Callanandf565402013-04-27 02:19:33 +0000405 {
406 lldb::ProcessSP process_sp = m_process_wp.lock();
407 if (process_sp)
408 process_sp->DeallocateMemory(allocation.m_process_alloc);
409 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000410 }
411
412 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
413 {
414 log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
415 (uint64_t)process_address,
416 iter->second.m_process_start,
417 iter->second.m_process_start + iter->second.m_size);
418 }
419
420 m_allocations.erase(iter);
421}
422
423void
424IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
425{
Sean Callanan08052af2013-04-17 07:50:58 +0000426 error.Clear();
427
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000428 AllocationMap::iterator iter = FindAllocation(process_address, size);
429
430 if (iter == m_allocations.end())
431 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000432 lldb::ProcessSP process_sp = m_process_wp.lock();
433
434 if (process_sp)
435 {
436 process_sp->WriteMemory(process_address, bytes, size, error);
437 return;
438 }
439
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000440 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000441 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000442 return;
443 }
444
445 Allocation &allocation = iter->second;
446
447 uint64_t offset = process_address - allocation.m_process_start;
448
449 lldb::ProcessSP process_sp;
450
451 switch (allocation.m_policy)
452 {
453 default:
454 error.SetErrorToGenericError();
455 error.SetErrorString("Couldn't write: invalid allocation policy");
456 return;
457 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000458 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000459 {
460 error.SetErrorToGenericError();
461 error.SetErrorString("Couldn't write: data buffer is empty");
462 return;
463 }
Sean Callanand2562502013-04-19 17:44:40 +0000464 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000465 break;
466 case eAllocationPolicyMirror:
Sean Callanand2562502013-04-19 17:44:40 +0000467 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000468 {
469 error.SetErrorToGenericError();
470 error.SetErrorString("Couldn't write: data buffer is empty");
471 return;
472 }
Sean Callanand2562502013-04-19 17:44:40 +0000473 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000474 process_sp = m_process_wp.lock();
475 if (process_sp)
476 {
477 process_sp->WriteMemory(process_address, bytes, size, error);
478 if (!error.Success())
479 return;
480 }
481 break;
482 case eAllocationPolicyProcessOnly:
483 process_sp = m_process_wp.lock();
484 if (process_sp)
485 {
486 process_sp->WriteMemory(process_address, bytes, size, error);
487 if (!error.Success())
488 return;
489 }
490 break;
491 }
492
493 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
494 {
495 log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
496 (uint64_t)process_address,
497 (uint64_t)bytes,
498 (uint64_t)size,
499 (uint64_t)allocation.m_process_start,
500 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
501 }
502}
503
504void
Sean Callanan35005f72013-04-12 18:10:34 +0000505IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000506{
507 error.Clear();
508
Sean Callanan35005f72013-04-12 18:10:34 +0000509 if (size == UINT32_MAX)
510 size = scalar.GetByteSize();
511
512 if (size > 0)
513 {
514 uint8_t buf[32];
515 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
516 if (mem_size > 0)
517 {
518 return WriteMemory(process_address, buf, mem_size, error);
519 }
520 else
521 {
522 error.SetErrorToGenericError();
523 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
524 }
525 }
526 else
527 {
528 error.SetErrorToGenericError();
529 error.SetErrorString ("Couldn't write scalar: its size was zero");
530 }
531 return;
532}
533
534void
Sean Callananf8043fa2013-04-12 21:40:34 +0000535IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
536{
Sean Callanan08052af2013-04-17 07:50:58 +0000537 error.Clear();
538
Sean Callananf8043fa2013-04-12 21:40:34 +0000539 Scalar scalar(address);
540
541 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
542}
543
Sean Callananf8043fa2013-04-12 21:40:34 +0000544void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000545IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
546{
Sean Callanan08052af2013-04-17 07:50:58 +0000547 error.Clear();
548
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000549 AllocationMap::iterator iter = FindAllocation(process_address, size);
550
551 if (iter == m_allocations.end())
552 {
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000553 lldb::ProcessSP process_sp = m_process_wp.lock();
554
555 if (process_sp)
556 {
557 process_sp->ReadMemory(process_address, bytes, size, error);
558 return;
559 }
560
561 lldb::TargetSP target_sp = m_target_wp.lock();
562
563 if (target_sp)
564 {
565 Address absolute_address(process_address);
566 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
567 return;
568 }
569
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000570 error.SetErrorToGenericError();
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000571 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 +0000572 return;
573 }
574
575 Allocation &allocation = iter->second;
576
577 uint64_t offset = process_address - allocation.m_process_start;
578
579 lldb::ProcessSP process_sp;
580
581 switch (allocation.m_policy)
582 {
583 default:
584 error.SetErrorToGenericError();
585 error.SetErrorString("Couldn't read: invalid allocation policy");
586 return;
587 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000588 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000589 {
590 error.SetErrorToGenericError();
591 error.SetErrorString("Couldn't read: data buffer is empty");
592 return;
593 }
Sean Callanand2562502013-04-19 17:44:40 +0000594 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000595 break;
596 case eAllocationPolicyMirror:
597 process_sp = m_process_wp.lock();
598 if (process_sp)
599 {
600 process_sp->ReadMemory(process_address, bytes, size, error);
601 if (!error.Success())
602 return;
603 }
604 else
605 {
Sean Callanand2562502013-04-19 17:44:40 +0000606 if (!allocation.m_data.GetByteSize())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000607 {
608 error.SetErrorToGenericError();
609 error.SetErrorString("Couldn't read: data buffer is empty");
610 return;
611 }
Sean Callanand2562502013-04-19 17:44:40 +0000612 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000613 }
614 break;
615 case eAllocationPolicyProcessOnly:
616 process_sp = m_process_wp.lock();
617 if (process_sp)
618 {
619 process_sp->ReadMemory(process_address, bytes, size, error);
620 if (!error.Success())
621 return;
622 }
623 break;
624 }
625
626 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
627 {
628 log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
629 (uint64_t)process_address,
630 (uint64_t)bytes,
631 (uint64_t)size,
632 (uint64_t)allocation.m_process_start,
633 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
634 }
635}
Sean Callanan35005f72013-04-12 18:10:34 +0000636
637void
638IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
Sean Callanan08052af2013-04-17 07:50:58 +0000639{
640 error.Clear();
641
Sean Callanan35005f72013-04-12 18:10:34 +0000642 if (size > 0)
643 {
644 DataBufferHeap buf(size, 0);
645 ReadMemory(buf.GetBytes(), process_address, size, error);
646
647 if (!error.Success())
648 return;
649
650 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
651
652 lldb::offset_t offset = 0;
653
654 switch (size)
655 {
656 default:
657 error.SetErrorToGenericError();
658 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
659 return;
660 case 1: scalar = extractor.GetU8(&offset); break;
661 case 2: scalar = extractor.GetU16(&offset); break;
662 case 4: scalar = extractor.GetU32(&offset); break;
663 case 8: scalar = extractor.GetU64(&offset); break;
664 }
665 }
666 else
667 {
668 error.SetErrorToGenericError();
Sean Callanan458ae1c2013-04-13 02:06:42 +0000669 error.SetErrorString ("Couldn't read scalar: its size was zero");
Sean Callanan35005f72013-04-12 18:10:34 +0000670 }
671 return;
672}
673
Sean Callanan458ae1c2013-04-13 02:06:42 +0000674void
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000675IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
676{
Sean Callanan08052af2013-04-17 07:50:58 +0000677 error.Clear();
678
Sean Callanan2d37e5a2013-04-15 22:48:23 +0000679 Scalar pointer_scalar;
680 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
681
682 if (!error.Success())
683 return;
684
685 *address = pointer_scalar.ULongLong();
686
687 return;
688}
689
690void
Sean Callanan458ae1c2013-04-13 02:06:42 +0000691IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
692{
Sean Callanan08052af2013-04-17 07:50:58 +0000693 error.Clear();
694
Sean Callanan458ae1c2013-04-13 02:06:42 +0000695 if (size > 0)
696 {
697 AllocationMap::iterator iter = FindAllocation(process_address, size);
698
699 if (iter == m_allocations.end())
700 {
701 error.SetErrorToGenericError();
702 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
703 return;
704 }
705
706 Allocation &allocation = iter->second;
707
708 switch (allocation.m_policy)
709 {
710 default:
711 error.SetErrorToGenericError();
712 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
713 return;
714 case eAllocationPolicyProcessOnly:
715 error.SetErrorToGenericError();
716 error.SetErrorString("Couldn't get memory data: memory is only in the target");
717 return;
Sean Callanan458ae1c2013-04-13 02:06:42 +0000718 case eAllocationPolicyMirror:
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000719 {
720 lldb::ProcessSP process_sp = m_process_wp.lock();
721
Sean Callanand2562502013-04-19 17:44:40 +0000722 if (!allocation.m_data.GetByteSize())
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000723 {
724 error.SetErrorToGenericError();
725 error.SetErrorString("Couldn't get memory data: data buffer is empty");
726 return;
727 }
728 if (process_sp)
729 {
Sean Callanand2562502013-04-19 17:44:40 +0000730 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000731 if (!error.Success())
732 return;
733 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000734 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callananc8c5b8d2013-04-15 21:35:52 +0000735 return;
736 }
737 }
738 case eAllocationPolicyHostOnly:
Sean Callanand2562502013-04-19 17:44:40 +0000739 if (!allocation.m_data.GetByteSize())
Sean Callanan458ae1c2013-04-13 02:06:42 +0000740 {
741 error.SetErrorToGenericError();
742 error.SetErrorString("Couldn't get memory data: data buffer is empty");
743 return;
744 }
745 uint64_t offset = process_address - allocation.m_process_start;
Sean Callanand2562502013-04-19 17:44:40 +0000746 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
Sean Callanan458ae1c2013-04-13 02:06:42 +0000747 return;
748 }
749 }
750 else
751 {
752 error.SetErrorToGenericError();
753 error.SetErrorString ("Couldn't get memory data: its size was zero");
754 return;
755 }
756}
757
758