Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Line
Count
Source (jump to first uncovered line)
1
//===- DWARFContext.h -------------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===/
8
9
#ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
10
#define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
11
12
#include "llvm/ADT/MapVector.h"
13
#include "llvm/ADT/SmallString.h"
14
#include "llvm/ADT/SmallVector.h"
15
#include "llvm/ADT/StringMap.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/ADT/iterator_range.h"
18
#include "llvm/DebugInfo/DIContext.h"
19
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
20
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
21
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
22
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
23
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
24
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
25
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
26
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
27
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
28
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
29
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
30
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
31
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
32
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
33
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
34
#include "llvm/Object/Binary.h"
35
#include "llvm/Object/ObjectFile.h"
36
#include "llvm/Support/DataExtractor.h"
37
#include "llvm/Support/Error.h"
38
#include "llvm/Support/Host.h"
39
#include <cstdint>
40
#include <deque>
41
#include <map>
42
#include <memory>
43
44
namespace llvm {
45
46
class MCRegisterInfo;
47
class MemoryBuffer;
48
class raw_ostream;
49
50
/// Used as a return value for a error callback passed to DWARF context.
51
/// Callback should return Halt if client application wants to stop
52
/// object parsing, or should return Continue otherwise.
53
enum class ErrorPolicy { Halt, Continue };
54
55
/// DWARFContext
56
/// This data structure is the top level entity that deals with dwarf debug
57
/// information parsing. The actual data is supplied through DWARFObj.
58
class DWARFContext : public DIContext {
59
  DWARFUnitVector NormalUnits;
60
  std::unique_ptr<DWARFUnitIndex> CUIndex;
61
  std::unique_ptr<DWARFGdbIndex> GdbIndex;
62
  std::unique_ptr<DWARFUnitIndex> TUIndex;
63
  std::unique_ptr<DWARFDebugAbbrev> Abbrev;
64
  std::unique_ptr<DWARFDebugLoc> Loc;
65
  std::unique_ptr<DWARFDebugAranges> Aranges;
66
  std::unique_ptr<DWARFDebugLine> Line;
67
  std::unique_ptr<DWARFDebugFrame> DebugFrame;
68
  std::unique_ptr<DWARFDebugFrame> EHFrame;
69
  std::unique_ptr<DWARFDebugMacro> Macro;
70
  std::unique_ptr<DWARFDebugNames> Names;
71
  std::unique_ptr<AppleAcceleratorTable> AppleNames;
72
  std::unique_ptr<AppleAcceleratorTable> AppleTypes;
73
  std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
74
  std::unique_ptr<AppleAcceleratorTable> AppleObjC;
75
76
  DWARFUnitVector DWOUnits;
77
  std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
78
  std::unique_ptr<DWARFDebugLoclists> LocDWO;
79
80
  /// The maximum DWARF version of all units.
81
  unsigned MaxVersion = 0;
82
83
  struct DWOFile {
84
    object::OwningBinary<object::ObjectFile> File;
85
    std::unique_ptr<DWARFContext> Context;
86
  };
87
  StringMap<std::weak_ptr<DWOFile>> DWOFiles;
88
  std::weak_ptr<DWOFile> DWP;
89
  bool CheckedForDWP = false;
90
  std::string DWPName;
91
92
  std::unique_ptr<MCRegisterInfo> RegInfo;
93
94
  /// Read compile units from the debug_info section (if necessary)
95
  /// and type units from the debug_types sections (if necessary)
96
  /// and store them in NormalUnits.
97
  void parseNormalUnits();
98
99
  /// Read compile units from the debug_info.dwo section (if necessary)
100
  /// and type units from the debug_types.dwo section (if necessary)
101
  /// and store them in DWOUnits.
102
  /// If \p Lazy is true, set up to parse but don't actually parse them.
103
  enum { EagerParse = false, LazyParse = true };
104
  void parseDWOUnits(bool Lazy = false);
105
106
  std::unique_ptr<const DWARFObject> DObj;
107
108
public:
109
  DWARFContext(std::unique_ptr<const DWARFObject> DObj,
110
               std::string DWPName = "");
111
  ~DWARFContext();
112
113
  DWARFContext(DWARFContext &) = delete;
114
  DWARFContext &operator=(DWARFContext &) = delete;
115
116
91.2k
  const DWARFObject &getDWARFObj() const { return *DObj; }
117
118
  static bool classof(const DIContext *DICtx) {
119
    return DICtx->getKind() == CK_DWARF;
120
  }
121
122
  /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
123
  /// dump only the record at the specified offset.
124
  void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
125
            std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
126
127
11
  void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
128
11
    std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
129
11
    dump(OS, DumpOpts, DumpOffsets);
130
11
  }
131
132
  bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
133
134
  using unit_iterator_range = DWARFUnitVector::iterator_range;
135
136
  /// Get units from .debug_info in this context.
137
2.14k
  unit_iterator_range info_section_units() {
138
2.14k
    parseNormalUnits();
139
2.14k
    return unit_iterator_range(NormalUnits.begin(),
140
2.14k
                               NormalUnits.begin() +
141
2.14k
                                   NormalUnits.getNumInfoUnits());
142
2.14k
  }
143
144
  /// Get units from .debug_types in this context.
145
251
  unit_iterator_range types_section_units() {
146
251
    parseNormalUnits();
147
251
    return unit_iterator_range(
148
251
        NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
149
251
  }
150
151
  /// Get compile units in this context.
152
1.41k
  unit_iterator_range compile_units() { return info_section_units(); }
153
154
  /// Get type units in this context.
155
233
  unit_iterator_range type_units() { return types_section_units(); }
156
157
  /// Get all normal compile/type units in this context.
158
53
  unit_iterator_range normal_units() {
159
53
    parseNormalUnits();
160
53
    return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
161
53
  }
162
163
  /// Get units from .debug_info..dwo in the DWO context.
164
100
  unit_iterator_range dwo_info_section_units() {
165
100
    parseDWOUnits();
166
100
    return unit_iterator_range(DWOUnits.begin(),
167
100
                               DWOUnits.begin() + DWOUnits.getNumInfoUnits());
168
100
  }
169
170
  /// Get units from .debug_types.dwo in the DWO context.
171
28
  unit_iterator_range dwo_types_section_units() {
172
28
    parseDWOUnits();
173
28
    return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
174
28
                               DWOUnits.end());
175
28
  }
176
177
  /// Get compile units in the DWO context.
178
24
  unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
179
180
  /// Get type units in the DWO context.
181
18
  unit_iterator_range dwo_type_units() { return dwo_types_section_units(); }
182
183
  /// Get all units in the DWO context.
184
58
  unit_iterator_range dwo_units() {
185
58
    parseDWOUnits();
186
58
    return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
187
58
  }
188
189
  /// Get the number of compile units in this context.
190
516
  unsigned getNumCompileUnits() {
191
516
    parseNormalUnits();
192
516
    return NormalUnits.getNumInfoUnits();
193
516
  }
194
195
  /// Get the number of type units in this context.
196
213
  unsigned getNumTypeUnits() {
197
213
    parseNormalUnits();
198
213
    return NormalUnits.getNumTypesUnits();
199
213
  }
200
201
  /// Get the number of compile units in the DWO context.
202
583
  unsigned getNumDWOCompileUnits() {
203
583
    parseDWOUnits();
204
583
    return DWOUnits.getNumInfoUnits();
205
583
  }
206
207
  /// Get the number of type units in the DWO context.
208
221
  unsigned getNumDWOTypeUnits() {
209
221
    parseDWOUnits();
210
221
    return DWOUnits.getNumTypesUnits();
211
221
  }
212
213
  /// Get the unit at the specified index.
214
96
  DWARFUnit *getUnitAtIndex(unsigned index) {
215
96
    parseNormalUnits();
216
96
    return NormalUnits[index].get();
217
96
  }
218
219
  /// Get the unit at the specified index for the DWO units.
220
0
  DWARFUnit *getDWOUnitAtIndex(unsigned index) {
221
0
    parseDWOUnits();
222
0
    return DWOUnits[index].get();
223
0
  }
224
225
  DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
226
227
  /// Return the compile unit that includes an offset (relative to .debug_info).
228
  DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
229
230
  /// Get a DIE given an exact offset.
231
  DWARFDie getDIEForOffset(uint32_t Offset);
232
233
62
  unsigned getMaxVersion() {
234
62
    // Ensure info units have been parsed to discover MaxVersion
235
62
    info_section_units();
236
62
    return MaxVersion;
237
62
  }
238
239
28
  unsigned getMaxDWOVersion() {
240
28
    // Ensure DWO info units have been parsed to discover MaxVersion
241
28
    dwo_info_section_units();
242
28
    return MaxVersion;
243
28
  }
244
245
2.15k
  void setMaxVersionIfGreater(unsigned Version) {
246
2.15k
    if (Version > MaxVersion)
247
1.23k
      MaxVersion = Version;
248
2.15k
  }
249
250
  const DWARFUnitIndex &getCUIndex();
251
  DWARFGdbIndex &getGdbIndex();
252
  const DWARFUnitIndex &getTUIndex();
253
254
  /// Get a pointer to the parsed DebugAbbrev object.
255
  const DWARFDebugAbbrev *getDebugAbbrev();
256
257
  /// Get a pointer to the parsed DebugLoc object.
258
  const DWARFDebugLoc *getDebugLoc();
259
260
  /// Get a pointer to the parsed dwo abbreviations object.
261
  const DWARFDebugAbbrev *getDebugAbbrevDWO();
262
263
  /// Get a pointer to the parsed DebugLoc object.
264
  const DWARFDebugLoclists *getDebugLocDWO();
265
266
  /// Get a pointer to the parsed DebugAranges object.
267
  const DWARFDebugAranges *getDebugAranges();
268
269
  /// Get a pointer to the parsed frame information object.
270
  const DWARFDebugFrame *getDebugFrame();
271
272
  /// Get a pointer to the parsed eh frame information object.
273
  const DWARFDebugFrame *getEHFrame();
274
275
  /// Get a pointer to the parsed DebugMacro object.
276
  const DWARFDebugMacro *getDebugMacro();
277
278
  /// Get a reference to the parsed accelerator table object.
279
  const DWARFDebugNames &getDebugNames();
280
281
  /// Get a reference to the parsed accelerator table object.
282
  const AppleAcceleratorTable &getAppleNames();
283
284
  /// Get a reference to the parsed accelerator table object.
285
  const AppleAcceleratorTable &getAppleTypes();
286
287
  /// Get a reference to the parsed accelerator table object.
288
  const AppleAcceleratorTable &getAppleNamespaces();
289
290
  /// Get a reference to the parsed accelerator table object.
291
  const AppleAcceleratorTable &getAppleObjC();
292
293
  /// Get a pointer to a parsed line table corresponding to a compile unit.
294
  /// Report any parsing issues as warnings on stderr.
295
  const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
296
297
  /// Get a pointer to a parsed line table corresponding to a compile unit.
298
  /// Report any recoverable parsing problems using the callback.
299
  Expected<const DWARFDebugLine::LineTable *>
300
  getLineTableForUnit(DWARFUnit *U,
301
                      std::function<void(Error)> RecoverableErrorCallback);
302
303
2
  DataExtractor getStringExtractor() const {
304
2
    return DataExtractor(DObj->getStringSection(), false, 0);
305
2
  }
306
392
  DataExtractor getLineStringExtractor() const {
307
392
    return DataExtractor(DObj->getLineStringSection(), false, 0);
308
392
  }
309
310
  /// Wraps the returned DIEs for a given address.
311
  struct DIEsForAddress {
312
    DWARFCompileUnit *CompileUnit = nullptr;
313
    DWARFDie FunctionDIE;
314
    DWARFDie BlockDIE;
315
    explicit operator bool() const { return CompileUnit != nullptr; }
316
  };
317
318
  /// Get the compilation unit, the function DIE and lexical block DIE for the
319
  /// given address where applicable.
320
  /// TODO: change input parameter from "uint64_t Address"
321
  ///       into "SectionedAddress Address"
322
  DIEsForAddress getDIEsForAddress(uint64_t Address);
323
324
  DILineInfo getLineInfoForAddress(
325
      object::SectionedAddress Address,
326
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
327
  DILineInfoTable getLineInfoForAddressRange(
328
      object::SectionedAddress Address, uint64_t Size,
329
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
330
  DIInliningInfo getInliningInfoForAddress(
331
      object::SectionedAddress Address,
332
      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
333
334
  std::vector<DILocal>
335
  getLocalsForAddress(object::SectionedAddress Address) override;
336
337
8.66k
  bool isLittleEndian() const { return DObj->isLittleEndian(); }
338
2.30k
  static bool isSupportedVersion(unsigned version) {
339
2.30k
    return version == 2 || 
version == 31.75k
||
version == 41.71k
||
version == 5205
;
340
2.30k
  }
341
342
  std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
343
344
3.75k
  const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
345
346
  /// Function used to handle default error reporting policy. Prints a error
347
  /// message and returns Continue, so DWARF context ignores the error.
348
  static ErrorPolicy defaultErrorHandler(Error E);
349
  static std::unique_ptr<DWARFContext>
350
  create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
351
         function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
352
         std::string DWPName = "");
353
354
  static std::unique_ptr<DWARFContext>
355
  create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
356
         uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
357
358
  /// Loads register info for the architecture of the provided object file.
359
  /// Improves readability of dumped DWARF expressions. Requires the caller to
360
  /// have initialized the relevant target descriptions.
361
  Error loadRegisterInfo(const object::ObjectFile &Obj);
362
363
  /// Get address size from CUs.
364
  /// TODO: refactor compile_units() to make this const.
365
  uint8_t getCUAddrSize();
366
367
  /// Dump Error as warning message to stderr.
368
  static void dumpWarning(Error Warning);
369
370
156
  Triple::ArchType getArch() const {
371
156
    return getDWARFObj().getFile()->getArch();
372
156
  }
373
374
private:
375
  /// Return the compile unit which contains instruction with provided
376
  /// address.
377
  /// TODO: change input parameter from "uint64_t Address"
378
  ///       into "SectionedAddress Address"
379
  DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
380
  void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
381
                       std::vector<DILocal> &Result);
382
};
383
384
} // end namespace llvm
385
386
#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H