| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef NOGROD_DWARF_INFO_ |
| #define NOGROD_DWARF_INFO_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "dwarf_abbrev.h" |
| #include "string_offset_table.h" |
| #include "string_table.h" |
| |
| #include "berberis/base/macros.h" |
| |
| namespace nogrod { |
| |
| class DwarfDie final { |
| public: |
| DwarfDie(const DwarfCompilationUnitHeader* cu, |
| const DwarfDie* parent, |
| uint64_t offset, |
| uint16_t tag); |
| |
| DwarfDie(const DwarfDie&) = delete; |
| const DwarfDie& operator=(const DwarfDie&) = delete; |
| |
| void AddAttribute(DwarfAttribute* attribute); |
| void AddChild(const DwarfDie* child); |
| |
| [[nodiscard]] uint16_t tag() const { return tag_; } |
| [[nodiscard]] uint64_t offset() const { return offset_; } |
| |
| [[nodiscard]] const DwarfCompilationUnitHeader* compilation_unit_header() const { |
| return compilation_unit_header_; |
| } |
| |
| [[nodiscard]] const DwarfDie* parent() const { return parent_; } |
| [[nodiscard]] const std::vector<const DwarfDie*>& children() const { return children_; } |
| |
| [[nodiscard]] std::optional<std::string> GetStringAttribute(uint16_t attr_name) const; |
| [[nodiscard]] std::optional<uint64_t> GetUint64Attribute(uint16_t attr_name) const; |
| |
| [[nodiscard]] uint64_t GetUint64AttributeOr(uint16_t attr_name, uint64_t default_value) const { |
| return GetUint64Attribute(attr_name).value_or(default_value); |
| } |
| |
| [[nodiscard]] bool GetBoolAttributeOr(uint16_t attr_name, bool default_value) const; |
| |
| void ResolveAttributes(DwarfContext* context); |
| |
| private: |
| const DwarfCompilationUnitHeader* compilation_unit_header_; |
| const DwarfDie* parent_; |
| uint64_t offset_; |
| uint16_t tag_; |
| std::vector<std::unique_ptr<DwarfAttribute>> attributes_; |
| std::vector<const DwarfDie*> children_; |
| }; |
| |
| class DwarfCompilationUnit { |
| public: |
| DwarfCompilationUnit(uint64_t unit_offset, |
| uint64_t unit_length, |
| uint16_t version, |
| uint64_t abbrev_offset, |
| uint8_t address_size, |
| bool is_dwarf64); |
| |
| DwarfCompilationUnit(const DwarfCompilationUnit&) = delete; |
| DwarfCompilationUnit& operator=(const DwarfCompilationUnit&) = delete; |
| DwarfCompilationUnit(DwarfCompilationUnit&&) = default; |
| DwarfCompilationUnit& operator=(DwarfCompilationUnit&&) = default; |
| |
| void SetDie(const DwarfDie* die); |
| |
| [[nodiscard]] const DwarfDie* GetDie() const { return cu_die_; } |
| |
| [[nodiscard]] const DwarfCompilationUnitHeader& header() const { return header_; } |
| |
| private: |
| DwarfCompilationUnitHeader header_; |
| const DwarfDie* cu_die_; |
| }; |
| |
| class DwarfInfo { |
| public: |
| DwarfInfo(const uint8_t* abbrev, |
| size_t abbrev_size, |
| const uint8_t* info, |
| size_t info_size, |
| StringTable string_table, |
| std::optional<StringOffsetTable> string_offset_table); |
| |
| DwarfInfo(const DwarfInfo&) = delete; |
| const DwarfInfo& operator=(const DwarfInfo&) = delete; |
| |
| bool Parse(std::string* error_msg); |
| |
| [[nodiscard]] std::vector<const DwarfDie*> FindDiesByName(const std::string& name) const; |
| [[nodiscard]] const DwarfDie* GetDieByOffset(uint64_t offset) const; |
| |
| private: |
| const uint8_t* abbrev_; |
| size_t abbrev_size_; |
| const uint8_t* info_; |
| size_t info_size_; |
| StringTable string_table_; |
| std::optional<StringOffsetTable> string_offset_table_; |
| |
| std::vector<std::unique_ptr<DwarfCompilationUnit>> compilation_units_; |
| std::unordered_map<uint64_t, std::unique_ptr<DwarfDie>> die_offset_map_; |
| }; |
| |
| } // namespace nogrod |
| #endif // NOGROD_DWARF_INFO_ |