summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRMemoryMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Expression/IRMemoryMap.cpp')
-rw-r--r--lldb/source/Expression/IRMemoryMap.cpp122
1 files changed, 82 insertions, 40 deletions
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 28a2fc1e0de..9a6f4479a54 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -50,36 +50,52 @@ IRMemoryMap::~IRMemoryMap ()
lldb::addr_t
IRMemoryMap::FindSpace (size_t size)
{
- // Yup, this is just plain O(n) insertion. We'll use a range tree if we
- // start caring.
-
- lldb::addr_t remote_address = 0x1000; // skip first page of memory
-
- for (AllocationMap::value_type &allocation : m_allocations)
- {
- if (remote_address < allocation.second.m_process_start &&
- remote_address + size <= allocation.second.m_process_start)
- return remote_address;
+ lldb::TargetSP target_sp = m_target_wp.lock();
+ lldb::ProcessSP process_sp = m_process_wp.lock();
- remote_address = allocation.second.m_process_start + allocation.second.m_size;
- }
+ lldb::addr_t ret = LLDB_INVALID_ADDRESS;
- if (remote_address + size < remote_address)
- return LLDB_INVALID_ADDRESS; // massively unlikely
-
- return remote_address;
-}
-
-bool
-IRMemoryMap::ContainsHostOnlyAllocations ()
-{
- for (AllocationMap::value_type &allocation : m_allocations)
+ for (int iterations = 0; iterations < 16; ++iterations)
{
- if (allocation.second.m_policy == eAllocationPolicyHostOnly)
- return true;
+ lldb::addr_t candidate;
+
+ switch (target_sp->GetArchitecture().GetAddressByteSize())
+ {
+ case 4:
+ {
+ uint32_t random_data = random();
+ candidate = random_data;
+ candidate &= ~0xfffull;
+ break;
+ }
+ case 8:
+ {
+ uint32_t random_low = random();
+ uint32_t random_high = random();
+ candidate = random_high;
+ candidate <<= 32ull;
+ candidate |= random_low;
+ candidate &= ~0xfffull;
+ break;
+ }
+ }
+
+ if (IntersectsAllocation(candidate, size))
+ continue;
+
+ char buf[1];
+
+ Error err;
+
+ if (process_sp &&
+ (process_sp->ReadMemory(candidate, buf, 1, err) == 1 ||
+ process_sp->ReadMemory(candidate + size, buf, 1, err) == 1))
+ continue;
+
+ ret = candidate;
}
- return false;
+ return ret;
}
IRMemoryMap::AllocationMap::iterator
@@ -104,6 +120,34 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
return m_allocations.end();
}
+bool
+IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
+{
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ AllocationMap::iterator iter = m_allocations.lower_bound (addr);
+
+ if (iter == m_allocations.end() ||
+ iter->first > addr)
+ {
+ if (iter == m_allocations.begin())
+ return false;
+
+ iter--;
+ }
+
+ while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
+ {
+ if (iter->second.m_process_start + iter->second.m_size > addr)
+ return true;
+
+ ++iter;
+ }
+
+ return false;
+}
+
lldb::ByteOrder
IRMemoryMap::GetByteOrder()
{
@@ -179,14 +223,8 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
}
break;
case eAllocationPolicyMirror:
- if (ContainsHostOnlyAllocations())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Couldn't malloc: host-only allocations are polluting the address space");
- return LLDB_INVALID_ADDRESS;
- }
process_sp = m_process_wp.lock();
- if (process_sp)
+ if (process_sp && process_sp->CanJIT())
{
allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
if (!error.Success())
@@ -194,6 +232,7 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
}
else
{
+ policy = eAllocationPolicyHostOnly;
allocation_address = FindSpace(allocation_size);
if (allocation_address == LLDB_INVALID_ADDRESS)
{
@@ -204,18 +243,21 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
}
break;
case eAllocationPolicyProcessOnly:
- if (ContainsHostOnlyAllocations())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Couldn't malloc: host-only allocations are polluting the address space");
- return LLDB_INVALID_ADDRESS;
- }
process_sp = m_process_wp.lock();
if (process_sp)
{
- allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
- if (!error.Success())
+ if (process_sp->CanJIT())
+ {
+ allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
+ if (!error.Success())
+ return LLDB_INVALID_ADDRESS;
+ }
+ else
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
return LLDB_INVALID_ADDRESS;
+ }
}
else
{
OpenPOWER on IntegriCloud