LLVM  15.0.0git
DWARFDebugMacro.cpp
Go to the documentation of this file.
1 //===- DWARFDebugMacro.cpp ------------------------------------------------===//
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 
10 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/WithColor.h"
18 #include <cstdint>
19 
20 using namespace llvm;
21 using namespace dwarf;
22 
23 DwarfFormat DWARFDebugMacro::MacroHeader::getDwarfFormat() const {
24  return Flags & MACRO_OFFSET_SIZE ? DWARF64 : DWARF32;
25 }
26 
27 uint8_t DWARFDebugMacro::MacroHeader::getOffsetByteSize() const {
28  return getDwarfOffsetByteSize(getDwarfFormat());
29 }
30 
31 void DWARFDebugMacro::MacroHeader::dumpMacroHeader(raw_ostream &OS) const {
32  // FIXME: Add support for dumping opcode_operands_table
33  OS << format("macro header: version = 0x%04" PRIx16, Version)
34  << format(", flags = 0x%02" PRIx8, Flags)
35  << ", format = " << FormatString(getDwarfFormat());
36  if (Flags & MACRO_DEBUG_LINE_OFFSET)
37  OS << format(", debug_line_offset = 0x%0*" PRIx64, 2 * getOffsetByteSize(),
38  DebugLineOffset);
39  OS << "\n";
40 }
41 
43  unsigned IndLevel = 0;
44  for (const auto &Macros : MacroLists) {
45  OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
46  if (Macros.IsDebugMacro)
47  Macros.Header.dumpMacroHeader(OS);
48  for (const Entry &E : Macros.Macros) {
49  // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
50  // this check handles the case of corrupted ".debug_macinfo" section.
51  if (IndLevel > 0)
52  IndLevel -= (E.Type == DW_MACINFO_end_file);
53  // Print indentation.
54  for (unsigned I = 0; I < IndLevel; I++)
55  OS << " ";
56  IndLevel += (E.Type == DW_MACINFO_start_file);
57  // Based on which version we are handling choose appropriate macro forms.
58  if (Macros.IsDebugMacro)
60  << (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
61  : MacroString(E.Type));
62  else
64  switch (E.Type) {
65  default:
66  // Got a corrupted ".debug_macinfo/.debug_macro" section (invalid
67  // macinfo type).
68  break;
69  // debug_macro and debug_macinfo share some common encodings.
70  // DW_MACRO_define == DW_MACINFO_define
71  // DW_MACRO_undef == DW_MACINFO_undef
72  // DW_MACRO_start_file == DW_MACINFO_start_file
73  // DW_MACRO_end_file == DW_MACINFO_end_file
74  // For readability/uniformity we are using DW_MACRO_*.
75  //
76  // The GNU .debug_macro extension's entries have the same encoding
77  // as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
78  case DW_MACRO_define:
79  case DW_MACRO_undef:
80  case DW_MACRO_define_strp:
81  case DW_MACRO_undef_strp:
82  case DW_MACRO_define_strx:
83  case DW_MACRO_undef_strx:
84  OS << " - lineno: " << E.Line;
85  OS << " macro: " << E.MacroStr;
86  break;
87  case DW_MACRO_start_file:
88  OS << " - lineno: " << E.Line;
89  OS << " filenum: " << E.File;
90  break;
91  case DW_MACRO_import:
92  OS << format(" - import offset: 0x%0*" PRIx64,
93  2 * Macros.Header.getOffsetByteSize(), E.ImportOffset);
94  break;
95  case DW_MACRO_end_file:
96  break;
98  OS << " - constant: " << E.ExtConstant;
99  OS << " string: " << E.ExtStr;
100  break;
101  }
102  OS << "\n";
103  }
104  }
105 }
106 
107 Error DWARFDebugMacro::parseImpl(
109  Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
110  bool IsMacro) {
111  uint64_t Offset = 0;
112  MacroList *M = nullptr;
113  using MacroToUnitsMap = DenseMap<uint64_t, DWARFUnit *>;
114  MacroToUnitsMap MacroToUnits;
115  if (IsMacro && Data.isValidOffset(Offset)) {
116  // Keep a mapping from Macro contribution to CUs, this will
117  // be needed while retrieving macro from DW_MACRO_define_strx form.
118  for (const auto &U : *Units)
119  if (auto CUDIE = U->getUnitDIE())
120  // Skip units which does not contibutes to macro section.
121  if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
122  MacroToUnits.try_emplace(*MacroOffset, U.get());
123  }
124  while (Data.isValidOffset(Offset)) {
125  if (!M) {
126  MacroLists.emplace_back();
127  M = &MacroLists.back();
128  M->Offset = Offset;
129  M->IsDebugMacro = IsMacro;
130  if (IsMacro) {
131  auto Err = M->Header.parseMacroHeader(Data, &Offset);
132  if (Err)
133  return Err;
134  }
135  }
136  // A macro list entry consists of:
137  M->Macros.emplace_back();
138  Entry &E = M->Macros.back();
139  // 1. Macinfo type
140  E.Type = Data.getULEB128(&Offset);
141 
142  if (E.Type == 0) {
143  // Reached end of a ".debug_macinfo/debug_macro" section contribution.
144  M = nullptr;
145  continue;
146  }
147 
148  switch (E.Type) {
149  default:
150  // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
151  // Push the corrupted entry to the list and halt parsing.
152  E.Type = DW_MACINFO_invalid;
153  return Error::success();
154  // debug_macro and debug_macinfo share some common encodings.
155  // DW_MACRO_define == DW_MACINFO_define
156  // DW_MACRO_undef == DW_MACINFO_undef
157  // DW_MACRO_start_file == DW_MACINFO_start_file
158  // DW_MACRO_end_file == DW_MACINFO_end_file
159  // For readibility/uniformity we are using DW_MACRO_*.
160  case DW_MACRO_define:
161  case DW_MACRO_undef:
162  // 2. Source line
163  E.Line = Data.getULEB128(&Offset);
164  // 3. Macro string
165  E.MacroStr = Data.getCStr(&Offset);
166  break;
167  case DW_MACRO_define_strp:
168  case DW_MACRO_undef_strp: {
169  if (!IsMacro) {
170  // DW_MACRO_define_strp is a new form introduced in DWARFv5, it is
171  // not supported in debug_macinfo[.dwo] sections. Assume it as an
172  // invalid entry, push it and halt parsing.
173  E.Type = DW_MACINFO_invalid;
174  return Error::success();
175  }
176  uint64_t StrOffset = 0;
177  // 2. Source line
178  E.Line = Data.getULEB128(&Offset);
179  // 3. Macro string
180  StrOffset =
181  Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
182  assert(StringExtractor && "String Extractor not found");
183  E.MacroStr = StringExtractor->getCStr(&StrOffset);
184  break;
185  }
186  case DW_MACRO_define_strx:
187  case DW_MACRO_undef_strx: {
188  if (!IsMacro) {
189  // DW_MACRO_define_strx is a new form introduced in DWARFv5, it is
190  // not supported in debug_macinfo[.dwo] sections. Assume it as an
191  // invalid entry, push it and halt parsing.
192  E.Type = DW_MACINFO_invalid;
193  return Error::success();
194  }
195  E.Line = Data.getULEB128(&Offset);
196  auto MacroContributionOffset = MacroToUnits.find(M->Offset);
197  if (MacroContributionOffset == MacroToUnits.end())
199  "Macro contribution of the unit not found");
200  Expected<uint64_t> StrOffset =
201  MacroContributionOffset->second->getStringOffsetSectionItem(
202  Data.getULEB128(&Offset));
203  if (!StrOffset)
204  return StrOffset.takeError();
205  E.MacroStr =
206  MacroContributionOffset->second->getStringExtractor().getCStr(
207  &*StrOffset);
208  break;
209  }
210  case DW_MACRO_start_file:
211  // 2. Source line
212  E.Line = Data.getULEB128(&Offset);
213  // 3. Source file id
214  E.File = Data.getULEB128(&Offset);
215  break;
216  case DW_MACRO_end_file:
217  break;
218  case DW_MACRO_import:
219  E.ImportOffset =
220  Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
221  break;
223  // 2. Vendor extension constant
224  E.ExtConstant = Data.getULEB128(&Offset);
225  // 3. Vendor extension string
226  E.ExtStr = Data.getCStr(&Offset);
227  break;
228  }
229  }
230  return Error::success();
231 }
232 
233 Error DWARFDebugMacro::MacroHeader::parseMacroHeader(DWARFDataExtractor Data,
234  uint64_t *Offset) {
235  Version = Data.getU16(Offset);
236  uint8_t FlagData = Data.getU8(Offset);
237 
238  // FIXME: Add support for parsing opcode_operands_table
239  if (FlagData & MACRO_OPCODE_OPERANDS_TABLE)
241  "opcode_operands_table is not supported");
242  Flags = FlagData;
243  if (Flags & MACRO_DEBUG_LINE_OFFSET)
244  DebugLineOffset = Data.getUnsigned(Offset, getOffsetByteSize());
245  return Error::success();
246 }
DWARFFormValue.h
llvm::errc::invalid_argument
@ invalid_argument
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::dwarf::MacroString
StringRef MacroString(unsigned Encoding)
Definition: Dwarf.cpp:486
DWARFDebugMacro.h
llvm::DWARFDebugMacro::dump
void dump(raw_ostream &OS) const
Print the macro list found within the debug_macinfo/debug_macro section.
Definition: DWARFDebugMacro.cpp:42
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Errc.h
llvm::WithColor::get
raw_ostream & get()
Definition: WithColor.h:79
DenseMap.h
llvm::WithColor
An RAII object that temporarily switches an output stream to a specific color.
Definition: WithColor.h:53
llvm::Optional
Definition: APInt.h:33
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::dwarf::GnuMacroString
StringRef GnuMacroString(unsigned Encoding)
Definition: Dwarf.cpp:497
llvm::dwarf::DW_MACINFO_end_file
@ DW_MACINFO_end_file
Definition: Dwarf.h:389
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DWARFDie.h
llvm::dwarf::FormatString
StringRef FormatString(DwarfFormat Format)
Definition: Dwarf.cpp:790
llvm::dwarf::toSectionOffset
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition: DWARFFormValue.h:318
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1027
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:93
uint64_t
llvm::DenseMap
Definition: DenseMap.h:716
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::HighlightColor::Macro
@ Macro
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DataExtractor::getCStr
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
Definition: DataExtractor.h:129
Dwarf.h
llvm::errc::not_supported
@ not_supported
llvm::dwarf::DW_MACINFO_vendor_ext
@ DW_MACINFO_vendor_ext
Definition: Dwarf.h:390
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
WithColor.h
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::dwarf::DW_MACINFO_start_file
@ DW_MACINFO_start_file
Definition: Dwarf.h:388
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::dwarf::MacinfoString
StringRef MacinfoString(unsigned Encoding)
Definition: Dwarf.cpp:457
llvm::dwarf::DW_MACINFO_invalid
@ DW_MACINFO_invalid
Macinfo type for invalid results.
Definition: Dwarf.h:51
llvm::DenseMapBase::try_emplace
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:224
llvm::dwarf::DWARF64
@ DWARF64
Definition: Dwarf.h:93
raw_ostream.h
llvm::dwarf::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:640
llvm::dwarf::DWARF32
@ DWARF32
Definition: Dwarf.h:93
DWARFDataExtractor.h