• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ABBREV_
18 #define NOGROD_DWARF_ABBREV_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <memory>
23 #include <optional>
24 #include <string>
25 #include <vector>
26 
27 #include <berberis/base/macros.h>
28 
29 #include "dwarf_context.h"
30 
31 namespace nogrod {
32 
33 class DwarfAttribute {
34  public:
35   explicit DwarfAttribute(uint32_t name);
36   virtual ~DwarfAttribute() = default;
37 
38   DwarfAttribute(const DwarfAttribute&) = delete;
39   const DwarfAttribute& operator=(const DwarfAttribute&) = delete;
40 
name()41   [[nodiscard]] uint32_t name() const { return name_; }
42   [[nodiscard]] virtual std::optional<std::string> StringValue() const = 0;
43   [[nodiscard]] virtual std::optional<uint64_t> Uint64Value() const = 0;
44   [[nodiscard]] virtual std::optional<bool> BoolValue() const = 0;
45 
46   // Some forms of attributes need to be resolved after reading entire abbrev
47   // The example are string attributes of form DW_FORM_strx? in compilation unit
48   // may come before DW_AT_str_offset_base and have undefined base offset at
49   // the time of reading. These need to be resolved after whole compilation unit
50   // is read.
51   virtual void Resolve(DwarfContext* context) = 0;
52 
53  private:
54   uint32_t name_;
55 };
56 
57 template <typename T>
58 class DwarfAttributeValue : public DwarfAttribute {
59  public:
DwarfAttributeValue(uint32_t name,T value)60   DwarfAttributeValue(uint32_t name, T value) : DwarfAttribute{name}, value_{std::move(value)} {}
61 
62   DwarfAttributeValue(const DwarfAttributeValue&) = delete;
63   const DwarfAttributeValue& operator=(const DwarfAttributeValue&) = delete;
64 
value()65   [[nodiscard]] const T& value() const { return value_; }
66   [[nodiscard]] std::optional<std::string> StringValue() const override;
67   [[nodiscard]] std::optional<uint64_t> Uint64Value() const override;
68   [[nodiscard]] std::optional<bool> BoolValue() const override;
69 
70   void Resolve(DwarfContext* context) override;
71 
72  private:
73   T value_;
74 };
75 
76 class DwarfStrXAttribute : public DwarfAttribute {
77  public:
DwarfStrXAttribute(uint32_t name,uint64_t index)78   DwarfStrXAttribute(uint32_t name, uint64_t index) : DwarfAttribute{name}, index_{index} {}
79 
80   [[nodiscard]] std::optional<std::string> StringValue() const override;
81 
Uint64Value()82   [[nodiscard]] std::optional<uint64_t> Uint64Value() const override { return std::nullopt; }
83 
BoolValue()84   [[nodiscard]] std::optional<bool> BoolValue() const override { return std::nullopt; }
85 
86   void Resolve(DwarfContext* context) override;
87 
88  private:
89   std::optional<std::string> string_;
90   uint64_t index_;
91 };
92 
93 class DwarfCompilationUnitHeader {
94  public:
95   DwarfCompilationUnitHeader(uint64_t unit_offset,
96                              uint64_t unit_length,
97                              uint16_t version,
98                              uint64_t abbrev_offset,
99                              uint8_t address_size,
100                              bool is_dwarf64);
101 
102   DwarfCompilationUnitHeader(const DwarfCompilationUnitHeader&) = delete;
103   const DwarfCompilationUnitHeader& operator=(const DwarfCompilationUnitHeader&) = delete;
104 
105   DwarfCompilationUnitHeader(DwarfCompilationUnitHeader&&) = default;
106   DwarfCompilationUnitHeader& operator=(DwarfCompilationUnitHeader&&) = default;
107 
unit_offset()108   [[nodiscard]] uint64_t unit_offset() const { return unit_offset_; }
unit_length()109   [[nodiscard]] uint64_t unit_length() const { return unit_length_; }
version()110   [[nodiscard]] uint16_t version() const { return version_; }
abbrev_offset()111   [[nodiscard]] uint64_t abbrev_offset() const { return abbrev_offset_; }
address_size()112   [[nodiscard]] uint8_t address_size() const { return address_size_; }
is_dwarf64()113   [[nodiscard]] bool is_dwarf64() const { return is_dwarf64_; }
114 
115  private:
116   uint64_t unit_offset_;
117   uint64_t unit_length_;
118   uint16_t version_;
119   uint64_t abbrev_offset_;
120   uint8_t address_size_;
121   bool is_dwarf64_;
122 };
123 
124 class DwarfAbbrevAttribute;
125 
126 class DwarfClass {
127  public:
128   static const DwarfClass* kAddress;
129   static const DwarfClass* kAddrptr;
130   static const DwarfClass* kBlock;
131   static const DwarfClass* kConstant;
132   static const DwarfClass* kExprloc;
133   static const DwarfClass* kFlag;
134   static const DwarfClass* kLineptr;
135   static const DwarfClass* kLoclist;
136   static const DwarfClass* kLoclistsptr;
137   static const DwarfClass* kMacptr;
138   static const DwarfClass* kRnglist;
139   static const DwarfClass* kRnglistsptr;
140   static const DwarfClass* kReference;
141   static const DwarfClass* kString;
142   static const DwarfClass* kStroffsetsptr;
143 
144   DwarfClass() = delete;
145   DwarfClass(const DwarfClass&) = delete;
146   DwarfClass& operator=(const DwarfClass&) = delete;
147   DwarfClass(DwarfClass&&) = delete;
148   DwarfClass& operator=(DwarfClass&&) = delete;
149 
150   virtual ~DwarfClass() = default;
151   [[nodiscard]] const char* name() const;
152   [[nodiscard]] virtual std::unique_ptr<DwarfAttribute> ReadAttribute(
153       const DwarfCompilationUnitHeader* cu,
154       const DwarfAbbrevAttribute* abbrev_attr,
155       DwarfContext* context,
156       std::string* error_msg) const = 0;
157 
158  protected:
159   explicit DwarfClass(const char* name);
160 
161  private:
162   const char* name_;
163 };
164 
165 class DwarfAbbrevAttribute {
166  public:
167   static std::unique_ptr<const DwarfAbbrevAttribute> CreateAbbrevAttribute(uint16_t version,
168                                                                            uint32_t name,
169                                                                            uint32_t form,
170                                                                            int64_t value,
171                                                                            std::string* error_msg);
172 
173   DwarfAbbrevAttribute();
174   DwarfAbbrevAttribute(uint32_t name, uint32_t form, int64_t value, const DwarfClass* dwarf_class);
175 
name()176   [[nodiscard]] uint32_t name() const { return name_; }
form()177   [[nodiscard]] uint32_t form() const { return form_; }
value()178   [[nodiscard]] int64_t value() const { return value_; }
dwarf_class()179   [[nodiscard]] const DwarfClass* dwarf_class() const { return dwarf_class_; }
180 
181  private:
182   uint32_t name_;
183   uint32_t form_;
184   int64_t value_;
185   const DwarfClass* dwarf_class_;
186 };
187 
188 class DwarfAbbrev {
189  public:
190   DwarfAbbrev();
191   DwarfAbbrev(uint64_t code, uint64_t tag, bool has_children);
192 
193   DwarfAbbrev(const DwarfAbbrev&) = delete;
194   const DwarfAbbrev& operator=(const DwarfAbbrev&) = delete;
195 
196   DwarfAbbrev(DwarfAbbrev&&) = default;
197   DwarfAbbrev& operator=(DwarfAbbrev&&) = default;
198 
199   void AddAttribute(std::unique_ptr<const DwarfAbbrevAttribute>&& abbrev_attribute);
200 
tag()201   [[nodiscard]] uint64_t tag() const { return tag_; }
code()202   [[nodiscard]] uint64_t code() const { return code_; }
has_children()203   [[nodiscard]] bool has_children() const { return has_children_; }
attributes()204   [[nodiscard]] const std::vector<std::unique_ptr<const DwarfAbbrevAttribute>>& attributes() const {
205     return attributes_;
206   }
207 
208  private:
209   uint64_t code_;
210   uint64_t tag_;
211   bool has_children_;
212   std::vector<std::unique_ptr<const DwarfAbbrevAttribute>> attributes_;
213 };
214 
215 }  // namespace nogrod
216 #endif  // NOGROD_DWARF_ABBREV_
217