Esempio n. 1
0
Error
ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info)
{
    Error error;
    llvm::sys::ScopedLock lock(m_mutex);

    if (!m_session_data)
    {
        error.SetErrorString("GetMemoryRegionInfo called with no debugging session.");
        WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
        return error;
    }

    HostProcess process = m_session_data->m_debugger->GetProcess();
    lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
    if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
    {
        error.SetErrorString("GetMemoryRegionInfo called with an invalid target process.");
        WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
        return error;
    }

    WINLOG_IFALL(WINDOWS_LOG_MEMORY, "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);

    void *addr = reinterpret_cast<void *>(vm_addr);
    MEMORY_BASIC_INFORMATION mem_info = {0};
    SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
    if (result == 0)
    {
        error.SetError(::GetLastError(), eErrorTypeWin32);
        WINERR_IFALL(WINDOWS_LOG_MEMORY,
                     "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
                     error.GetError(), vm_addr);
        return error;
    }
    const bool readable = IsPageReadable(mem_info.Protect);
    const bool executable = IsPageExecutable(mem_info.Protect);
    const bool writable = IsPageWritable(mem_info.Protect);
    info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
    info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
    info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);

    error.SetError(::GetLastError(), eErrorTypeWin32);
    WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
                  BOOL_STR(readable), BOOL_STR(executable), BOOL_STR(writable));
    return error;
}
Esempio n. 2
0
ErrorCode Process::getMemoryRegionInfo(Address const &address,
                                       MemoryRegionInfo &info) {
  if (!address.valid())
    return kErrorInvalidArgument;

  info.clear();

  return kErrorNotFound;
}
Esempio n. 3
0
Error
ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info)
{
    Error error;
    llvm::sys::ScopedLock lock(m_mutex);

    if (!m_session_data)
    {
        error.SetErrorString("ProcessWindows::GetMemoryRegionInfo called with no debugging session.");
        return error;
    }

    HostProcess process = m_session_data->m_debugger->GetProcess();
    lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
    if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
    {
        error.SetErrorString("ProcessWindows::GetMemoryRegionInfo called with an invalid target process.");
        return error;
    }

    void *addr = reinterpret_cast<void *>(vm_addr);
    MEMORY_BASIC_INFORMATION mem_info = {0};
    SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
    if (result == 0)
    {
        error.SetError(::GetLastError(), eErrorTypeWin32);
        return error;
    }

    bool readable = !(mem_info.Protect & PAGE_NOACCESS);
    bool executable = mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
    bool writable = mem_info.Protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY);
    info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
    info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
    info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
    return error;
}
Esempio n. 4
0
Error
ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, MemoryRegionInfo &region_info)
{
    region_info.Clear();
    const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
    if (permission_entry)
    {
        if (permission_entry->Contains(load_addr))
        {
            region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
            const Flags permissions(permission_entry->data);
            region_info.SetReadable(permissions.Test(ePermissionsReadable) ? MemoryRegionInfo::eYes
                                                                           : MemoryRegionInfo::eNo);
            region_info.SetWritable(permissions.Test(ePermissionsWritable) ? MemoryRegionInfo::eYes
                                                                           : MemoryRegionInfo::eNo);
            region_info.SetExecutable(permissions.Test(ePermissionsExecutable) ? MemoryRegionInfo::eYes
                                                                               : MemoryRegionInfo::eNo);
        }
        else if (load_addr < permission_entry->GetRangeBase())
        {
            region_info.GetRange().SetRangeBase(load_addr);
            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
            region_info.SetReadable(MemoryRegionInfo::eNo);
            region_info.SetWritable(MemoryRegionInfo::eNo);
            region_info.SetExecutable(MemoryRegionInfo::eNo);
        }
        return Error();
    }

    return Error("invalid address");
}
Esempio n. 5
0
ErrorCode Process::getMemoryRegionInfo(Address const &address,
                                       MemoryRegionInfo &info) {
  if (!address.valid())
    return kErrorInvalidArgument;

  info.clear();

  FILE *fp = ProcFS::OpenFILE(_pid, "maps");
  if (fp == nullptr) {
    return Platform::TranslateError();
  }

  uint64_t last = 0;
  bool found = false;

  while (!found) {
    // Each line can contain one path and some additional addresses and
    // such, so PATH_MAX * 2 should be enough.
    char buf[PATH_MAX * 2];
    uint64_t start, end;
    char r, w, x, p;
    uint64_t offset;
    unsigned int devMinor, devMajor;
    uint64_t inode;
    int nread;

    if (std::fgets(buf, sizeof(buf), fp) == nullptr)
      break;

    if (std::sscanf(buf, "%" PRIx64 "-%" PRIx64 " %c%c%c%c %" PRIx64
                         " %x:%x %" PRIu64 " %n",
                    &start, &end, &r, &w, &x, &p, &offset, &devMinor, &devMajor,
                    &inode, &nread) != 10) {
      continue;
    }

    if (address >= last && address <= start) {
      //
      // A hole.
      //
      info.start = last;
      info.length = start - last;
      found = true;
    } else if (address >= start && address < end) {
      //
      // A defined region.
      //
      info.start = start;
      info.length = end - start;
      info.protection = 0;
      if (r == 'r')
        info.protection |= ds2::kProtectionRead;
      if (w == 'w')
        info.protection |= ds2::kProtectionWrite;
      if (x == 'x')
        info.protection |= ds2::kProtectionExecute;
      while (buf[nread] != '\0' && std::isspace(buf[nread]))
        ++nread;
      info.backingFile = buf + nread;
      info.backingFileOffset = offset;
      info.backingFileInode = inode;
      found = true;
    } else {
      last = end;
    }
  }
  std::fclose(fp);

  if (!found) {
    info.start = last;

    //
    // We need to obtain the end of the address space, first
    // we need to know if it's 64-bit.
    //
    ErrorCode error = updateInfo();
    if (error != kSuccess && error != kErrorAlreadyExist)
      return error;

    if (CPUTypeIs64Bit(_info.cpuType)) {
      info.length = std::numeric_limits<uint64_t>::max() - info.start;
    } else {
      info.length = std::numeric_limits<uint32_t>::max() - info.start;
    }
  }

  return kSuccess;
}