Error
ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
{
    Error error;
    size_t size;
    const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
    if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
    {
        error.SetErrorString("the mini dump contains no memory range information");
        return error;
    }

    if (list->SizeOfEntry < sizeof(MINIDUMP_MEMORY_INFO))
    {
        error.SetErrorString("the entries in the mini dump memory info list are smaller than expected");
        return error;
    }

    if (size < list->SizeOfHeader + list->SizeOfEntry * list->NumberOfEntries)
    {
        error.SetErrorString("the mini dump memory info list is incomplete");
        return error;
    }

    for (int i = 0; i < list->NumberOfEntries; ++i)
    {
        const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) +
                                                                          list->SizeOfHeader + i * list->SizeOfEntry);
        const auto head = entry->BaseAddress;
        const auto tail = head + entry->RegionSize;
        if (head <= load_addr && load_addr < tail)
        {
            info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            info.SetExecutable(IsPageExecutable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            return error;
        }
    }
    // Note that the memory info list doesn't seem to contain ranges in kernel space,
    // so if you're walking a stack that has kernel frames, the stack may appear
    // truncated.
    error.SetErrorString("address is not in a known range");
    return error;
}
Ejemplo n.º 2
0
Error
ProcessWinMiniDump::Impl::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
{
    Error error;
    size_t size;
    info.Clear();
    const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
    if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
    {
        error.SetErrorString("the mini dump contains no memory range information");
        return error;
    }

    if (list->SizeOfEntry < sizeof(MINIDUMP_MEMORY_INFO))
    {
        error.SetErrorString("the entries in the mini dump memory info list are smaller than expected");
        return error;
    }

    if (size < list->SizeOfHeader + list->SizeOfEntry * list->NumberOfEntries)
    {
        error.SetErrorString("the mini dump memory info list is incomplete");
        return error;
    }

    const MINIDUMP_MEMORY_INFO *next_entry = nullptr;

    for (int i = 0; i < list->NumberOfEntries; ++i)
    {
        const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) +
                                                                          list->SizeOfHeader + i * list->SizeOfEntry);
        const auto head = entry->BaseAddress;
        const auto tail = head + entry->RegionSize;
        if (head <= load_addr && load_addr < tail)
        {
            info.GetRange().SetRangeBase((entry->State != MEM_FREE) ? head : load_addr);
            info.GetRange().SetRangeEnd(tail);
            info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            info.SetExecutable(IsPageExecutable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            info.SetMapped((entry->State != MEM_FREE) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
            return error;
        }
        else if (head > load_addr && (next_entry == nullptr || head < next_entry->BaseAddress) )
        {
            // In case there is no region containing load_addr keep track of the nearest region
            // after load_addr so we can return the distance to it.
            next_entry = entry;
        }
    }

    // No containing region found. Create an unmapped region that extends to the next region
    // or LLDB_INVALID_ADDRESS
    info.GetRange().SetRangeBase(load_addr);
    info.GetRange().SetRangeEnd((next_entry != nullptr)?next_entry->BaseAddress:LLDB_INVALID_ADDRESS);
    info.SetReadable(MemoryRegionInfo::eNo);
    info.SetWritable(MemoryRegionInfo::eNo);
    info.SetExecutable(MemoryRegionInfo::eNo);
    info.SetMapped(MemoryRegionInfo::eNo);

    // Note that the memory info list doesn't seem to contain ranges in kernel space,
    // so if you're walking a stack that has kernel frames, the stack may appear
    // truncated.
    return error;
}