1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef NOGROD_DWARF_INFO_ 18 #define NOGROD_DWARF_INFO_ 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <memory> 23 #include <optional> 24 #include <string> 25 #include <unordered_map> 26 #include <vector> 27 28 #include "dwarf_abbrev.h" 29 #include "string_offset_table.h" 30 #include "string_table.h" 31 32 #include "berberis/base/macros.h" 33 34 namespace nogrod { 35 36 class DwarfDie final { 37 public: 38 DwarfDie(const DwarfCompilationUnitHeader* cu, 39 const DwarfDie* parent, 40 uint64_t offset, 41 uint16_t tag); 42 43 DwarfDie(const DwarfDie&) = delete; 44 const DwarfDie& operator=(const DwarfDie&) = delete; 45 46 void AddAttribute(DwarfAttribute* attribute); 47 void AddChild(const DwarfDie* child); 48 tag()49 [[nodiscard]] uint16_t tag() const { return tag_; } offset()50 [[nodiscard]] uint64_t offset() const { return offset_; } 51 compilation_unit_header()52 [[nodiscard]] const DwarfCompilationUnitHeader* compilation_unit_header() const { 53 return compilation_unit_header_; 54 } 55 parent()56 [[nodiscard]] const DwarfDie* parent() const { return parent_; } children()57 [[nodiscard]] const std::vector<const DwarfDie*>& children() const { return children_; } 58 59 [[nodiscard]] std::optional<std::string> GetStringAttribute(uint16_t attr_name) const; 60 [[nodiscard]] std::optional<uint64_t> GetUint64Attribute(uint16_t attr_name) const; 61 GetUint64AttributeOr(uint16_t attr_name,uint64_t default_value)62 [[nodiscard]] uint64_t GetUint64AttributeOr(uint16_t attr_name, uint64_t default_value) const { 63 return GetUint64Attribute(attr_name).value_or(default_value); 64 } 65 66 [[nodiscard]] bool GetBoolAttributeOr(uint16_t attr_name, bool default_value) const; 67 68 void ResolveAttributes(DwarfContext* context); 69 70 private: 71 const DwarfCompilationUnitHeader* compilation_unit_header_; 72 const DwarfDie* parent_; 73 uint64_t offset_; 74 uint16_t tag_; 75 std::vector<std::unique_ptr<DwarfAttribute>> attributes_; 76 std::vector<const DwarfDie*> children_; 77 }; 78 79 class DwarfCompilationUnit { 80 public: 81 DwarfCompilationUnit(uint64_t unit_offset, 82 uint64_t unit_length, 83 uint16_t version, 84 uint64_t abbrev_offset, 85 uint8_t address_size, 86 bool is_dwarf64); 87 88 DwarfCompilationUnit(const DwarfCompilationUnit&) = delete; 89 DwarfCompilationUnit& operator=(const DwarfCompilationUnit&) = delete; 90 DwarfCompilationUnit(DwarfCompilationUnit&&) = default; 91 DwarfCompilationUnit& operator=(DwarfCompilationUnit&&) = default; 92 93 void SetDie(const DwarfDie* die); 94 GetDie()95 [[nodiscard]] const DwarfDie* GetDie() const { return cu_die_; } 96 header()97 [[nodiscard]] const DwarfCompilationUnitHeader& header() const { return header_; } 98 99 private: 100 DwarfCompilationUnitHeader header_; 101 const DwarfDie* cu_die_; 102 }; 103 104 class DwarfInfo { 105 public: 106 DwarfInfo(const uint8_t* abbrev, 107 size_t abbrev_size, 108 const uint8_t* info, 109 size_t info_size, 110 StringTable string_table, 111 std::optional<StringOffsetTable> string_offset_table); 112 113 DwarfInfo(const DwarfInfo&) = delete; 114 const DwarfInfo& operator=(const DwarfInfo&) = delete; 115 116 bool Parse(std::string* error_msg); 117 118 [[nodiscard]] std::vector<const DwarfDie*> FindDiesByName(const std::string& name) const; 119 [[nodiscard]] const DwarfDie* GetDieByOffset(uint64_t offset) const; 120 121 private: 122 const uint8_t* abbrev_; 123 size_t abbrev_size_; 124 const uint8_t* info_; 125 size_t info_size_; 126 StringTable string_table_; 127 std::optional<StringOffsetTable> string_offset_table_; 128 129 std::vector<std::unique_ptr<DwarfCompilationUnit>> compilation_units_; 130 std::unordered_map<uint64_t, std::unique_ptr<DwarfDie>> die_offset_map_; 131 }; 132 133 } // namespace nogrod 134 #endif // NOGROD_DWARF_INFO_ 135