2020-05-04 12:14:39 +03:00
|
|
|
/*
|
2021-06-19 11:50:24 +03:00
|
|
|
* Copyright (c) 2020-2021, Itamar S. <itamar8910@gmail.com>
|
2020-05-04 12:14:39 +03:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-05-04 12:14:39 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
2020-05-28 20:40:53 +02:00
|
|
|
|
2021-06-18 14:15:01 +03:00
|
|
|
#include "AttributeValue.h"
|
2020-05-04 12:14:39 +03:00
|
|
|
#include "DwarfTypes.h"
|
|
|
|
|
#include <AK/ByteBuffer.h>
|
|
|
|
|
#include <AK/NonnullRefPtr.h>
|
2021-06-18 15:25:27 +03:00
|
|
|
#include <AK/RedBlackTree.h>
|
2020-05-04 12:14:39 +03:00
|
|
|
#include <AK/RefCounted.h>
|
2022-09-14 10:39:32 +02:00
|
|
|
#include <LibDebug/Dwarf/DIE.h>
|
2020-12-25 02:14:56 +01:00
|
|
|
#include <LibELF/Image.h>
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2020-08-25 04:33:07 +01:00
|
|
|
namespace Debug::Dwarf {
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2022-09-14 10:39:32 +02:00
|
|
|
class CompilationUnit;
|
|
|
|
|
|
2020-12-25 02:14:56 +01:00
|
|
|
class DwarfInfo {
|
2021-06-18 14:31:03 +03:00
|
|
|
AK_MAKE_NONCOPYABLE(DwarfInfo);
|
|
|
|
|
AK_MAKE_NONMOVABLE(DwarfInfo);
|
|
|
|
|
|
2020-05-04 12:14:39 +03:00
|
|
|
public:
|
2021-06-19 15:33:03 +03:00
|
|
|
explicit DwarfInfo(ELF::Image const&);
|
2022-09-14 10:39:32 +02:00
|
|
|
~DwarfInfo();
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2020-12-19 13:14:00 +01:00
|
|
|
ReadonlyBytes debug_info_data() const { return m_debug_info_data; }
|
|
|
|
|
ReadonlyBytes abbreviation_data() const { return m_abbreviation_data; }
|
|
|
|
|
ReadonlyBytes debug_strings_data() const { return m_debug_strings_data; }
|
2021-04-28 22:15:51 +02:00
|
|
|
ReadonlyBytes debug_line_strings_data() const { return m_debug_line_strings_data; }
|
2021-09-28 13:35:28 +03:00
|
|
|
ReadonlyBytes debug_range_lists_data() const { return m_debug_range_lists_data; }
|
2021-10-09 17:38:26 +02:00
|
|
|
ReadonlyBytes debug_str_offsets_data() const { return m_debug_str_offsets_data; }
|
|
|
|
|
ReadonlyBytes debug_addr_data() const { return m_debug_addr_data; }
|
2021-12-05 08:45:05 +01:00
|
|
|
ReadonlyBytes debug_ranges_data() const { return m_debug_ranges_data; }
|
2020-05-04 12:14:39 +03:00
|
|
|
|
|
|
|
|
template<typename Callback>
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<void> for_each_compilation_unit(Callback) const;
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<AttributeValue> get_attribute_value(AttributeDataForm form, ssize_t implicit_const_value,
|
2023-01-22 05:09:11 +01:00
|
|
|
SeekableStream& debug_info_stream, CompilationUnit const* unit = nullptr) const;
|
2021-04-28 20:12:21 +02:00
|
|
|
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<Optional<DIE>> get_die_at_address(FlatPtr) const;
|
2021-06-19 11:59:48 +03:00
|
|
|
|
2021-06-19 12:03:14 +03:00
|
|
|
// Note that even if there is a DIE at the given offset,
|
|
|
|
|
// but it does not exist in the DIE cache (because for example
|
|
|
|
|
// it does not contain an address range), then this function will not return it.
|
|
|
|
|
// To get any DIE object at a given offset in a compilation unit,
|
|
|
|
|
// use CompilationUnit::get_die_at_offset.
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<Optional<DIE>> get_cached_die_at_offset(FlatPtr) const;
|
2021-06-19 12:03:14 +03:00
|
|
|
|
2020-05-04 12:14:39 +03:00
|
|
|
private:
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<void> populate_compilation_units();
|
|
|
|
|
ErrorOr<void> build_cached_dies() const;
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2021-11-11 00:55:02 +01:00
|
|
|
ReadonlyBytes section_data(StringView section_name) const;
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2021-06-19 15:33:03 +03:00
|
|
|
ELF::Image const& m_elf;
|
2020-12-19 13:14:00 +01:00
|
|
|
ReadonlyBytes m_debug_info_data;
|
|
|
|
|
ReadonlyBytes m_abbreviation_data;
|
|
|
|
|
ReadonlyBytes m_debug_strings_data;
|
2021-06-18 15:25:27 +03:00
|
|
|
ReadonlyBytes m_debug_line_data;
|
2021-04-28 22:15:51 +02:00
|
|
|
ReadonlyBytes m_debug_line_strings_data;
|
2021-09-28 13:35:28 +03:00
|
|
|
ReadonlyBytes m_debug_range_lists_data;
|
2021-10-09 17:38:26 +02:00
|
|
|
ReadonlyBytes m_debug_str_offsets_data;
|
|
|
|
|
ReadonlyBytes m_debug_addr_data;
|
2021-12-05 08:45:05 +01:00
|
|
|
ReadonlyBytes m_debug_ranges_data;
|
2020-05-04 12:14:39 +03:00
|
|
|
|
2023-03-06 17:16:25 +01:00
|
|
|
Vector<NonnullOwnPtr<Dwarf::CompilationUnit>> m_compilation_units;
|
2021-06-19 11:50:24 +03:00
|
|
|
|
|
|
|
|
struct DIERange {
|
|
|
|
|
FlatPtr start_address { 0 };
|
|
|
|
|
FlatPtr end_address { 0 };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct DIEAndRange {
|
|
|
|
|
DIE die;
|
|
|
|
|
DIERange range;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using DIEStartAddress = FlatPtr;
|
|
|
|
|
|
|
|
|
|
mutable RedBlackTree<DIEStartAddress, DIEAndRange> m_cached_dies_by_range;
|
|
|
|
|
mutable RedBlackTree<FlatPtr, DIE> m_cached_dies_by_offset;
|
|
|
|
|
mutable bool m_built_cached_dies { false };
|
2020-05-04 12:14:39 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename Callback>
|
2023-01-22 00:32:08 +01:00
|
|
|
ErrorOr<void> DwarfInfo::for_each_compilation_unit(Callback callback) const
|
2020-05-04 12:14:39 +03:00
|
|
|
{
|
2022-04-01 20:58:27 +03:00
|
|
|
for (auto const& unit : m_compilation_units) {
|
2023-03-06 17:16:25 +01:00
|
|
|
TRY(callback(*unit));
|
2020-05-04 12:14:39 +03:00
|
|
|
}
|
2023-01-22 00:32:08 +01:00
|
|
|
return {};
|
2020-05-04 12:14:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|