summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2020-12-30 13:18:32 +0100
committerAndreas Kling <kling@serenityos.org>2020-12-30 15:00:17 +0100
commita28954a8827ab54128b416a50e6ff96a3dd1a078 (patch)
tree1a93d002689d8500fba0fcad6b9650df2f1d1f7f /Libraries
parent9227e66bb45afe530dd7115416d247835be5d3df (diff)
downloadserenity-a28954a8827ab54128b416a50e6ff96a3dd1a078.zip
LibELF+LibCoreDump: Add a ProcessInfo notes entry
This is a new NotesEntry type which contains information related to the coredump's process: - PID - executable path Having these in the coredump explicitly avoids having to parse them from the coredump filename and backtrace, respectively.
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibCoreDump/Reader.cpp38
-rw-r--r--Libraries/LibCoreDump/Reader.h2
-rw-r--r--Libraries/LibELF/CoreDump.h8
3 files changed, 39 insertions, 9 deletions
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<const ELF::Core::ProcessInfo*>(m_current);
+ m_current = reinterpret_cast<const ELF::Core::NotesEntry*>(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<const ELF::Core::ThreadInfo*>(m_current);
+ m_current = reinterpret_cast<const ELF::Core::NotesEntry*>(current + 1);
+ break;
+ }
+ case ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo: {
+ const auto* current = reinterpret_cast<const ELF::Core::MemoryRegionInfo*>(m_current);
+ m_current = reinterpret_cast<const ELF::Core::NotesEntry*>(current->region_name + strlen(current->region_name) + 1);
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
}
}
@@ -108,6 +118,16 @@ Optional<uint32_t> Reader::peek_memory(FlatPtr address) const
return *(const uint32_t*)(&region_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<const ELF::Core::ProcessInfo&>(*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<MappedFile>&&);
+ const ELF::Core::ProcessInfo& process_info() const;
+
template<typename Func>
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;