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 "buffer.h" 29 #include "dwarf_abbrev.h" 30 #include "string_offset_table.h" 31 #include "string_table.h" 32 33 #include "berberis/base/macros.h" 34 35 namespace nogrod { 36 37 class DwarfDie final { 38 public: 39 DwarfDie(const DwarfCompilationUnitHeader* cu, 40 const DwarfDie* parent, 41 uint64_t offset, 42 uint16_t tag); 43 44 DwarfDie(const DwarfDie&) = delete; 45 const DwarfDie& operator=(const DwarfDie&) = delete; 46 47 void AddAttribute(DwarfAttribute* attribute); 48 void AddChild(const DwarfDie* child); 49 tag()50 [[nodiscard]] uint16_t tag() const { return tag_; } offset()51 [[nodiscard]] uint64_t offset() const { return offset_; } 52 compilation_unit_header()53 [[nodiscard]] const DwarfCompilationUnitHeader* compilation_unit_header() const { 54 return compilation_unit_header_; 55 } 56 parent()57 [[nodiscard]] const DwarfDie* parent() const { return parent_; } children()58 [[nodiscard]] const std::vector<const DwarfDie*>& children() const { return children_; } 59 60 [[nodiscard]] std::optional<std::string> GetStringAttribute(uint16_t attr_name) const; 61 [[nodiscard]] std::optional<uint64_t> GetUint64Attribute(uint16_t attr_name) const; 62 GetUint64AttributeOr(uint16_t attr_name,uint64_t default_value)63 [[nodiscard]] uint64_t GetUint64AttributeOr(uint16_t attr_name, uint64_t default_value) const { 64 return GetUint64Attribute(attr_name).value_or(default_value); 65 } 66 67 [[nodiscard]] bool GetBoolAttributeOr(uint16_t attr_name, bool default_value) const; 68 69 void ResolveAttributes(DwarfContext* context); 70 71 private: 72 const DwarfCompilationUnitHeader* compilation_unit_header_; 73 const DwarfDie* parent_; 74 uint64_t offset_; 75 uint16_t tag_; 76 std::vector<std::unique_ptr<DwarfAttribute>> attributes_; 77 std::vector<const DwarfDie*> children_; 78 }; 79 80 class DwarfCompilationUnit { 81 public: 82 DwarfCompilationUnit(uint64_t unit_offset, 83 uint64_t unit_length, 84 uint16_t version, 85 uint64_t abbrev_offset, 86 uint8_t address_size, 87 bool is_dwarf64); 88 89 DwarfCompilationUnit(const DwarfCompilationUnit&) = delete; 90 DwarfCompilationUnit& operator=(const DwarfCompilationUnit&) = delete; 91 DwarfCompilationUnit(DwarfCompilationUnit&&) = default; 92 DwarfCompilationUnit& operator=(DwarfCompilationUnit&&) = default; 93 94 void SetDie(const DwarfDie* die); 95 GetDie()96 [[nodiscard]] const DwarfDie* GetDie() const { return cu_die_; } 97 header()98 [[nodiscard]] const DwarfCompilationUnitHeader& header() const { return header_; } 99 100 private: 101 DwarfCompilationUnitHeader header_; 102 const DwarfDie* cu_die_; 103 }; 104 105 class DwarfInfo { 106 public: 107 DwarfInfo(Buffer<uint8_t> abbrev_buf_, 108 Buffer<uint8_t> info_buf_, 109 StringTable string_table, 110 std::optional<StringOffsetTable> string_offset_table); 111 112 DwarfInfo(const DwarfInfo&) = delete; 113 const DwarfInfo& operator=(const DwarfInfo&) = delete; 114 115 bool Parse(std::string* error_msg); 116 117 [[nodiscard]] std::vector<const DwarfDie*> FindDiesByName(const std::string& name) const; 118 [[nodiscard]] const DwarfDie* GetDieByOffset(uint64_t offset) const; 119 120 private: 121 Buffer<uint8_t> abbrev_buf_; 122 Buffer<uint8_t> info_buf_; 123 StringTable string_table_; 124 std::optional<StringOffsetTable> string_offset_table_; 125 126 std::vector<std::unique_ptr<DwarfCompilationUnit>> compilation_units_; 127 std::unordered_map<uint64_t, std::unique_ptr<DwarfDie>> die_offset_map_; 128 }; 129 130 } // namespace nogrod 131 #endif // NOGROD_DWARF_INFO_ 132