diff --git a/Libraries/LibCoreDump/Reader.cpp b/Libraries/LibCoreDump/Reader.cpp index 7aae04fb8f..e1bdbeed37 100644 --- a/Libraries/LibCoreDump/Reader.cpp +++ b/Libraries/LibCoreDump/Reader.cpp @@ -66,7 +66,8 @@ Reader::NotesEntryIterator::NotesEntryIterator(const u8* notes_data) ELF::Core::NotesEntryHeader::Type Reader::NotesEntryIterator::type() const { - ASSERT(m_current->header.type == ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo + ASSERT(m_current->header.type == ELF::Core::NotesEntryHeader::Type::ProcessInfo + || m_current->header.type == ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo || m_current->header.type == ELF::Core::NotesEntryHeader::Type::ThreadInfo || m_current->header.type == ELF::Core::NotesEntryHeader::Type::Null); return m_current->header.type; @@ -80,15 +81,24 @@ const ELF::Core::NotesEntry* Reader::NotesEntryIterator::current() const void Reader::NotesEntryIterator::next() { ASSERT(!at_end()); - if (type() == ELF::Core::NotesEntryHeader::Type::ThreadInfo) { - const ELF::Core::ThreadInfo* current = (const ELF::Core::ThreadInfo*)m_current; - m_current = (const ELF::Core::NotesEntry*)(current + 1); - return; + switch (type()) { + case ELF::Core::NotesEntryHeader::Type::ProcessInfo: { + const auto* current = reinterpret_cast(m_current); + m_current = reinterpret_cast(current->executable_path + strlen(current->executable_path) + 1); + break; } - if (type() == ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo) { - const ELF::Core::MemoryRegionInfo* current = (const ELF::Core::MemoryRegionInfo*)m_current; - m_current = (const ELF::Core::NotesEntry*)(current->region_name + strlen(current->region_name) + 1); - return; + case ELF::Core::NotesEntryHeader::Type::ThreadInfo: { + const auto* current = reinterpret_cast(m_current); + m_current = reinterpret_cast(current + 1); + break; + } + case ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo: { + const auto* current = reinterpret_cast(m_current); + m_current = reinterpret_cast(current->region_name + strlen(current->region_name) + 1); + break; + } + default: + ASSERT_NOT_REACHED(); } } @@ -108,6 +118,16 @@ Optional Reader::peek_memory(FlatPtr address) const return *(const uint32_t*)(®ion_data[offset_in_region]); } +const ELF::Core::ProcessInfo& Reader::process_info() const +{ + for (NotesEntryIterator it((const u8*)m_coredump_image.program_header(m_notes_segment_index).raw_data()); !it.at_end(); it.next()) { + if (it.type() != ELF::Core::NotesEntryHeader::Type::ProcessInfo) + continue; + return reinterpret_cast(*it.current()); + } + ASSERT_NOT_REACHED(); +} + const ELF::Core::MemoryRegionInfo* Reader::region_containing(FlatPtr address) const { const ELF::Core::MemoryRegionInfo* ret = nullptr; diff --git a/Libraries/LibCoreDump/Reader.h b/Libraries/LibCoreDump/Reader.h index e754488b48..ee7dd82ed2 100644 --- a/Libraries/LibCoreDump/Reader.h +++ b/Libraries/LibCoreDump/Reader.h @@ -44,6 +44,8 @@ public: Reader(OwnPtr&&); + const ELF::Core::ProcessInfo& process_info() const; + template void for_each_memory_region_info(Func func) const; diff --git a/Libraries/LibELF/CoreDump.h b/Libraries/LibELF/CoreDump.h index 531f5eadde..3ff21d38bb 100644 --- a/Libraries/LibELF/CoreDump.h +++ b/Libraries/LibELF/CoreDump.h @@ -36,6 +36,7 @@ struct [[gnu::packed]] NotesEntryHeader { enum Type : u8 { Null = 0, // Terminates segment + ProcessInfo, ThreadInfo, MemoryRegionInfo, }; @@ -48,6 +49,13 @@ struct [[gnu::packed]] NotesEntry char data[]; }; +struct [[gnu::packed]] ProcessInfo +{ + NotesEntryHeader header; + int pid; + char executable_path[]; // Null terminated +}; + struct [[gnu::packed]] ThreadInfo { NotesEntryHeader header;