|
@@ -6,6 +6,7 @@
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
+#include <AK/ByteReader.h>
|
|
|
#include <AK/HashMap.h>
|
|
|
#include <AK/Noncopyable.h>
|
|
|
#include <AK/OwnPtr.h>
|
|
@@ -15,6 +16,24 @@
|
|
|
|
|
|
namespace Coredump {
|
|
|
|
|
|
+struct MemoryRegionInfo {
|
|
|
+ ELF::Core::NotesEntryHeader header;
|
|
|
+ uint64_t region_start;
|
|
|
+ uint64_t region_end;
|
|
|
+ uint16_t program_header_index;
|
|
|
+ StringView region_name;
|
|
|
+
|
|
|
+ StringView object_name() const
|
|
|
+ {
|
|
|
+ if (region_name.contains("Loader.so"))
|
|
|
+ return "Loader.so"sv;
|
|
|
+ auto maybe_colon_index = region_name.find(':');
|
|
|
+ if (!maybe_colon_index.has_value())
|
|
|
+ return {};
|
|
|
+ return region_name.substring_view(0, *maybe_colon_index);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
class Reader {
|
|
|
AK_MAKE_NONCOPYABLE(Reader);
|
|
|
AK_MAKE_NONMOVABLE(Reader);
|
|
@@ -40,8 +59,8 @@ public:
|
|
|
const ELF::Image& image() const { return m_coredump_image; }
|
|
|
|
|
|
Optional<FlatPtr> peek_memory(FlatPtr address) const;
|
|
|
- ELF::Core::MemoryRegionInfo const* first_region_for_object(StringView object_name) const;
|
|
|
- const ELF::Core::MemoryRegionInfo* region_containing(FlatPtr address) const;
|
|
|
+ Optional<MemoryRegionInfo> first_region_for_object(StringView object_name) const;
|
|
|
+ Optional<MemoryRegionInfo> region_containing(FlatPtr address) const;
|
|
|
|
|
|
struct LibraryData {
|
|
|
String name;
|
|
@@ -104,7 +123,20 @@ void Reader::for_each_memory_region_info(Func func) const
|
|
|
for (; !it.at_end(); it.next()) {
|
|
|
if (it.type() != ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo)
|
|
|
continue;
|
|
|
- auto& memory_region_info = *bit_cast<const ELF::Core::MemoryRegionInfo*>(it.current());
|
|
|
+ ELF::Core::MemoryRegionInfo raw_memory_region_info;
|
|
|
+ ReadonlyBytes raw_data {
|
|
|
+ it.current(),
|
|
|
+ sizeof(raw_memory_region_info),
|
|
|
+ };
|
|
|
+ ByteReader::load(raw_data.data(), raw_memory_region_info);
|
|
|
+
|
|
|
+ MemoryRegionInfo memory_region_info {
|
|
|
+ raw_memory_region_info.header,
|
|
|
+ raw_memory_region_info.region_start,
|
|
|
+ raw_memory_region_info.region_end,
|
|
|
+ raw_memory_region_info.program_header_index,
|
|
|
+ { bit_cast<const char*>(raw_data.offset_pointer(raw_data.size())) },
|
|
|
+ };
|
|
|
IterationDecision decision = func(memory_region_info);
|
|
|
if (decision == IterationDecision::Break)
|
|
|
return;
|
|
@@ -118,7 +150,9 @@ void Reader::for_each_thread_info(Func func) const
|
|
|
for (; !it.at_end(); it.next()) {
|
|
|
if (it.type() != ELF::Core::NotesEntryHeader::Type::ThreadInfo)
|
|
|
continue;
|
|
|
- auto& thread_info = *bit_cast<const ELF::Core::ThreadInfo*>(it.current());
|
|
|
+ ELF::Core::ThreadInfo thread_info;
|
|
|
+ ByteReader::load(bit_cast<const u8*>(it.current()), thread_info);
|
|
|
+
|
|
|
IterationDecision decision = func(thread_info);
|
|
|
if (decision == IterationDecision::Break)
|
|
|
return;
|