LLVM  8.0.1
DWARFListTable.h
Go to the documentation of this file.
1 //===- DWARFListTable.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 LLVM_DEBUGINFO_DWARFLISTTABLE_H
11 #define LLVM_DEBUGINFO_DWARFLISTTABLE_H
12 
16 #include "llvm/Support/Errc.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/Format.h"
20 #include <cstdint>
21 #include <map>
22 #include <vector>
23 
24 namespace llvm {
25 
26 /// A base class for DWARF list entries, such as range or location list
27 /// entries.
29  /// The offset at which the entry is located in the section.
31  /// The DWARF encoding (DW_RLE_* or DW_LLE_*).
32  uint8_t EntryKind;
33  /// The index of the section this entry belongs to.
34  uint64_t SectionIndex;
35 };
36 
37 /// A base class for lists of entries that are extracted from a particular
38 /// section, such as range lists or location lists.
39 template <typename ListEntryType> class DWARFListType {
40  using EntryType = ListEntryType;
41  using ListEntries = std::vector<EntryType>;
42 
43 protected:
44  ListEntries Entries;
45 
46 public:
47  const ListEntries &getEntries() const { return Entries; }
48  bool empty() const { return Entries.empty(); }
49  void clear() { Entries.clear(); }
51  uint32_t *OffsetPtr, StringRef SectionName,
52  StringRef ListStringName);
53 };
54 
55 /// A class representing the header of a list table such as the range list
56 /// table in the .debug_rnglists section.
58  struct Header {
59  /// The total length of the entries for this table, not including the length
60  /// field itself.
61  uint32_t Length = 0;
62  /// The DWARF version number.
63  uint16_t Version;
64  /// The size in bytes of an address on the target architecture. For
65  /// segmented addressing, this is the size of the offset portion of the
66  /// address.
67  uint8_t AddrSize;
68  /// The size in bytes of a segment selector on the target architecture.
69  /// If the target system uses a flat address space, this value is 0.
70  uint8_t SegSize;
71  /// The number of offsets that follow the header before the range lists.
72  uint32_t OffsetEntryCount;
73  };
74 
75  Header HeaderData;
76  /// The offset table, which contains offsets to the individual list entries.
77  /// It is used by forms such as DW_FORM_rnglistx.
78  /// FIXME: Generate the table and use the appropriate forms.
79  std::vector<uint32_t> Offsets;
80  /// The table's format, either DWARF32 or DWARF64.
82  /// The offset at which the header (and hence the table) is located within
83  /// its section.
84  uint32_t HeaderOffset;
85  /// The name of the section the list is located in.
87  /// A characterization of the list for dumping purposes, e.g. "range" or
88  /// "location".
89  StringRef ListTypeString;
90 
91 public:
92  DWARFListTableHeader(StringRef SectionName, StringRef ListTypeString)
93  : SectionName(SectionName), ListTypeString(ListTypeString) {}
94 
95  void clear() {
96  HeaderData = {};
97  Offsets.clear();
98  }
99  uint32_t getHeaderOffset() const { return HeaderOffset; }
100  uint8_t getAddrSize() const { return HeaderData.AddrSize; }
101  uint32_t getLength() const { return HeaderData.Length; }
102  uint16_t getVersion() const { return HeaderData.Version; }
104  StringRef getListTypeString() const { return ListTypeString; }
105  dwarf::DwarfFormat getFormat() const { return Format; }
106 
107  void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
109  if (Index < Offsets.size())
110  return Offsets[Index];
111  return None;
112  }
113 
114  /// Extract the table header and the array of offsets.
116 
117  /// Returns the length of the table, including the length field, or 0 if the
118  /// length has not been determined (e.g. because the table has not yet been
119  /// parsed, or there was a problem in parsing).
120  uint32_t length() const;
121 };
122 
123 /// A class representing a table of lists as specified in the DWARF v5
124 /// standard for location lists and range lists. The table consists of a header
125 /// followed by an array of offsets into a DWARF section, followed by zero or
126 /// more list entries. The list entries are kept in a map where the keys are
127 /// the lists' section offsets.
128 template <typename DWARFListType> class DWARFListTableBase {
129  DWARFListTableHeader Header;
130  /// A mapping between file offsets and lists. It is used to find a particular
131  /// list based on an offset (obtained from DW_AT_ranges, for example).
132  std::map<uint32_t, DWARFListType> ListMap;
133  /// This string is displayed as a heading before the list is dumped
134  /// (e.g. "ranges:").
135  StringRef HeaderString;
136 
137 protected:
139  StringRef ListTypeString)
140  : Header(SectionName, ListTypeString), HeaderString(HeaderString) {}
141 
142 public:
143  void clear() {
144  Header.clear();
145  ListMap.clear();
146  }
147  /// Extract the table header and the array of offsets.
149  return Header.extract(Data, OffsetPtr);
150  }
151  /// Extract an entire table, including all list entries.
153  /// Look up a list based on a given offset. Extract it and enter it into the
154  /// list map if necessary.
156 
157  uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); }
158  uint8_t getAddrSize() const { return Header.getAddrSize(); }
159 
160  void dump(raw_ostream &OS,
162  LookupPooledAddress,
163  DIDumpOptions DumpOpts = {}) const;
164 
165  /// Return the contents of the offset entry designated by a given index.
167  return Header.getOffsetEntry(Index);
168  }
169  /// Return the size of the table header including the length but not including
170  /// the offsets. This is dependent on the table format, which is unambiguously
171  /// derived from parsing the table.
172  uint8_t getHeaderSize() const {
173  switch (Header.getFormat()) {
175  return 12;
177  return 20;
178  }
179  llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
180  }
181 
182  uint32_t length() { return Header.length(); }
183 };
184 
185 template <typename DWARFListType>
187  uint32_t *OffsetPtr) {
188  clear();
189  if (Error E = extractHeaderAndOffsets(Data, OffsetPtr))
190  return E;
191 
192  Data.setAddressSize(Header.getAddrSize());
193  uint32_t End = getHeaderOffset() + Header.length();
194  while (*OffsetPtr < End) {
195  DWARFListType CurrentList;
196  uint32_t Off = *OffsetPtr;
197  if (Error E = CurrentList.extract(Data, getHeaderOffset(), End, OffsetPtr,
198  Header.getSectionName(),
199  Header.getListTypeString()))
200  return E;
201  ListMap[Off] = CurrentList;
202  }
203 
204  assert(*OffsetPtr == End &&
205  "mismatch between expected length of table and length "
206  "of extracted data");
207  return Error::success();
208 }
209 
210 template <typename ListEntryType>
212  uint32_t HeaderOffset, uint32_t End,
213  uint32_t *OffsetPtr,
215  StringRef ListTypeString) {
216  if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
218  "invalid %s list offset 0x%" PRIx32,
219  ListTypeString.data(), *OffsetPtr);
220  Entries.clear();
221  while (*OffsetPtr < End) {
222  ListEntryType Entry;
223  if (Error E = Entry.extract(Data, End, OffsetPtr))
224  return E;
225  Entries.push_back(Entry);
226  if (Entry.isSentinel())
227  return Error::success();
228  }
230  "no end of list marker detected at end of %s table "
231  "starting at offset 0x%" PRIx32,
232  SectionName.data(), HeaderOffset);
233 }
234 
235 template <typename DWARFListType>
237  raw_ostream &OS,
239  LookupPooledAddress,
240  DIDumpOptions DumpOpts) const {
241  Header.dump(OS, DumpOpts);
242  OS << HeaderString << "\n";
243 
244  // Determine the length of the longest encoding string we have in the table,
245  // so we can align the output properly. We only need this in verbose mode.
246  size_t MaxEncodingStringLength = 0;
247  if (DumpOpts.Verbose) {
248  for (const auto &List : ListMap)
249  for (const auto &Entry : List.second.getEntries())
250  MaxEncodingStringLength =
251  std::max(MaxEncodingStringLength,
252  dwarf::RangeListEncodingString(Entry.EntryKind).size());
253  }
254 
255  uint64_t CurrentBase = 0;
256  for (const auto &List : ListMap)
257  for (const auto &Entry : List.second.getEntries())
258  Entry.dump(OS, getAddrSize(), MaxEncodingStringLength, CurrentBase,
259  DumpOpts, LookupPooledAddress);
260 }
261 
262 template <typename DWARFListType>
265  uint32_t Offset) {
266  auto Entry = ListMap.find(Offset);
267  if (Entry != ListMap.end())
268  return Entry->second;
269 
270  // Extract the list from the section and enter it into the list map.
272  uint32_t End = getHeaderOffset() + Header.length();
273  uint32_t StartingOffset = Offset;
274  if (Error E =
275  List.extract(Data, getHeaderOffset(), End, &Offset,
276  Header.getSectionName(), Header.getListTypeString()))
277  return std::move(E);
278  ListMap[StartingOffset] = List;
279  return List;
280 }
281 
282 } // end namespace llvm
283 
284 #endif // LLVM_DEBUGINFO_DWARFLISTTABLE_H
Optional< uint32_t > getOffsetEntry(uint32_t Index) const
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A class representing the header of a list table such as the range list table in the ...
const ListEntries & getEntries() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
DWARFListTableHeader(StringRef SectionName, StringRef ListTypeString)
dwarf::DwarfFormat getFormat() const
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:117
Expected< DWARFListType > findList(DWARFDataExtractor Data, uint32_t Offset)
Look up a list based on a given offset.
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1025
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract the table header and the array of offsets.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:66
A base class for DWARF list entries, such as range or location list entries.
uint8_t EntryKind
The DWARF encoding (DW_RLE_* or DW_LLE_*).
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
uint64_t SectionIndex
The index of the section this entry belongs to.
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:159
uint32_t getHeaderOffset() const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
uint16_t getVersion() const
uint32_t getHeaderOffset() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Optional< uint32_t > getOffsetEntry(uint32_t Index) const
Return the contents of the offset entry designated by a given index.
Error extract(DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End, uint32_t *OffsetPtr, StringRef SectionName, StringRef ListStringName)
StringRef RangeListEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:459
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
bool empty() const
DWARFListTableBase(StringRef SectionName, StringRef HeaderString, StringRef ListTypeString)
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
uint32_t Offset
The offset at which the entry is located in the section.
Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract the table header and the array of offsets.
void dump(raw_ostream &OS, llvm::function_ref< Optional< SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
void setAddressSize(uint8_t Size)
Set the address size for this extractor.
Definition: DataExtractor.h:61
This file contains constants used for implementing Dwarf debug support.
uint8_t getHeaderSize() const
Return the size of the table header including the length but not including the offsets.
StringRef getListTypeString() const
loop extract
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:212
const NodeList & List
Definition: RDFGraph.cpp:210
uint32_t length() const
Returns the length of the table, including the length field, or 0 if the length has not been determin...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract an entire table, including all list entries.
uint8_t getAddrSize() const
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
const char SectionName[]
Definition: AMDGPUPTNote.h:24
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
uint32_t getLength() const
StringRef getSectionName() const
const uint64_t Version
Definition: InstrProf.h:895
A base class for lists of entries that are extracted from a particular section, such as range lists o...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1164
A class representing a table of lists as specified in the DWARF v5 standard for location lists and ra...