DWARFUnit.h revision 341825
1//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef SymbolFileDWARF_DWARFUnit_h_
11#define SymbolFileDWARF_DWARFUnit_h_
12
13#include "DWARFDIE.h"
14#include "DWARFDebugInfoEntry.h"
15#include "lldb/lldb-enumerations.h"
16#include "llvm/Support/RWMutex.h"
17#include <atomic>
18
19class DWARFUnit;
20class DWARFCompileUnit;
21class NameToDIE;
22class SymbolFileDWARF;
23class SymbolFileDWARFDwo;
24
25typedef std::shared_ptr<DWARFUnit> DWARFUnitSP;
26
27enum DWARFProducer {
28  eProducerInvalid = 0,
29  eProducerClang,
30  eProducerGCC,
31  eProducerLLVMGCC,
32  eProcucerOther
33};
34
35class DWARFUnit {
36  using die_iterator_range =
37      llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
38
39public:
40  virtual ~DWARFUnit();
41
42  void ExtractUnitDIEIfNeeded();
43  void ExtractDIEsIfNeeded();
44
45  class ScopedExtractDIEs {
46    DWARFUnit *m_cu;
47  public:
48    bool m_clear_dies = false;
49    ScopedExtractDIEs(DWARFUnit *cu);
50    ~ScopedExtractDIEs();
51    DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs);
52    ScopedExtractDIEs(ScopedExtractDIEs &&rhs);
53    ScopedExtractDIEs &operator=(ScopedExtractDIEs &&rhs);
54  };
55  ScopedExtractDIEs ExtractDIEsScoped();
56
57  DWARFDIE LookupAddress(const dw_addr_t address);
58  size_t AppendDIEsWithTag(const dw_tag_t tag,
59                           DWARFDIECollection &matching_dies,
60                           uint32_t depth = UINT32_MAX) const;
61  bool Verify(lldb_private::Stream *s) const;
62  virtual void Dump(lldb_private::Stream *s) const = 0;
63  //------------------------------------------------------------------
64  /// Get the data that contains the DIE information for this unit.
65  ///
66  /// This will return the correct bytes that contain the data for
67  /// this DWARFUnit. It could be .debug_info or .debug_types
68  /// depending on where the data for this unit originates.
69  ///
70  /// @return
71  ///   The correct data for the DIE information in this unit.
72  //------------------------------------------------------------------
73  virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
74  //------------------------------------------------------------------
75  /// Get the size in bytes of the compile unit header.
76  ///
77  /// @return
78  ///     Byte size of the compile unit header
79  //------------------------------------------------------------------
80  virtual uint32_t GetHeaderByteSize() const = 0;
81  // Offset of the initial length field.
82  dw_offset_t GetOffset() const { return m_offset; }
83  lldb::user_id_t GetID() const;
84  //------------------------------------------------------------------
85  /// Get the size in bytes of the length field in the header.
86  ///
87  /// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4
88  /// are 0xFFFFFFFF followed by the actual 64 bit length.
89  ///
90  /// @return
91  ///     Byte size of the compile unit header length field
92  //------------------------------------------------------------------
93  size_t GetLengthByteSize() const { return IsDWARF64() ? 12 : 4; }
94
95  bool ContainsDIEOffset(dw_offset_t die_offset) const {
96    return die_offset >= GetFirstDIEOffset() &&
97           die_offset < GetNextCompileUnitOffset();
98  }
99  dw_offset_t GetFirstDIEOffset() const {
100    return m_offset + GetHeaderByteSize();
101  }
102  dw_offset_t GetNextCompileUnitOffset() const;
103  // Size of the CU data (without initial length and without header).
104  size_t GetDebugInfoSize() const;
105  // Size of the CU data incl. header but without initial length.
106  uint32_t GetLength() const { return m_length; }
107  uint16_t GetVersion() const { return m_version; }
108  const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
109  dw_offset_t GetAbbrevOffset() const;
110  uint8_t GetAddressByteSize() const { return m_addr_size; }
111  dw_addr_t GetBaseAddress() const { return m_base_addr; }
112  dw_addr_t GetAddrBase() const { return m_addr_base; }
113  dw_addr_t GetRangesBase() const { return m_ranges_base; }
114  void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base,
115                   dw_offset_t base_obj_offset);
116  void BuildAddressRangeTable(SymbolFileDWARF *dwarf,
117                              DWARFDebugAranges *debug_aranges);
118
119  lldb::ByteOrder GetByteOrder() const;
120
121  lldb_private::TypeSystem *GetTypeSystem();
122
123  const DWARFDebugAranges &GetFunctionAranges();
124
125  DWARFFormValue::FixedFormSizes GetFixedFormSizes();
126
127  void SetBaseAddress(dw_addr_t base_addr);
128
129  DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
130
131  DWARFDIE DIE() { return DWARFDIE(this, DIEPtr()); }
132
133  DWARFDIE GetDIE(dw_offset_t die_offset);
134
135  static uint8_t GetAddressByteSize(const DWARFUnit *cu);
136
137  static bool IsDWARF64(const DWARFUnit *cu);
138
139  static uint8_t GetDefaultAddressSize();
140
141  void *GetUserData() const;
142
143  void SetUserData(void *d);
144
145  bool Supports_DW_AT_APPLE_objc_complete_type();
146
147  bool DW_AT_decl_file_attributes_are_invalid();
148
149  bool Supports_unnamed_objc_bitfields();
150
151  SymbolFileDWARF *GetSymbolFileDWARF() const;
152
153  DWARFProducer GetProducer();
154
155  uint32_t GetProducerVersionMajor();
156
157  uint32_t GetProducerVersionMinor();
158
159  uint32_t GetProducerVersionUpdate();
160
161  static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
162
163  lldb::LanguageType GetLanguageType();
164
165  bool IsDWARF64() const { return m_is_dwarf64; }
166
167  bool GetIsOptimized();
168
169  SymbolFileDWARFDwo *GetDwoSymbolFile() const;
170
171  dw_offset_t GetBaseObjOffset() const;
172
173  die_iterator_range dies() {
174    ExtractDIEsIfNeeded();
175    return die_iterator_range(m_die_array.begin(), m_die_array.end());
176  }
177
178protected:
179  DWARFUnit(SymbolFileDWARF *dwarf);
180
181  SymbolFileDWARF *m_dwarf = nullptr;
182  std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
183  const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
184  void *m_user_data = nullptr;
185  // The compile unit debug information entry item
186  DWARFDebugInfoEntry::collection m_die_array;
187  mutable llvm::sys::RWMutex m_die_array_mutex;
188  // It is used for tracking of ScopedExtractDIEs instances.
189  mutable llvm::sys::RWMutex m_die_array_scoped_mutex;
190  // ScopedExtractDIEs instances should not call ClearDIEsRWLocked()
191  // as someone called ExtractDIEsIfNeeded().
192  std::atomic<bool> m_cancel_scopes;
193  // GetUnitDIEPtrOnly() needs to return pointer to the first DIE.
194  // But the first element of m_die_array after ExtractUnitDIEIfNeeded()
195  // would possibly move in memory after later ExtractDIEsIfNeeded().
196  DWARFDebugInfoEntry m_first_die;
197  llvm::sys::RWMutex m_first_die_mutex;
198  // A table similar to the .debug_aranges table, but this one points to the
199  // exact DW_TAG_subprogram DIEs
200  std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap;
201  dw_addr_t m_base_addr = 0;
202  dw_offset_t m_length = 0;
203  uint16_t m_version = 0;
204  uint8_t m_addr_size = 0;
205  DWARFProducer m_producer = eProducerInvalid;
206  uint32_t m_producer_version_major = 0;
207  uint32_t m_producer_version_minor = 0;
208  uint32_t m_producer_version_update = 0;
209  lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
210  bool m_is_dwarf64 = false;
211  lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
212  dw_addr_t m_addr_base = 0;   // Value of DW_AT_addr_base
213  dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
214  // If this is a dwo compile unit this is the offset of the base compile unit
215  // in the main object file
216  dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
217
218  // Offset of the initial length field.
219  dw_offset_t m_offset;
220
221private:
222  void ParseProducerInfo();
223  void ExtractDIEsRWLocked();
224  void ClearDIEsRWLocked();
225
226  // Get the DWARF unit DWARF debug informration entry. Parse the single DIE
227  // if needed.
228  const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() {
229    ExtractUnitDIEIfNeeded();
230    // m_first_die_mutex is not required as m_first_die is never cleared.
231    if (!m_first_die)
232      return NULL;
233    return &m_first_die;
234  }
235
236  // Get all DWARF debug informration entries. Parse all DIEs if needed.
237  const DWARFDebugInfoEntry *DIEPtr() {
238    ExtractDIEsIfNeeded();
239    if (m_die_array.empty())
240      return NULL;
241    return &m_die_array[0];
242  }
243
244  void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
245  void ExtractDIEsEndCheck(lldb::offset_t offset) const;
246
247  DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
248};
249
250#endif // SymbolFileDWARF_DWARFUnit_h_
251