1 //===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/DataBufferHeap.h"
11 #include "lldb/Core/DataExtractor.h"
12 #include "lldb/Core/Error.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/Scalar.h"
15 #include "lldb/Expression/IRMemoryMap.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/Target.h"
19 using namespace lldb_private;
21 IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
22 m_target_wp(target_sp)
25 m_process_wp = target_sp->GetProcessSP();
28 IRMemoryMap::~IRMemoryMap ()
30 lldb::ProcessSP process_sp = m_process_wp.lock();
34 AllocationMap::iterator iter;
38 while ((iter = m_allocations.begin()) != m_allocations.end())
41 if (iter->second.m_leak)
42 m_allocations.erase(iter);
44 Free(iter->first, err);
50 IRMemoryMap::FindSpace (size_t size)
52 lldb::TargetSP target_sp = m_target_wp.lock();
53 lldb::ProcessSP process_sp = m_process_wp.lock();
55 lldb::addr_t ret = LLDB_INVALID_ADDRESS;
57 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
61 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
63 if (!alloc_error.Success())
64 return LLDB_INVALID_ADDRESS;
69 for (int iterations = 0; iterations < 16; ++iterations)
71 lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
73 switch (target_sp->GetArchitecture().GetAddressByteSize())
77 uint32_t random_data = random();
78 candidate = random_data;
79 candidate &= ~0xfffull;
84 uint32_t random_low = random();
85 uint32_t random_high = random();
86 candidate = random_high;
88 candidate |= random_low;
89 candidate &= ~0xfffull;
94 if (IntersectsAllocation(candidate, size))
105 IRMemoryMap::AllocationMap::iterator
106 IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
108 if (addr == LLDB_INVALID_ADDRESS)
109 return m_allocations.end();
111 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
113 if (iter == m_allocations.end() ||
116 if (iter == m_allocations.begin())
117 return m_allocations.end();
121 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
124 return m_allocations.end();
128 IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
130 if (addr == LLDB_INVALID_ADDRESS)
133 AllocationMap::iterator iter = m_allocations.lower_bound (addr);
135 if (iter == m_allocations.end() ||
138 if (iter == m_allocations.begin())
144 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
146 if (iter->second.m_process_start + iter->second.m_size > addr)
156 IRMemoryMap::GetByteOrder()
158 lldb::ProcessSP process_sp = m_process_wp.lock();
161 return process_sp->GetByteOrder();
163 lldb::TargetSP target_sp = m_target_wp.lock();
166 return target_sp->GetArchitecture().GetByteOrder();
168 return lldb::eByteOrderInvalid;
172 IRMemoryMap::GetAddressByteSize()
174 lldb::ProcessSP process_sp = m_process_wp.lock();
177 return process_sp->GetAddressByteSize();
179 lldb::TargetSP target_sp = m_target_wp.lock();
182 return target_sp->GetArchitecture().GetAddressByteSize();
187 ExecutionContextScope *
188 IRMemoryMap::GetBestExecutionContextScope()
190 lldb::ProcessSP process_sp = m_process_wp.lock();
193 return process_sp.get();
195 lldb::TargetSP target_sp = m_target_wp.lock();
198 return target_sp.get();
203 IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
204 lldb::addr_t process_start,
206 uint32_t permissions,
208 AllocationPolicy policy) :
209 m_process_alloc (process_alloc),
210 m_process_start (process_start),
212 m_permissions (permissions),
213 m_alignment (alignment),
220 assert (0 && "We cannot reach this!");
221 case eAllocationPolicyHostOnly:
222 m_data.SetByteSize(size);
223 memset(m_data.GetBytes(), 0, size);
225 case eAllocationPolicyProcessOnly:
227 case eAllocationPolicyMirror:
228 m_data.SetByteSize(size);
229 memset(m_data.GetBytes(), 0, size);
235 IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
239 lldb::ProcessSP process_sp;
240 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
241 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
243 size_t alignment_mask = alignment - 1;
244 size_t allocation_size;
247 allocation_size = alignment;
249 allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
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)
261 error.SetErrorToGenericError();
262 error.SetErrorString("Couldn't malloc: address space is full");
263 return LLDB_INVALID_ADDRESS;
266 case eAllocationPolicyMirror:
267 process_sp = m_process_wp.lock();
268 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
270 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
271 if (!error.Success())
272 return LLDB_INVALID_ADDRESS;
276 policy = eAllocationPolicyHostOnly;
277 allocation_address = FindSpace(allocation_size);
278 if (allocation_address == LLDB_INVALID_ADDRESS)
280 error.SetErrorToGenericError();
281 error.SetErrorString("Couldn't malloc: address space is full");
282 return LLDB_INVALID_ADDRESS;
286 case eAllocationPolicyProcessOnly:
287 process_sp = m_process_wp.lock();
290 if (process_sp->CanJIT() && process_sp->IsAlive())
292 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
293 if (!error.Success())
294 return LLDB_INVALID_ADDRESS;
298 error.SetErrorToGenericError();
299 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
300 return LLDB_INVALID_ADDRESS;
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;
313 lldb::addr_t mask = alignment - 1;
314 aligned_address = (allocation_address + mask) & (~mask);
316 m_allocations[aligned_address] = Allocation(allocation_address,
323 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
325 const char * policy_string;
330 policy_string = "<invalid policy>";
332 case eAllocationPolicyHostOnly:
333 policy_string = "eAllocationPolicyHostOnly";
335 case eAllocationPolicyProcessOnly:
336 policy_string = "eAllocationPolicyProcessOnly";
338 case eAllocationPolicyMirror:
339 policy_string = "eAllocationPolicyMirror";
343 log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
344 (uint64_t)allocation_size,
346 (uint64_t)permissions,
351 return aligned_address;
355 IRMemoryMap::Leak (lldb::addr_t process_address, Error &error)
359 AllocationMap::iterator iter = m_allocations.find(process_address);
361 if (iter == m_allocations.end())
363 error.SetErrorToGenericError();
364 error.SetErrorString("Couldn't leak: allocation doesn't exist");
368 Allocation &allocation = iter->second;
370 allocation.m_leak = true;
374 IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
378 AllocationMap::iterator iter = m_allocations.find(process_address);
380 if (iter == m_allocations.end())
382 error.SetErrorToGenericError();
383 error.SetErrorString("Couldn't free: allocation doesn't exist");
387 Allocation &allocation = iter->second;
389 switch (allocation.m_policy)
392 case eAllocationPolicyHostOnly:
394 lldb::ProcessSP process_sp = m_process_wp.lock();
397 if (process_sp->CanJIT() && process_sp->IsAlive())
398 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
403 case eAllocationPolicyMirror:
404 case eAllocationPolicyProcessOnly:
406 lldb::ProcessSP process_sp = m_process_wp.lock();
408 process_sp->DeallocateMemory(allocation.m_process_alloc);
412 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
414 log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")",
415 (uint64_t)process_address,
416 iter->second.m_process_start,
417 iter->second.m_process_start + iter->second.m_size);
420 m_allocations.erase(iter);
424 IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
428 AllocationMap::iterator iter = FindAllocation(process_address, size);
430 if (iter == m_allocations.end())
432 lldb::ProcessSP process_sp = m_process_wp.lock();
436 process_sp->WriteMemory(process_address, bytes, size, error);
440 error.SetErrorToGenericError();
441 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
445 Allocation &allocation = iter->second;
447 uint64_t offset = process_address - allocation.m_process_start;
449 lldb::ProcessSP process_sp;
451 switch (allocation.m_policy)
454 error.SetErrorToGenericError();
455 error.SetErrorString("Couldn't write: invalid allocation policy");
457 case eAllocationPolicyHostOnly:
458 if (!allocation.m_data.GetByteSize())
460 error.SetErrorToGenericError();
461 error.SetErrorString("Couldn't write: data buffer is empty");
464 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
466 case eAllocationPolicyMirror:
467 if (!allocation.m_data.GetByteSize())
469 error.SetErrorToGenericError();
470 error.SetErrorString("Couldn't write: data buffer is empty");
473 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
474 process_sp = m_process_wp.lock();
477 process_sp->WriteMemory(process_address, bytes, size, error);
478 if (!error.Success())
482 case eAllocationPolicyProcessOnly:
483 process_sp = m_process_wp.lock();
486 process_sp->WriteMemory(process_address, bytes, size, error);
487 if (!error.Success())
493 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
495 log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
496 (uint64_t)process_address,
499 (uint64_t)allocation.m_process_start,
500 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
505 IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
509 if (size == UINT32_MAX)
510 size = scalar.GetByteSize();
515 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
518 return WriteMemory(process_address, buf, mem_size, error);
522 error.SetErrorToGenericError();
523 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
528 error.SetErrorToGenericError();
529 error.SetErrorString ("Couldn't write scalar: its size was zero");
535 IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
539 Scalar scalar(address);
541 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
545 IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
549 AllocationMap::iterator iter = FindAllocation(process_address, size);
551 if (iter == m_allocations.end())
553 lldb::ProcessSP process_sp = m_process_wp.lock();
557 process_sp->ReadMemory(process_address, bytes, size, error);
561 lldb::TargetSP target_sp = m_target_wp.lock();
565 Address absolute_address(process_address);
566 target_sp->ReadMemory(absolute_address, false, bytes, size, error);
570 error.SetErrorToGenericError();
571 error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
575 Allocation &allocation = iter->second;
577 uint64_t offset = process_address - allocation.m_process_start;
579 lldb::ProcessSP process_sp;
581 switch (allocation.m_policy)
584 error.SetErrorToGenericError();
585 error.SetErrorString("Couldn't read: invalid allocation policy");
587 case eAllocationPolicyHostOnly:
588 if (!allocation.m_data.GetByteSize())
590 error.SetErrorToGenericError();
591 error.SetErrorString("Couldn't read: data buffer is empty");
594 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
596 case eAllocationPolicyMirror:
597 process_sp = m_process_wp.lock();
600 process_sp->ReadMemory(process_address, bytes, size, error);
601 if (!error.Success())
606 if (!allocation.m_data.GetByteSize())
608 error.SetErrorToGenericError();
609 error.SetErrorString("Couldn't read: data buffer is empty");
612 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
615 case eAllocationPolicyProcessOnly:
616 process_sp = m_process_wp.lock();
619 process_sp->ReadMemory(process_address, bytes, size, error);
620 if (!error.Success())
626 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
628 log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
629 (uint64_t)process_address,
632 (uint64_t)allocation.m_process_start,
633 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
638 IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
644 DataBufferHeap buf(size, 0);
645 ReadMemory(buf.GetBytes(), process_address, size, error);
647 if (!error.Success())
650 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
652 lldb::offset_t offset = 0;
657 error.SetErrorToGenericError();
658 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
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;
668 error.SetErrorToGenericError();
669 error.SetErrorString ("Couldn't read scalar: its size was zero");
675 IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
679 Scalar pointer_scalar;
680 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
682 if (!error.Success())
685 *address = pointer_scalar.ULongLong();
691 IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
697 AllocationMap::iterator iter = FindAllocation(process_address, size);
699 if (iter == m_allocations.end())
701 error.SetErrorToGenericError();
702 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
706 Allocation &allocation = iter->second;
708 switch (allocation.m_policy)
711 error.SetErrorToGenericError();
712 error.SetErrorString("Couldn't get memory data: invalid allocation policy");
714 case eAllocationPolicyProcessOnly:
715 error.SetErrorToGenericError();
716 error.SetErrorString("Couldn't get memory data: memory is only in the target");
718 case eAllocationPolicyMirror:
720 lldb::ProcessSP process_sp = m_process_wp.lock();
722 if (!allocation.m_data.GetByteSize())
724 error.SetErrorToGenericError();
725 error.SetErrorString("Couldn't get memory data: data buffer is empty");
730 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
731 if (!error.Success())
733 uint64_t offset = process_address - allocation.m_process_start;
734 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
738 case eAllocationPolicyHostOnly:
739 if (!allocation.m_data.GetByteSize())
741 error.SetErrorToGenericError();
742 error.SetErrorString("Couldn't get memory data: data buffer is empty");
745 uint64_t offset = process_address - allocation.m_process_start;
746 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
752 error.SetErrorToGenericError();
753 error.SetErrorString ("Couldn't get memory data: its size was zero");