blob: a83da2260e3d89c92a5f334e72b730407db997c0 [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();
Sean Callananfbf5c682013-05-22 22:49:06 +000041 if (iter->second.m_leak)
42 m_allocations.erase(iter);
43 else
44 Free(iter->first, err);
Sean Callanan5a1af4e2013-04-05 02:22:57 +000045 }
46 }
47}
48
49lldb::addr_t
50IRMemoryMap::FindSpace (size_t size)
51{
Sean Callananbb9945f2013-04-19 01:51:24 +000052 lldb::TargetSP target_sp = m_target_wp.lock();
53 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callanan5a1af4e2013-04-05 02:22:57 +000054
Sean Callananbb9945f2013-04-19 01:51:24 +000055 lldb::addr_t ret = LLDB_INVALID_ADDRESS;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000056
Sean Callananad7cc462013-06-17 21:19:31 +000057 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
Sean Callanandf565402013-04-27 02:19:33 +000058 {
59 Error alloc_error;
60
61 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
62
63 if (!alloc_error.Success())
64 return LLDB_INVALID_ADDRESS;
65 else
66 return ret;
67 }
68
Sean Callananbb9945f2013-04-19 01:51:24 +000069 for (int iterations = 0; iterations < 16; ++iterations)
Sean Callanan5a1af4e2013-04-05 02:22:57 +000070 {
Jim Ingham5c42d8a2013-05-15 18:27:08 +000071 lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +000072
73 switch (target_sp->GetArchitecture().GetAddressByteSize())
74 {
75 case 4:
76 {
77 uint32_t random_data = random();
78 candidate = random_data;
79 candidate &= ~0xfffull;
80 break;
81 }
82 case 8:
83 {
84 uint32_t random_low = random();
85 uint32_t random_high = random();
86 candidate = random_high;
87 candidate <<= 32ull;
88 candidate |= random_low;
89 candidate &= ~0xfffull;
90 break;
91 }
92 }
93
94 if (IntersectsAllocation(candidate, size))
95 continue;
Sean Callanan70cac8f2013-06-27 00:10:26 +000096
Sean Callananbb9945f2013-04-19 01:51:24 +000097 ret = candidate;
Sean Callanan70cac8f2013-06-27 00:10:26 +000098
Sean Callananbb777042013-05-16 17:30:37 +000099 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000100 }
101
Sean Callananbb9945f2013-04-19 01:51:24 +0000102 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000103}
104
105IRMemoryMap::AllocationMap::iterator
106IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
107{
Sean Callanan1582ee62013-04-18 22:06:33 +0000108 if (addr == LLDB_INVALID_ADDRESS)
109 return m_allocations.end();
110
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000111 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
112
Sean Callanan14b1bae2013-04-16 23:25:35 +0000113 if (iter == m_allocations.end() ||
114 iter->first > addr)
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000115 {
116 if (iter == m_allocations.begin())
117 return m_allocations.end();
118 iter--;
119 }
120
121 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
122 return iter;
123
124 return m_allocations.end();
125}
126
Sean Callananbb9945f2013-04-19 01:51:24 +0000127bool
128IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
129{
130 if (addr == LLDB_INVALID_ADDRESS)
131 return false;
132
133 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
134
135 if (iter == m_allocations.end() ||
136 iter->first > addr)
137 {
138 if (iter == m_allocations.begin())
139 return false;
140
141 iter--;
142 }
143
144 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
145 {
146 if (iter->second.m_process_start + iter->second.m_size > addr)
147 return true;
148
149 ++iter;
150 }
151
152 return false;
153}
154
Sean Callanan35005f72013-04-12 18:10:34 +0000155lldb::ByteOrder
156IRMemoryMap::GetByteOrder()
157{
158 lldb::ProcessSP process_sp = m_process_wp.lock();
159
160 if (process_sp)
161 return process_sp->GetByteOrder();
162
163 lldb::TargetSP target_sp = m_target_wp.lock();
164
165 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000166 return target_sp->GetArchitecture().GetByteOrder();
Sean Callanan35005f72013-04-12 18:10:34 +0000167
168 return lldb::eByteOrderInvalid;
169}
170
171uint32_t
172IRMemoryMap::GetAddressByteSize()
173{
174 lldb::ProcessSP process_sp = m_process_wp.lock();
175
176 if (process_sp)
177 return process_sp->GetAddressByteSize();
178
179 lldb::TargetSP target_sp = m_target_wp.lock();
180
181 if (target_sp)
Sean Callanan08052af2013-04-17 07:50:58 +0000182 return target_sp->GetArchitecture().GetAddressByteSize();
Sean Callanan35005f72013-04-12 18:10:34 +0000183
184 return UINT32_MAX;
185}
186
187ExecutionContextScope *
188IRMemoryMap::GetBestExecutionContextScope()
189{
190 lldb::ProcessSP process_sp = m_process_wp.lock();
191
192 if (process_sp)
193 return process_sp.get();
194
195 lldb::TargetSP target_sp = m_target_wp.lock();
196
197 if (target_sp)
198 return target_sp.get();
199
200 return NULL;
201}
202
Sean Callanand2562502013-04-19 17:44:40 +0000203IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
204 lldb::addr_t process_start,
205 size_t size,
206 uint32_t permissions,
207 uint8_t alignment,
208 AllocationPolicy policy)
209{
210 m_process_alloc = process_alloc;
211 m_process_start = process_start;
212 m_size = size;
213 m_permissions = permissions;
214 m_alignment = alignment;
215 m_policy = policy;
216
217 switch (policy)
218 {
219 default:
220 assert (0 && "We cannot reach this!");
221 case eAllocationPolicyHostOnly:
222 m_data.SetByteSize(size);
223 memset(m_data.GetBytes(), 0, size);
224 break;
225 case eAllocationPolicyProcessOnly:
226 break;
227 case eAllocationPolicyMirror:
228 m_data.SetByteSize(size);
229 memset(m_data.GetBytes(), 0, size);
230 break;
231 }
232}
233
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000234lldb::addr_t
235IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
236{
Sean Callanan08052af2013-04-17 07:50:58 +0000237 error.Clear();
238
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000239 lldb::ProcessSP process_sp;
240 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
241 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
Matt Kopec750dcc32013-04-26 17:48:01 +0000242
243 size_t alignment_mask = alignment - 1;
244 size_t allocation_size;
245
246 if (size == 0)
247 allocation_size = alignment;
248 else
249 allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000250
251 switch (policy)
252 {
253 default:
254 error.SetErrorToGenericError();
255 error.SetErrorString("Couldn't malloc: invalid allocation policy");
256 return LLDB_INVALID_ADDRESS;
257 case eAllocationPolicyHostOnly:
258 allocation_address = FindSpace(allocation_size);
259 if (allocation_address == LLDB_INVALID_ADDRESS)
260 {
261 error.SetErrorToGenericError();
262 error.SetErrorString("Couldn't malloc: address space is full");
263 return LLDB_INVALID_ADDRESS;
264 }
265 break;
266 case eAllocationPolicyMirror:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000267 process_sp = m_process_wp.lock();
Sean Callananad7cc462013-06-17 21:19:31 +0000268 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000269 {
270 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
271 if (!error.Success())
272 return LLDB_INVALID_ADDRESS;
273 }
274 else
275 {
Sean Callananbb9945f2013-04-19 01:51:24 +0000276 policy = eAllocationPolicyHostOnly;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000277 allocation_address = FindSpace(allocation_size);
278 if (allocation_address == LLDB_INVALID_ADDRESS)
279 {
280 error.SetErrorToGenericError();
281 error.SetErrorString("Couldn't malloc: address space is full");
282 return LLDB_INVALID_ADDRESS;
283 }
284 }
285 break;
286 case eAllocationPolicyProcessOnly:
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000287 process_sp = m_process_wp.lock();
288 if (process_sp)
289 {
Sean Callananad7cc462013-06-17 21:19:31 +0000290 if (process_sp->CanJIT() && process_sp->IsAlive())
Sean Callananbb9945f2013-04-19 01:51:24 +0000291 {
292 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
293 if (!error.Success())
294 return LLDB_INVALID_ADDRESS;
295 }
296 else
297 {
298 error.SetErrorToGenericError();
299 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000300 return LLDB_INVALID_ADDRESS;
Sean Callananbb9945f2013-04-19 01:51:24 +0000301 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000302 }
303 else
304 {
305 error.SetErrorToGenericError();
306 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
307 return LLDB_INVALID_ADDRESS;
308 }
309 break;
310 }
311
312
313 lldb::addr_t mask = alignment - 1;
314 aligned_address = (allocation_address + mask) & (~mask);
315
Sean Callanand2562502013-04-19 17:44:40 +0000316 m_allocations[aligned_address] = Allocation(allocation_address,
317 aligned_address,
Matt Kopec750dcc32013-04-26 17:48:01 +0000318 allocation_size,
Sean Callanand2562502013-04-19 17:44:40 +0000319 permissions,
320 alignment,
321 policy);
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000322
323 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
324 {
325 const char * policy_string;
326
327 switch (policy)
328 {
329 default:
330 policy_string = "<invalid policy>";
331 break;
332 case eAllocationPolicyHostOnly:
333 policy_string = "eAllocationPolicyHostOnly";
334 break;
335 case eAllocationPolicyProcessOnly:
336 policy_string = "eAllocationPolicyProcessOnly";
337 break;
338 case eAllocationPolicyMirror:
339 policy_string = "eAllocationPolicyMirror";
340 break;
341 }
342
Matt Kopecef143712013-06-03 18:00:07 +0000343 log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
Matt Kopec750dcc32013-04-26 17:48:01 +0000344 (uint64_t)allocation_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000345 (uint64_t)alignment,
346 (uint64_t)permissions,
347 policy_string,
348 aligned_address);
349 }
350
351 return aligned_address;
352}
353
354void
Sean Callananfbf5c682013-05-22 22:49:06 +0000355IRMemoryMap::Leak (lldb::addr_t process_address, Error &error)
356{
357 error.Clear();
358
359 AllocationMap::iterator iter = m_allocations.find(process_address);
360
361 if (iter == m_allocations.end())
362 {
363 error.SetErrorToGenericError();
364 error.SetErrorString("Couldn't leak: allocation doesn't exist");
365 return;
366 }
367
368 Allocation &allocation = iter->second;
369
370 allocation.m_leak = true;
371}
372
373void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000374IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
375{
Sean Callanan08052af2013-04-17 07:50:58 +0000376 error.Clear();
377
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000378 AllocationMap::iterator iter = m_allocations.find(process_address);
379
380 if (iter == m_allocations.end())
381 {
382 error.SetErrorToGenericError();
383 error.SetErrorString("Couldn't free: allocation doesn't exist");
384 return;
385 }
386
387 Allocation &allocation = iter->second;
388
389 switch (allocation.m_policy)
390 {
391 default:
392 case eAllocationPolicyHostOnly:
Sean Callanandf565402013-04-27 02:19:33 +0000393 {
394 lldb::ProcessSP process_sp = m_process_wp.lock();
Sean Callananbb777042013-05-16 17:30:37 +0000395 if (process_sp)
396 {
Sean Callananad7cc462013-06-17 21:19:31 +0000397 if (process_sp->CanJIT() && process_sp->IsAlive())
Sean Callananbb777042013-05-16 17:30:37 +0000398 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
Sean Callananbb777042013-05-16 17:30:37 +0000399 }
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 {
Matt Kopecef143712013-06-03 18:00:07 +0000414 log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")",
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000415 (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 {
Matt Kopecef143712013-06-03 18:00:07 +0000495 log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000496 (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 {
Matt Kopecef143712013-06-03 18:00:07 +0000628 log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000629 (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();
Greg Claytone86cef62013-06-04 21:30:42 +0000658 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
Sean Callanan35005f72013-04-12 18:10:34 +0000659 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();
Matt Kopecef143712013-06-03 18:00:07 +0000702 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
Sean Callanan458ae1c2013-04-13 02:06:42 +0000703 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