19e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===//
29e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//
39e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//                     The LLVM Compiler Infrastructure
49e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//
59e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan// This file is distributed under the University of Illinois Open Source
69e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan// License. See LICENSE.TXT for details.
79e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//
89e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan//===----------------------------------------------------------------------===//
99e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
10f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Core/DataBufferHeap.h"
11f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Core/DataExtractor.h"
129e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan#include "lldb/Core/Error.h"
139e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan#include "lldb/Core/Log.h"
14f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Core/Scalar.h"
159e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan#include "lldb/Expression/IRMemoryMap.h"
169e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan#include "lldb/Target/Process.h"
17f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Target/Target.h"
189e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
199e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananusing namespace lldb_private;
209e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
21f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
22f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    m_target_wp(target_sp)
239e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
24faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan    if (target_sp)
25faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan        m_process_wp = target_sp->GetProcessSP();
269e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
279e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
289e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::~IRMemoryMap ()
299e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
309e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::ProcessSP process_sp = m_process_wp.lock();
319e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
329e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (process_sp)
339e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
345acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan        AllocationMap::iterator iter;
355acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan
365acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan        Error err;
375acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan
385acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan        while ((iter = m_allocations.begin()) != m_allocations.end())
399e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
405acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan            err.Clear();
41e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan            if (iter->second.m_leak)
42e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan                m_allocations.erase(iter);
43e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan            else
44e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan                Free(iter->first, err);
459e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
469e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
479e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
489e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
499e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananlldb::addr_t
509e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::FindSpace (size_t size)
519e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
5273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    lldb::TargetSP target_sp = m_target_wp.lock();
5373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    lldb::ProcessSP process_sp = m_process_wp.lock();
549e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    lldb::addr_t ret = LLDB_INVALID_ADDRESS;
569e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
57755d62b7348a837c282b1480c2c01dacdae7898fSean Callanan    if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
58cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    {
59cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        Error alloc_error;
60cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
61cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
62cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
63cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        if (!alloc_error.Success())
64cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            return LLDB_INVALID_ADDRESS;
65cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        else
66cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            return ret;
67cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    }
68cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
6973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    for (int iterations = 0; iterations < 16; ++iterations)
709e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
710c2921f5b9dab2ca1832bb746ab3aa3f66fdd0b5Jim Ingham        lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
7273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
7373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        switch (target_sp->GetArchitecture().GetAddressByteSize())
7473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        {
7573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        case 4:
7673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            {
7773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                uint32_t random_data = random();
7873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate = random_data;
7973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate &= ~0xfffull;
8073cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                break;
8173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            }
8273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        case 8:
8373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            {
8473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                uint32_t random_low = random();
8573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                uint32_t random_high = random();
8673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate = random_high;
8773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate <<= 32ull;
8873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate |= random_low;
8973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                candidate &= ~0xfffull;
9073cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                break;
9173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            }
9273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        }
9373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
9473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        if (IntersectsAllocation(candidate, size))
9573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            continue;
96e46dd5bb968f0c269ead5cbf3d05511fd2ebcf92Sean Callanan
9773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        ret = candidate;
98e46dd5bb968f0c269ead5cbf3d05511fd2ebcf92Sean Callanan
995acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan        return ret;
1009e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
1019e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
10273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    return ret;
1039e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
1049e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
1059e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::AllocationMap::iterator
1069e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
1079e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
1080f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (addr == LLDB_INVALID_ADDRESS)
1090f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return m_allocations.end();
1100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
1119e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    AllocationMap::iterator iter = m_allocations.lower_bound (addr);
1129e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
113a6686e36cd56843e594139324884585fb47b918bSean Callanan    if (iter == m_allocations.end() ||
114a6686e36cd56843e594139324884585fb47b918bSean Callanan        iter->first > addr)
1159e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
1169e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (iter == m_allocations.begin())
1179e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return m_allocations.end();
1189e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        iter--;
1199e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
1209e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
1219e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
1229e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return iter;
1239e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
1249e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    return m_allocations.end();
1259e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
1269e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
12773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callananbool
12873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean CallananIRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
12973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan{
13073cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    if (addr == LLDB_INVALID_ADDRESS)
13173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        return false;
13273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
13373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    AllocationMap::iterator iter = m_allocations.lower_bound (addr);
13473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
13573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    if (iter == m_allocations.end() ||
13673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        iter->first > addr)
13773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    {
13873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        if (iter == m_allocations.begin())
13973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            return false;
14073cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
14173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        iter--;
14273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    }
14373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
14473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
14573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    {
14673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        if (iter->second.m_process_start + iter->second.m_size > addr)
14773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            return true;
14873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
14973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan        ++iter;
15073cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    }
15173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
15273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan    return false;
15373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan}
15473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan
155f4b59480e8d1056b1638141a6a627b252f657db0Sean Callananlldb::ByteOrder
156f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::GetByteOrder()
157f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan{
158f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::ProcessSP process_sp = m_process_wp.lock();
159f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
160f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (process_sp)
161f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        return process_sp->GetByteOrder();
162f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
163f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::TargetSP target_sp = m_target_wp.lock();
164f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
165f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (target_sp)
16613615cfef0435af28ccc1e93e13c6161e94585edSean Callanan        return target_sp->GetArchitecture().GetByteOrder();
167f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
168f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    return lldb::eByteOrderInvalid;
169f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan}
170f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
171f4b59480e8d1056b1638141a6a627b252f657db0Sean Callananuint32_t
172f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::GetAddressByteSize()
173f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan{
174f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::ProcessSP process_sp = m_process_wp.lock();
175f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
176f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (process_sp)
177f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        return process_sp->GetAddressByteSize();
178f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
179f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::TargetSP target_sp = m_target_wp.lock();
180f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
181f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (target_sp)
18213615cfef0435af28ccc1e93e13c6161e94585edSean Callanan        return target_sp->GetArchitecture().GetAddressByteSize();
183f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
184f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    return UINT32_MAX;
185f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan}
186f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
187f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananExecutionContextScope *
188f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::GetBestExecutionContextScope()
189f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan{
190f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::ProcessSP process_sp = m_process_wp.lock();
191f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
192f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (process_sp)
193f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        return process_sp.get();
194f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
195f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    lldb::TargetSP target_sp = m_target_wp.lock();
196f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
197f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (target_sp)
198f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        return target_sp.get();
199f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
200f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    return NULL;
201f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan}
202f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
20306761aad61604feba2af78c873b104e0415d9361Sean CallananIRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
20406761aad61604feba2af78c873b104e0415d9361Sean Callanan                                     lldb::addr_t process_start,
20506761aad61604feba2af78c873b104e0415d9361Sean Callanan                                     size_t size,
20606761aad61604feba2af78c873b104e0415d9361Sean Callanan                                     uint32_t permissions,
20706761aad61604feba2af78c873b104e0415d9361Sean Callanan                                     uint8_t alignment,
2084300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain                                     AllocationPolicy policy) :
2094300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_process_alloc (process_alloc),
2104300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_process_start (process_start),
2114300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_size (size),
2124300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_permissions (permissions),
2134300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_alignment (alignment),
2144300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_policy (policy),
2154300bb1e6e55c9711f56474d8b0fc02795a86c32Michael Sartain    m_leak (false)
21606761aad61604feba2af78c873b104e0415d9361Sean Callanan{
21706761aad61604feba2af78c873b104e0415d9361Sean Callanan    switch (policy)
21806761aad61604feba2af78c873b104e0415d9361Sean Callanan    {
21906761aad61604feba2af78c873b104e0415d9361Sean Callanan        default:
22006761aad61604feba2af78c873b104e0415d9361Sean Callanan            assert (0 && "We cannot reach this!");
22106761aad61604feba2af78c873b104e0415d9361Sean Callanan        case eAllocationPolicyHostOnly:
22206761aad61604feba2af78c873b104e0415d9361Sean Callanan            m_data.SetByteSize(size);
22306761aad61604feba2af78c873b104e0415d9361Sean Callanan            memset(m_data.GetBytes(), 0, size);
22406761aad61604feba2af78c873b104e0415d9361Sean Callanan            break;
22506761aad61604feba2af78c873b104e0415d9361Sean Callanan        case eAllocationPolicyProcessOnly:
22606761aad61604feba2af78c873b104e0415d9361Sean Callanan            break;
22706761aad61604feba2af78c873b104e0415d9361Sean Callanan        case eAllocationPolicyMirror:
22806761aad61604feba2af78c873b104e0415d9361Sean Callanan            m_data.SetByteSize(size);
22906761aad61604feba2af78c873b104e0415d9361Sean Callanan            memset(m_data.GetBytes(), 0, size);
23006761aad61604feba2af78c873b104e0415d9361Sean Callanan            break;
23106761aad61604feba2af78c873b104e0415d9361Sean Callanan    }
23206761aad61604feba2af78c873b104e0415d9361Sean Callanan}
23306761aad61604feba2af78c873b104e0415d9361Sean Callanan
2349e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananlldb::addr_t
2359e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
2369e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
23713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
23813615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
2399e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::ProcessSP process_sp;
2409e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::addr_t    allocation_address  = LLDB_INVALID_ADDRESS;
2419e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::addr_t    aligned_address     = LLDB_INVALID_ADDRESS;
2423b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec
2433b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec    size_t          alignment_mask = alignment - 1;
2443b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec    size_t          allocation_size;
2453b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec
2463b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec    if (size == 0)
2473b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec        allocation_size = alignment;
2483b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec    else
2493b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec        allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
2509e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
2519e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    switch (policy)
2529e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
2539e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    default:
2549e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
2559e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorString("Couldn't malloc: invalid allocation policy");
2569e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return LLDB_INVALID_ADDRESS;
2579e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyHostOnly:
2589e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        allocation_address = FindSpace(allocation_size);
2599e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (allocation_address == LLDB_INVALID_ADDRESS)
2609e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
2619e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorToGenericError();
2629e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorString("Couldn't malloc: address space is full");
2639e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return LLDB_INVALID_ADDRESS;
2649e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
2659e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
2669e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyMirror:
2679e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
268755d62b7348a837c282b1480c2c01dacdae7898fSean Callanan        if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
2699e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
2709e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
2719e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (!error.Success())
2729e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return LLDB_INVALID_ADDRESS;
2739e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
2749e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        else
2759e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
27673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            policy = eAllocationPolicyHostOnly;
2779e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            allocation_address = FindSpace(allocation_size);
2789e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (allocation_address == LLDB_INVALID_ADDRESS)
2799e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            {
2809e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                error.SetErrorToGenericError();
2819e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                error.SetErrorString("Couldn't malloc: address space is full");
2829e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return LLDB_INVALID_ADDRESS;
2839e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            }
2849e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
2859e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
2869e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyProcessOnly:
2879e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
2889e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (process_sp)
2899e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
290755d62b7348a837c282b1480c2c01dacdae7898fSean Callanan            if (process_sp->CanJIT() && process_sp->IsAlive())
29173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            {
29273cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
29373cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                if (!error.Success())
29473cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                    return LLDB_INVALID_ADDRESS;
29573cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            }
29673cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            else
29773cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            {
29873cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                error.SetErrorToGenericError();
29973cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan                error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
3009e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return LLDB_INVALID_ADDRESS;
30173cb33aa0c9a59cfd42c3cea222378dc9d15abb0Sean Callanan            }
3029e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
3039e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        else
3049e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
3059e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorToGenericError();
3069e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
3079e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return LLDB_INVALID_ADDRESS;
3089e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
3099e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
3109e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
3119e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3129e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3139e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::addr_t mask = alignment - 1;
3149e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    aligned_address = (allocation_address + mask) & (~mask);
3159e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
31606761aad61604feba2af78c873b104e0415d9361Sean Callanan    m_allocations[aligned_address] = Allocation(allocation_address,
31706761aad61604feba2af78c873b104e0415d9361Sean Callanan                                                aligned_address,
3183b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec                                                allocation_size,
31906761aad61604feba2af78c873b104e0415d9361Sean Callanan                                                permissions,
32006761aad61604feba2af78c873b104e0415d9361Sean Callanan                                                alignment,
32106761aad61604feba2af78c873b104e0415d9361Sean Callanan                                                policy);
3229e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3239e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
3249e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
3259e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        const char * policy_string;
3269e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3279e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        switch (policy)
3289e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
3299e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        default:
3309e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            policy_string = "<invalid policy>";
3319e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            break;
3329e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        case eAllocationPolicyHostOnly:
3339e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            policy_string = "eAllocationPolicyHostOnly";
3349e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            break;
3359e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        case eAllocationPolicyProcessOnly:
3369e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            policy_string = "eAllocationPolicyProcessOnly";
3379e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            break;
3389e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        case eAllocationPolicyMirror:
3399e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            policy_string = "eAllocationPolicyMirror";
3409e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            break;
3419e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
3429e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
343884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec        log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
3443b04228884c9ae4365ef25e6feffc962e253ccbbMatt Kopec                    (uint64_t)allocation_size,
3459e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)alignment,
3469e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)permissions,
3479e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    policy_string,
3489e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    aligned_address);
3499e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
3509e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3519e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    return aligned_address;
3529e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
3539e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3549e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananvoid
355e7872343f18b90e4134fb91a616b138ba6bd6b92Sean CallananIRMemoryMap::Leak (lldb::addr_t process_address, Error &error)
356e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan{
357e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    error.Clear();
358e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan
359e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    AllocationMap::iterator iter = m_allocations.find(process_address);
360e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan
361e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    if (iter == m_allocations.end())
362e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    {
363e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan        error.SetErrorToGenericError();
364e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan        error.SetErrorString("Couldn't leak: allocation doesn't exist");
365e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan        return;
366e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    }
367e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan
368e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    Allocation &allocation = iter->second;
369e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan
370e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan    allocation.m_leak = true;
371e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan}
372e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan
373e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callananvoid
3749e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::Free (lldb::addr_t process_address, Error &error)
3759e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
37613615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
37713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
3789e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    AllocationMap::iterator iter = m_allocations.find(process_address);
3799e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3809e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (iter == m_allocations.end())
3819e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
3829e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
3839e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorString("Couldn't free: allocation doesn't exist");
3849e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return;
3859e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
3869e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3879e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    Allocation &allocation = iter->second;
3889e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
3899e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    switch (allocation.m_policy)
3909e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
3919e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    default:
3929e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyHostOnly:
393cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        {
394cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            lldb::ProcessSP process_sp = m_process_wp.lock();
3955acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan            if (process_sp)
3965acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan            {
397755d62b7348a837c282b1480c2c01dacdae7898fSean Callanan                if (process_sp->CanJIT() && process_sp->IsAlive())
3985acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan                    process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
3995acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan            }
4005acdec75cbdb5078de36d0bcf5b0c9bd97f46336Sean Callanan
401cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            break;
402cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        }
4039e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyMirror:
4049e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyProcessOnly:
405cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        {
406cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            lldb::ProcessSP process_sp = m_process_wp.lock();
407cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            if (process_sp)
408cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                process_sp->DeallocateMemory(allocation.m_process_alloc);
409cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        }
4109e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
4119e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4129e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
4139e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
414884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec        log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")",
4159e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)process_address,
4169e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    iter->second.m_process_start,
4179e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    iter->second.m_process_start + iter->second.m_size);
4189e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
4199e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4209e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    m_allocations.erase(iter);
4219e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
4229e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4239e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananvoid
4249e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
4259e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
42613615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
42713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
4289e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    AllocationMap::iterator iter = FindAllocation(process_address, size);
4299e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4309e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (iter == m_allocations.end())
4319e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
43256380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        lldb::ProcessSP process_sp = m_process_wp.lock();
43356380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
43456380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        if (process_sp)
43556380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        {
43656380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            process_sp->WriteMemory(process_address, bytes, size, error);
43756380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            return;
43856380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        }
43956380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
4409e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
44156380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
4429e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return;
4439e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
4449e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4459e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    Allocation &allocation = iter->second;
4469e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4479e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    uint64_t offset = process_address - allocation.m_process_start;
4489e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4499e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::ProcessSP process_sp;
4509e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4519e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    switch (allocation.m_policy)
4529e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
4539e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    default:
4549e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
4559e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorString("Couldn't write: invalid allocation policy");
4569e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return;
4579e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyHostOnly:
45806761aad61604feba2af78c873b104e0415d9361Sean Callanan        if (!allocation.m_data.GetByteSize())
4599e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
4609e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorToGenericError();
4619e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorString("Couldn't write: data buffer is empty");
4629e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return;
4639e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
46406761aad61604feba2af78c873b104e0415d9361Sean Callanan        ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
4659e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
4669e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyMirror:
46706761aad61604feba2af78c873b104e0415d9361Sean Callanan        if (!allocation.m_data.GetByteSize())
4689e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
4699e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorToGenericError();
4709e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorString("Couldn't write: data buffer is empty");
4719e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return;
4729e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
47306761aad61604feba2af78c873b104e0415d9361Sean Callanan        ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
4749e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
4759e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (process_sp)
4769e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
4779e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            process_sp->WriteMemory(process_address, bytes, size, error);
4789e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (!error.Success())
4799e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return;
4809e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
4819e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
4829e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyProcessOnly:
4839e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
4849e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (process_sp)
4859e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
4869e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            process_sp->WriteMemory(process_address, bytes, size, error);
4879e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (!error.Success())
4889e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return;
4899e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
4909e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
4919e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
4929e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
4939e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
4949e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
495884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec        log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
4969e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)process_address,
4979e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)bytes,
4989e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)size,
4999e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)allocation.m_process_start,
5009e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
5019e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
5029e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
5039e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5049e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callananvoid
505f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
50613615cfef0435af28ccc1e93e13c6161e94585edSean Callanan{
50713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
50813615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
509f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (size == UINT32_MAX)
510f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        size = scalar.GetByteSize();
511f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
512f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (size > 0)
513f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    {
514f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        uint8_t buf[32];
515f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
516f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        if (mem_size > 0)
517f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        {
518f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            return WriteMemory(process_address, buf, mem_size, error);
519f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        }
520f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        else
521f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        {
522f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            error.SetErrorToGenericError();
523f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
524f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        }
525f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    }
526f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    else
527f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    {
528f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        error.SetErrorToGenericError();
529f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        error.SetErrorString ("Couldn't write scalar: its size was zero");
530f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    }
531f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    return;
532f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan}
533f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
534f4b59480e8d1056b1638141a6a627b252f657db0Sean Callananvoid
535934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean CallananIRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
536934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan{
53713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
53813615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
539934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan    Scalar scalar(address);
540934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan
541934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan    WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
542934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan}
543934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan
544934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callananvoid
5459e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean CallananIRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
5469e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan{
54713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
54813615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
5499e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    AllocationMap::iterator iter = FindAllocation(process_address, size);
5509e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5519e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (iter == m_allocations.end())
5529e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
55356380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        lldb::ProcessSP process_sp = m_process_wp.lock();
55456380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
55556380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        if (process_sp)
55656380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        {
55756380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            process_sp->ReadMemory(process_address, bytes, size, error);
55856380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            return;
55956380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        }
56056380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
56156380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        lldb::TargetSP target_sp = m_target_wp.lock();
56256380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
56356380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        if (target_sp)
56456380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        {
56556380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            Address absolute_address(process_address);
56656380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            target_sp->ReadMemory(absolute_address, false, bytes, size, error);
56756380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            return;
56856380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        }
56956380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
5709e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
57156380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
5729e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return;
5739e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
5749e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5759e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    Allocation &allocation = iter->second;
5769e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5779e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    uint64_t offset = process_address - allocation.m_process_start;
5789e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5799e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    lldb::ProcessSP process_sp;
5809e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
5819e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    switch (allocation.m_policy)
5829e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
5839e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    default:
5849e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorToGenericError();
5859e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        error.SetErrorString("Couldn't read: invalid allocation policy");
5869e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        return;
5879e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyHostOnly:
58806761aad61604feba2af78c873b104e0415d9361Sean Callanan        if (!allocation.m_data.GetByteSize())
5899e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
5909e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorToGenericError();
5919e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            error.SetErrorString("Couldn't read: data buffer is empty");
5929e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            return;
5939e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
59406761aad61604feba2af78c873b104e0415d9361Sean Callanan        ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
5959e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
5969e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyMirror:
5979e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
5989e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (process_sp)
5999e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
6009e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            process_sp->ReadMemory(process_address, bytes, size, error);
6019e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (!error.Success())
6029e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return;
6039e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
6049e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        else
6059e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
60606761aad61604feba2af78c873b104e0415d9361Sean Callanan            if (!allocation.m_data.GetByteSize())
6079e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            {
6089e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                error.SetErrorToGenericError();
6099e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                error.SetErrorString("Couldn't read: data buffer is empty");
6109e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return;
6119e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            }
61206761aad61604feba2af78c873b104e0415d9361Sean Callanan            ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
6139e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
6149e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
6159e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    case eAllocationPolicyProcessOnly:
6169e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        process_sp = m_process_wp.lock();
6179e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        if (process_sp)
6189e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        {
6199e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            process_sp->ReadMemory(process_address, bytes, size, error);
6209e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan            if (!error.Success())
6219e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                return;
6229e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        }
6239e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan        break;
6249e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
6259e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan
6269e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
6279e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    {
628884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec        log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
6299e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)process_address,
6309e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)bytes,
6319e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)size,
6329e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)allocation.m_process_start,
6339e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                    (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
6349e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan    }
6359e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan}
636f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
637f4b59480e8d1056b1638141a6a627b252f657db0Sean Callananvoid
638f4b59480e8d1056b1638141a6a627b252f657db0Sean CallananIRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
63913615cfef0435af28ccc1e93e13c6161e94585edSean Callanan{
64013615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
64113615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
642f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    if (size > 0)
643f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    {
644f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        DataBufferHeap buf(size, 0);
645f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        ReadMemory(buf.GetBytes(), process_address, size, error);
646f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
647f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        if (!error.Success())
648f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            return;
649f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
650f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
651f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
652f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        lldb::offset_t offset = 0;
653f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
654f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        switch (size)
655f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        {
656f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        default:
657f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            error.SetErrorToGenericError();
6580ffd7ac680f5363ca6536c913a3a14eeaa874321Greg Clayton            error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
659f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan            return;
660f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        case 1: scalar = extractor.GetU8(&offset);  break;
661f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        case 2: scalar = extractor.GetU16(&offset); break;
662f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        case 4: scalar = extractor.GetU32(&offset); break;
663f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        case 8: scalar = extractor.GetU64(&offset); break;
664f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        }
665f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    }
666f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    else
667f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    {
668f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan        error.SetErrorToGenericError();
669e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        error.SetErrorString ("Couldn't read scalar: its size was zero");
670f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    }
671f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan    return;
672f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan}
673f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan
674e287e900488e20e07ef986ec0524b872fbeafa5dSean Callananvoid
67576f9879afa1508febd5538a63a3fad7f01c6c64fSean CallananIRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
67676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan{
67713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
67813615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
67976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan    Scalar pointer_scalar;
68076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan    ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
68176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan
68276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan    if (!error.Success())
68376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan        return;
68476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan
68576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan    *address = pointer_scalar.ULongLong();
68676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan
68776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan    return;
68876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan}
68976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan
69076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callananvoid
691e287e900488e20e07ef986ec0524b872fbeafa5dSean CallananIRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
692e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan{
69313615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    error.Clear();
69413615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
695e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    if (size > 0)
696e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    {
697e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        AllocationMap::iterator iter = FindAllocation(process_address, size);
698e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan
699e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        if (iter == m_allocations.end())
700e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        {
701e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            error.SetErrorToGenericError();
702884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec            error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
703e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            return;
704e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        }
705e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan
706e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        Allocation &allocation = iter->second;
707e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan
708e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        switch (allocation.m_policy)
709e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        {
710e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        default:
711e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            error.SetErrorToGenericError();
712e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            error.SetErrorString("Couldn't get memory data: invalid allocation policy");
713e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            return;
714e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        case eAllocationPolicyProcessOnly:
715e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            error.SetErrorToGenericError();
716e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            error.SetErrorString("Couldn't get memory data: memory is only in the target");
717e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            return;
718e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        case eAllocationPolicyMirror:
71956380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            {
72056380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                lldb::ProcessSP process_sp = m_process_wp.lock();
72156380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan
72206761aad61604feba2af78c873b104e0415d9361Sean Callanan                if (!allocation.m_data.GetByteSize())
72356380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                {
72456380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    error.SetErrorToGenericError();
72556380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    error.SetErrorString("Couldn't get memory data: data buffer is empty");
72656380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    return;
72756380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                }
72856380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                if (process_sp)
72956380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                {
73006761aad61604feba2af78c873b104e0415d9361Sean Callanan                    process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
73156380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    if (!error.Success())
73256380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                        return;
73356380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    uint64_t offset = process_address - allocation.m_process_start;
73406761aad61604feba2af78c873b104e0415d9361Sean Callanan                    extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
73556380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                    return;
73656380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan                }
73756380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan            }
73856380f2e77f9f33e0c0817f6d7db2fd06e49438bSean Callanan        case eAllocationPolicyHostOnly:
73906761aad61604feba2af78c873b104e0415d9361Sean Callanan            if (!allocation.m_data.GetByteSize())
740e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            {
741e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan                error.SetErrorToGenericError();
742e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan                error.SetErrorString("Couldn't get memory data: data buffer is empty");
743e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan                return;
744e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            }
745e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            uint64_t offset = process_address - allocation.m_process_start;
74606761aad61604feba2af78c873b104e0415d9361Sean Callanan            extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
747e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan            return;
748e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        }
749e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    }
750e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    else
751e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    {
752e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        error.SetErrorToGenericError();
753e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        error.SetErrorString ("Couldn't get memory data: its size was zero");
754e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan        return;
755e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan    }
756e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan}
757e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan
758e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan
759