//===-- IRMemoryMap.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"

using namespace lldb_private;

IRMemoryMap::IRMemoryMap(lldb::TargetSP target_sp) : m_target_wp(target_sp) {
  if (target_sp)
    m_process_wp = target_sp->GetProcessSP();
}

IRMemoryMap::~IRMemoryMap() {
  lldb::ProcessSP process_sp = m_process_wp.lock();

  if (process_sp) {
    AllocationMap::iterator iter;

    Status err;

    while ((iter = m_allocations.begin()) != m_allocations.end()) {
      err.Clear();
      if (iter->second.m_leak)
        m_allocations.erase(iter);
      else
        Free(iter->first, err);
    }
  }
}

lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
  // The FindSpace algorithm's job is to find a region of memory that the
  // underlying process is unlikely to be using.
  //
  // The memory returned by this function will never be written to.  The only
  // point is that it should not shadow process memory if possible, so that
  // expressions processing real values from the process do not use the wrong
  // data.
  //
  // If the process can in fact allocate memory (CanJIT() lets us know this)
  // then this can be accomplished just be allocating memory in the inferior.
  // Then no guessing is required.

  lldb::TargetSP target_sp = m_target_wp.lock();
  lldb::ProcessSP process_sp = m_process_wp.lock();

  const bool process_is_alive = process_sp && process_sp->IsAlive();

  lldb::addr_t ret = LLDB_INVALID_ADDRESS;
  if (size == 0)
    return ret;

  if (process_is_alive && process_sp->CanJIT()) {
    Status alloc_error;

    ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable |
                                               lldb::ePermissionsWritable,
                                     alloc_error);

    if (!alloc_error.Success())
      return LLDB_INVALID_ADDRESS;
    else
      return ret;
  }

  // At this point we know that we need to hunt.
  //
  // First, go to the end of the existing allocations we've made if there are
  // any allocations.  Otherwise start at the beginning of memory.

  if (m_allocations.empty()) {
    ret = 0;
  } else {
    auto back = m_allocations.rbegin();
    lldb::addr_t addr = back->first;
    size_t alloc_size = back->second.m_size;
    ret = llvm::alignTo(addr + alloc_size, 4096);
  }

  uint64_t end_of_memory;
  switch (GetAddressByteSize()) {
  case 2:
    end_of_memory = 0xffffull;
    break;
  case 4:
    end_of_memory = 0xffffffffull;
    break;
  case 8:
    end_of_memory = 0xffffffffffffffffull;
    break;
  default:
    lldbassert(false && "Invalid address size.");
    return LLDB_INVALID_ADDRESS;
  }

  // Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped
  // regions, walk forward through memory until a region is found that has
  // adequate space for our allocation.
  //
  // Skip this when the process can't JIT. In that case, allocations are
  // host-only and never written to process memory, so there's no need to probe
  // the process's memory map.
  if (process_is_alive && process_sp->CanJIT()) {
    MemoryRegionInfo region_info;
    Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
    if (err.Success()) {
      while (true) {
        if (region_info.GetRange().GetRangeBase() == 0 &&
            region_info.GetRange().GetRangeEnd() < end_of_memory) {
          // Don't use a region that starts at address 0,
          // it can make it harder to debug null dereference crashes
          // in the inferior.
          ret = region_info.GetRange().GetRangeEnd();
        } else if (region_info.GetReadable() != eLazyBoolNo ||
                   region_info.GetWritable() != eLazyBoolNo ||
                   region_info.GetExecutable() != eLazyBoolNo) {
          if (region_info.GetRange().GetRangeEnd() - 1 >= end_of_memory) {
            ret = LLDB_INVALID_ADDRESS;
            break;
          } else {
            ret = region_info.GetRange().GetRangeEnd();
          }
        } else if (ret + size < region_info.GetRange().GetRangeEnd()) {
          return ret;
        } else {
          // ret stays the same.  We just need to walk a bit further.
        }

        // FIXME: When we're able to JIT WebAssembly, this strategy won't work
        // because we might probe beyond its linear memory.
        err = process_sp->GetMemoryRegionInfo(
            region_info.GetRange().GetRangeEnd(), region_info);
        if (err.Fail()) {
          lldbassert(0 && "GetMemoryRegionInfo() succeeded, then failed");
          ret = LLDB_INVALID_ADDRESS;
          break;
        }
      }
    }
  }

  // We've tried our algorithm, and it didn't work.  Now we have to reset back
  // to the end of the allocations we've already reported, or use a 'sensible'
  // default if this is our first allocation.
  if (m_allocations.empty()) {
    uint64_t alloc_address = target_sp->GetExprAllocAddress();
    if (alloc_address > 0) {
      if (alloc_address >= end_of_memory) {
        lldbassert(0 && "The allocation address for expression evaluation must "
                        "be within process address space");
        return LLDB_INVALID_ADDRESS;
      }
      ret = alloc_address;
    } else {
      uint32_t address_byte_size = GetAddressByteSize();
      if (address_byte_size != UINT32_MAX) {
        switch (address_byte_size) {
        case 2:
          ret = 0x8000ull;
          break;
        case 4:
          ret = 0xee000000ull;
          break;
        case 8:
          ret = 0xdead0fff00000000ull;
          break;
        default:
          lldbassert(false && "Invalid address size.");
          return LLDB_INVALID_ADDRESS;
        }
      }
    }
  } else {
    auto back = m_allocations.rbegin();
    lldb::addr_t addr = back->first;
    size_t alloc_size = back->second.m_size;
    uint64_t align = target_sp->GetExprAllocAlign();
    if (align == 0)
      align = 4096;
    ret = llvm::alignTo(addr + alloc_size, align);
  }

  return ret;
}

IRMemoryMap::AllocationMap::iterator
IRMemoryMap::FindAllocation(lldb::addr_t addr, size_t size) {
  if (addr == LLDB_INVALID_ADDRESS)
    return m_allocations.end();

  AllocationMap::iterator iter = m_allocations.lower_bound(addr);

  if (iter == m_allocations.end() || iter->first > addr) {
    if (iter == m_allocations.begin())
      return m_allocations.end();
    iter--;
  }

  if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
    return iter;

  return m_allocations.end();
}

bool IRMemoryMap::IntersectsAllocation(lldb::addr_t addr, size_t size) const {
  if (addr == LLDB_INVALID_ADDRESS)
    return false;

  AllocationMap::const_iterator iter = m_allocations.lower_bound(addr);

  // Since we only know that the returned interval begins at a location greater
  // than or equal to where the given interval begins, it's possible that the
  // given interval intersects either the returned interval or the previous
  // interval.  Thus, we need to check both. Note that we only need to check
  // these two intervals.  Since all intervals are disjoint it is not possible
  // that an adjacent interval does not intersect, but a non-adjacent interval
  // does intersect.
  if (iter != m_allocations.end()) {
    if (AllocationsIntersect(addr, size, iter->second.m_process_start,
                             iter->second.m_size))
      return true;
  }

  if (iter != m_allocations.begin()) {
    --iter;
    if (AllocationsIntersect(addr, size, iter->second.m_process_start,
                             iter->second.m_size))
      return true;
  }

  return false;
}

bool IRMemoryMap::AllocationsIntersect(lldb::addr_t addr1, size_t size1,
                                       lldb::addr_t addr2, size_t size2) {
  // Given two half open intervals [A, B) and [X, Y), the only 6 permutations
  // that satisfy A<B and X<Y are the following:
  // A B X Y
  // A X B Y  (intersects)
  // A X Y B  (intersects)
  // X A B Y  (intersects)
  // X A Y B  (intersects)
  // X Y A B
  // The first is B <= X, and the last is Y <= A. So the condition is !(B <= X
  // || Y <= A)), or (X < B && A < Y)
  return (addr2 < (addr1 + size1)) && (addr1 < (addr2 + size2));
}

lldb::ByteOrder IRMemoryMap::GetByteOrder() {
  lldb::ProcessSP process_sp = m_process_wp.lock();

  if (process_sp)
    return process_sp->GetByteOrder();

  lldb::TargetSP target_sp = m_target_wp.lock();

  if (target_sp)
    return target_sp->GetArchitecture().GetByteOrder();

  return lldb::eByteOrderInvalid;
}

uint32_t IRMemoryMap::GetAddressByteSize() {
  lldb::ProcessSP process_sp = m_process_wp.lock();

  if (process_sp)
    return process_sp->GetAddressByteSize();

  lldb::TargetSP target_sp = m_target_wp.lock();

  if (target_sp)
    return target_sp->GetArchitecture().GetAddressByteSize();

  return UINT32_MAX;
}

ExecutionContextScope *IRMemoryMap::GetBestExecutionContextScope() const {
  lldb::ProcessSP process_sp = m_process_wp.lock();

  if (process_sp)
    return process_sp.get();

  lldb::TargetSP target_sp = m_target_wp.lock();

  if (target_sp)
    return target_sp.get();

  return nullptr;
}

IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc,
                                    lldb::addr_t process_start, size_t size,
                                    uint32_t permissions, uint8_t alignment,
                                    AllocationPolicy policy)
    : m_process_alloc(process_alloc), m_process_start(process_start),
      m_size(size), m_policy(policy), m_leak(false), m_permissions(permissions),
      m_alignment(alignment) {
  switch (policy) {
  default:
    llvm_unreachable("Invalid AllocationPolicy");
  case eAllocationPolicyHostOnly:
  case eAllocationPolicyMirror:
    m_data.SetByteSize(size);
    break;
  case eAllocationPolicyProcessOnly:
    break;
  }
}

llvm::Expected<lldb::addr_t>
IRMemoryMap::Malloc(size_t size, uint8_t alignment, uint32_t permissions,
                    AllocationPolicy policy, bool zero_memory,
                    AllocationPolicy *used_policy) {
  lldb_private::Log *log(GetLog(LLDBLog::Expressions));

  lldb::ProcessSP process_sp;
  lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
  lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;

  size_t allocation_size;

  if (size == 0) {
    // FIXME: Malloc(0) should either return an invalid address or assert, in
    // order to cut down on unnecessary allocations.
    allocation_size = alignment;
  } else {
    // Round up the requested size to an aligned value.
    allocation_size = llvm::alignTo(size, alignment);

    // The process page cache does not see the requested alignment. We can't
    // assume its result will be any more than 1-byte aligned. To work around
    // this, request `alignment - 1` additional bytes.
    allocation_size += alignment - 1;
  }

  switch (policy) {
  default:
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "Couldn't malloc: invalid allocation policy");
  case eAllocationPolicyHostOnly:
    allocation_address = FindSpace(allocation_size);
    if (allocation_address == LLDB_INVALID_ADDRESS)
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Couldn't malloc: address space is full");
    break;
  case eAllocationPolicyMirror:
    process_sp = m_process_wp.lock();
    LLDB_LOGF(log,
              "IRMemoryMap::%s process_sp=0x%" PRIxPTR
              ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s",
              __FUNCTION__, reinterpret_cast<uintptr_t>(process_sp.get()),
              process_sp && process_sp->CanJIT() ? "true" : "false",
              process_sp && process_sp->IsAlive() ? "true" : "false");
    if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) {
      Status error;
      if (!zero_memory)
        allocation_address =
            process_sp->AllocateMemory(allocation_size, permissions, error);
      else
        allocation_address =
            process_sp->CallocateMemory(allocation_size, permissions, error);

      if (!error.Success())
        return error.takeError();
    } else {
      LLDB_LOGF(log,
                "IRMemoryMap::%s switching to eAllocationPolicyHostOnly "
                "due to failed condition (see previous expr log message)",
                __FUNCTION__);
      policy = eAllocationPolicyHostOnly;
      allocation_address = FindSpace(allocation_size);
      if (allocation_address == LLDB_INVALID_ADDRESS)
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Couldn't malloc: address space is full");
    }
    break;
  case eAllocationPolicyProcessOnly:
    process_sp = m_process_wp.lock();
    if (process_sp) {
      if (process_sp->CanJIT() && process_sp->IsAlive()) {
        Status error;
        if (!zero_memory)
          allocation_address =
              process_sp->AllocateMemory(allocation_size, permissions, error);
        else
          allocation_address =
              process_sp->CallocateMemory(allocation_size, permissions, error);

        if (!error.Success())
          return error.takeError();
      } else {
        return llvm::createStringError(
            llvm::inconvertibleErrorCode(),
            "Couldn't malloc: process doesn't support allocating memory");
      }
    } else {
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Couldn't malloc: process doesn't exist, "
                                     "and this memory must be in the process");
    }
    break;
  }

  lldb::addr_t mask = alignment - 1;
  aligned_address = (allocation_address + mask) & (~mask);

  m_allocations.emplace(
      std::piecewise_construct, std::forward_as_tuple(aligned_address),
      std::forward_as_tuple(allocation_address, aligned_address,
                            allocation_size, permissions, alignment, policy));

  if (zero_memory) {
    Status write_error;
    std::vector<uint8_t> zero_buf(size, 0);
    WriteMemory(aligned_address, zero_buf.data(), size, write_error);
  }

  if (log) {
    const char *policy_string;

    switch (policy) {
    default:
      policy_string = "<invalid policy>";
      break;
    case eAllocationPolicyHostOnly:
      policy_string = "eAllocationPolicyHostOnly";
      break;
    case eAllocationPolicyProcessOnly:
      policy_string = "eAllocationPolicyProcessOnly";
      break;
    case eAllocationPolicyMirror:
      policy_string = "eAllocationPolicyMirror";
      break;
    }

    LLDB_LOGF(log,
              "IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64
              ", %s) -> 0x%" PRIx64,
              (uint64_t)allocation_size, (uint64_t)alignment,
              (uint64_t)permissions, policy_string, aligned_address);
  }

  if (used_policy)
    *used_policy = policy;

  return aligned_address;
}

void IRMemoryMap::Leak(lldb::addr_t process_address, Status &error) {
  error.Clear();

  AllocationMap::iterator iter = m_allocations.find(process_address);

  if (iter == m_allocations.end()) {
    error = Status::FromErrorString("Couldn't leak: allocation doesn't exist");
    return;
  }

  Allocation &allocation = iter->second;

  allocation.m_leak = true;
}

void IRMemoryMap::Free(lldb::addr_t process_address, Status &error) {
  error.Clear();

  AllocationMap::iterator iter = m_allocations.find(process_address);

  if (iter == m_allocations.end()) {
    error = Status::FromErrorString("Couldn't free: allocation doesn't exist");
    return;
  }

  Allocation &allocation = iter->second;

  switch (allocation.m_policy) {
  default:
  case eAllocationPolicyHostOnly: {
    lldb::ProcessSP process_sp = m_process_wp.lock();
    if (process_sp) {
      if (process_sp->CanJIT() && process_sp->IsAlive())
        process_sp->DeallocateMemory(
            allocation.m_process_alloc); // FindSpace allocated this for real
    }

    break;
  }
  case eAllocationPolicyMirror:
  case eAllocationPolicyProcessOnly: {
    lldb::ProcessSP process_sp = m_process_wp.lock();
    if (process_sp)
      process_sp->DeallocateMemory(allocation.m_process_alloc);
  }
  }

  if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) {
    LLDB_LOGF(log,
              "IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64
              "..0x%" PRIx64 ")",
              (uint64_t)process_address, iter->second.m_process_start,
              iter->second.m_process_start + iter->second.m_size);
  }

  m_allocations.erase(iter);
}

bool IRMemoryMap::GetAllocSize(lldb::addr_t address, size_t &size) {
  AllocationMap::iterator iter = FindAllocation(address, size);
  if (iter == m_allocations.end())
    return false;

  Allocation &al = iter->second;

  if (address > (al.m_process_start + al.m_size)) {
    size = 0;
    return false;
  }

  if (address > al.m_process_start) {
    int dif = address - al.m_process_start;
    size = al.m_size - dif;
    return true;
  }

  size = al.m_size;
  return true;
}

void IRMemoryMap::WriteMemory(lldb::addr_t process_address,
                              const uint8_t *bytes, size_t size,
                              Status &error) {
  error.Clear();

  AllocationMap::iterator iter = FindAllocation(process_address, size);

  if (iter == m_allocations.end()) {
    lldb::ProcessSP process_sp = m_process_wp.lock();

    if (process_sp) {
      process_sp->WriteMemory(process_address, bytes, size, error);
      return;
    }

    error = Status::FromErrorString(
        "Couldn't write: no allocation contains the target "
        "range and the process doesn't exist");
    return;
  }

  Allocation &allocation = iter->second;

  uint64_t offset = process_address - allocation.m_process_start;

  lldb::ProcessSP process_sp;

  switch (allocation.m_policy) {
  default:
    error =
        Status::FromErrorString("Couldn't write: invalid allocation policy");
    return;
  case eAllocationPolicyHostOnly:
    if (!allocation.m_data.GetByteSize()) {
      error = Status::FromErrorString("Couldn't write: data buffer is empty");
      return;
    }
    ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size);
    break;
  case eAllocationPolicyMirror:
    if (!allocation.m_data.GetByteSize()) {
      error = Status::FromErrorString("Couldn't write: data buffer is empty");
      return;
    }
    ::memcpy(allocation.m_data.GetBytes() + offset, bytes, size);
    process_sp = m_process_wp.lock();
    if (process_sp) {
      process_sp->WriteMemory(process_address, bytes, size, error);
      if (!error.Success())
        return;
    }
    break;
  case eAllocationPolicyProcessOnly:
    process_sp = m_process_wp.lock();
    if (process_sp) {
      process_sp->WriteMemory(process_address, bytes, size, error);
      if (!error.Success())
        return;
    }
    break;
  }

  if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) {
    LLDB_LOGF(log,
              "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIxPTR
              ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
              (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size,
              (uint64_t)allocation.m_process_start,
              (uint64_t)allocation.m_process_start +
                  (uint64_t)allocation.m_size);
  }
}

void IRMemoryMap::WriteScalarToMemory(lldb::addr_t process_address,
                                      Scalar &scalar, size_t size,
                                      Status &error) {
  error.Clear();

  if (size == UINT32_MAX)
    size = scalar.GetByteSize();

  if (size > 0) {
    uint8_t buf[32];
    const size_t mem_size =
        scalar.GetAsMemoryData(buf, size, GetByteOrder(), error);
    if (mem_size > 0) {
      return WriteMemory(process_address, buf, mem_size, error);
    } else {
      error = Status::FromErrorString(
          "Couldn't write scalar: failed to get scalar as memory data");
    }
  } else {
    error = Status::FromErrorString("Couldn't write scalar: its size was zero");
  }
}

void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
                                       lldb::addr_t pointer, Status &error) {
  error.Clear();

  /// Only ask the Process to fix `pointer` if the address belongs to the
  /// process. An address belongs to the process if the Allocation policy is not
  /// eAllocationPolicyHostOnly.
  auto it = FindAllocation(pointer, 1);
  if (it == m_allocations.end() ||
      it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly)
    if (auto process_sp = GetProcessWP().lock())
      pointer = process_sp->FixAnyAddress(pointer);

  Scalar scalar(pointer);

  WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
}

void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address,
                             size_t size, Status &error) {
  error.Clear();

  AllocationMap::iterator iter = FindAllocation(process_address, size);

  if (iter == m_allocations.end()) {
    lldb::ProcessSP process_sp = m_process_wp.lock();

    if (process_sp) {
      process_sp->ReadMemory(process_address, bytes, size, error);
      return;
    }

    lldb::TargetSP target_sp = m_target_wp.lock();

    if (target_sp) {
      Address absolute_address(process_address);
      target_sp->ReadMemory(absolute_address, bytes, size, error, true);
      return;
    }

    error = Status::FromErrorString(
        "Couldn't read: no allocation contains the target "
        "range, and neither the process nor the target exist");
    return;
  }

  Allocation &allocation = iter->second;

  uint64_t offset = process_address - allocation.m_process_start;

  if (offset > allocation.m_size) {
    error =
        Status::FromErrorString("Couldn't read: data is not in the allocation");
    return;
  }

  lldb::ProcessSP process_sp;

  switch (allocation.m_policy) {
  default:
    error = Status::FromErrorString("Couldn't read: invalid allocation policy");
    return;
  case eAllocationPolicyHostOnly:
    if (!allocation.m_data.GetByteSize()) {
      error = Status::FromErrorString("Couldn't read: data buffer is empty");
      return;
    }
    if (allocation.m_data.GetByteSize() < offset + size) {
      error =
          Status::FromErrorString("Couldn't read: not enough underlying data");
      return;
    }

    ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size);
    break;
  case eAllocationPolicyMirror:
    process_sp = m_process_wp.lock();
    if (process_sp) {
      process_sp->ReadMemory(process_address, bytes, size, error);
      if (!error.Success())
        return;
    } else {
      if (!allocation.m_data.GetByteSize()) {
        error = Status::FromErrorString("Couldn't read: data buffer is empty");
        return;
      }
      ::memcpy(bytes, allocation.m_data.GetBytes() + offset, size);
    }
    break;
  case eAllocationPolicyProcessOnly:
    process_sp = m_process_wp.lock();
    if (process_sp) {
      process_sp->ReadMemory(process_address, bytes, size, error);
      if (!error.Success())
        return;
    }
    break;
  }

  if (lldb_private::Log *log = GetLog(LLDBLog::Expressions)) {
    LLDB_LOGF(log,
              "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIxPTR
              ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
              (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size,
              (uint64_t)allocation.m_process_start,
              (uint64_t)allocation.m_process_start +
                  (uint64_t)allocation.m_size);
  }
}

void IRMemoryMap::ReadScalarFromMemory(Scalar &scalar,
                                       lldb::addr_t process_address,
                                       size_t size, Status &error) {
  error.Clear();

  if (size > 0) {
    DataBufferHeap buf(size, 0);
    ReadMemory(buf.GetBytes(), process_address, size, error);

    if (!error.Success())
      return;

    DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(),
                            GetAddressByteSize());

    lldb::offset_t offset = 0;

    switch (size) {
    default:
      error = Status::FromErrorStringWithFormat(
          "Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
      return;
    case 1:
      scalar = extractor.GetU8(&offset);
      break;
    case 2:
      scalar = extractor.GetU16(&offset);
      break;
    case 4:
      scalar = extractor.GetU32(&offset);
      break;
    case 8:
      scalar = extractor.GetU64(&offset);
      break;
    }
  } else {
    error = Status::FromErrorString("Couldn't read scalar: its size was zero");
  }
}

void IRMemoryMap::ReadPointerFromMemory(lldb::addr_t *address,
                                        lldb::addr_t process_address,
                                        Status &error) {
  error.Clear();

  Scalar pointer_scalar;
  ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(),
                       error);

  if (!error.Success())
    return;

  *address = pointer_scalar.ULongLong();
}

void IRMemoryMap::GetMemoryData(DataExtractor &extractor,
                                lldb::addr_t process_address, size_t size,
                                Status &error) {
  error.Clear();

  if (size > 0) {
    AllocationMap::iterator iter = FindAllocation(process_address, size);

    if (iter == m_allocations.end()) {
      error = Status::FromErrorStringWithFormat(
          "Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64
          ")",
          process_address, process_address + size);
      return;
    }

    Allocation &allocation = iter->second;

    switch (allocation.m_policy) {
    default:
      error = Status::FromErrorString(
          "Couldn't get memory data: invalid allocation policy");
      return;
    case eAllocationPolicyProcessOnly:
      error = Status::FromErrorString(
          "Couldn't get memory data: memory is only in the target");
      return;
    case eAllocationPolicyMirror: {
      lldb::ProcessSP process_sp = m_process_wp.lock();

      if (!allocation.m_data.GetByteSize()) {
        error = Status::FromErrorString(
            "Couldn't get memory data: data buffer is empty");
        return;
      }
      if (process_sp) {
        process_sp->ReadMemory(allocation.m_process_start,
                               allocation.m_data.GetBytes(),
                               allocation.m_data.GetByteSize(), error);
        if (!error.Success())
          return;
        uint64_t offset = process_address - allocation.m_process_start;
        extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size,
                                  GetByteOrder(), GetAddressByteSize());
        return;
      }
    } break;
    case eAllocationPolicyHostOnly:
      if (!allocation.m_data.GetByteSize()) {
        error = Status::FromErrorString(
            "Couldn't get memory data: data buffer is empty");
        return;
      }
      uint64_t offset = process_address - allocation.m_process_start;
      extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size,
                                GetByteOrder(), GetAddressByteSize());
      return;
    }
  } else {
    error =
        Status::FromErrorString("Couldn't get memory data: its size was zero");
    return;
  }
}
