Reader.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/HashMap.h>
  8. #include <AK/MappedFile.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/OwnPtr.h>
  11. #include <LibELF/Core.h>
  12. #include <LibELF/Image.h>
  13. namespace Coredump {
  14. class Reader {
  15. AK_MAKE_NONCOPYABLE(Reader);
  16. AK_MAKE_NONMOVABLE(Reader);
  17. public:
  18. static OwnPtr<Reader> create(const String&);
  19. ~Reader();
  20. template<typename Func>
  21. void for_each_memory_region_info(Func func) const;
  22. template<typename Func>
  23. void for_each_thread_info(Func func) const;
  24. const ELF::Image& image() const { return m_coredump_image; }
  25. Optional<FlatPtr> peek_memory(FlatPtr address) const;
  26. ELF::Core::MemoryRegionInfo const* first_region_for_object(StringView object_name) const;
  27. const ELF::Core::MemoryRegionInfo* region_containing(FlatPtr address) const;
  28. struct LibraryData {
  29. String name;
  30. FlatPtr base_address { 0 };
  31. NonnullRefPtr<MappedFile> file;
  32. ELF::Image lib_elf;
  33. };
  34. const LibraryData* library_containing(FlatPtr address) const;
  35. int process_pid() const;
  36. u8 process_termination_signal() const;
  37. String process_executable_path() const;
  38. Vector<String> process_arguments() const;
  39. Vector<String> process_environment() const;
  40. HashMap<String, String> metadata() const;
  41. private:
  42. Reader(ReadonlyBytes);
  43. static ByteBuffer decompress_coredump(const ReadonlyBytes&);
  44. class NotesEntryIterator {
  45. public:
  46. NotesEntryIterator(const u8* notes_data);
  47. ELF::Core::NotesEntryHeader::Type type() const;
  48. const ELF::Core::NotesEntry* current() const;
  49. void next();
  50. bool at_end() const;
  51. private:
  52. const ELF::Core::NotesEntry* m_current { nullptr };
  53. const u8* start { nullptr };
  54. };
  55. // Private as we don't need anyone poking around in this JsonObject
  56. // manually - we know very well what should be included and expose that
  57. // as getters with the appropriate (non-JsonValue) types.
  58. const JsonObject process_info() const;
  59. ByteBuffer m_coredump_buffer;
  60. ELF::Image m_coredump_image;
  61. ssize_t m_notes_segment_index { -1 };
  62. };
  63. template<typename Func>
  64. void Reader::for_each_memory_region_info(Func func) const
  65. {
  66. for (NotesEntryIterator it((const u8*)m_coredump_image.program_header(m_notes_segment_index).raw_data()); !it.at_end(); it.next()) {
  67. if (it.type() != ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo)
  68. continue;
  69. auto& memory_region_info = reinterpret_cast<const ELF::Core::MemoryRegionInfo&>(*it.current());
  70. IterationDecision decision = func(memory_region_info);
  71. if (decision == IterationDecision::Break)
  72. return;
  73. }
  74. }
  75. template<typename Func>
  76. void Reader::for_each_thread_info(Func func) const
  77. {
  78. for (NotesEntryIterator it((const u8*)m_coredump_image.program_header(m_notes_segment_index).raw_data()); !it.at_end(); it.next()) {
  79. if (it.type() != ELF::Core::NotesEntryHeader::Type::ThreadInfo)
  80. continue;
  81. auto& thread_info = reinterpret_cast<const ELF::Core::ThreadInfo&>(*it.current());
  82. IterationDecision decision = func(thread_info);
  83. if (decision == IterationDecision::Break)
  84. return;
  85. }
  86. }
  87. }