LLVM  14.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 
13 #include "llvm/Support/WithColor.h"
15 #include <cstdint>
16 
17 using namespace llvm;
18 using namespace dwarf;
19 
20 DwarfFormat DWARFDebugMacro::MacroHeader::getDwarfFormat() const {
21  return Flags & MACRO_OFFSET_SIZE ? DWARF64 : DWARF32;
22 }
23 
24 uint8_t DWARFDebugMacro::MacroHeader::getOffsetByteSize() const {
25  return getDwarfOffsetByteSize(getDwarfFormat());
26 }
27 
28 void DWARFDebugMacro::MacroHeader::dumpMacroHeader(raw_ostream &OS) const {
29  // FIXME: Add support for dumping opcode_operands_table
30  OS << format("macro header: version = 0x%04" PRIx16, Version)
31  << format(", flags = 0x%02" PRIx8, Flags)
32  << ", format = " << FormatString(getDwarfFormat());
33  if (Flags & MACRO_DEBUG_LINE_OFFSET)
34  OS << format(", debug_line_offset = 0x%0*" PRIx64, 2 * getOffsetByteSize(),
35  DebugLineOffset);
36  OS << "\n";
37 }
38 
40  unsigned IndLevel = 0;
41  for (const auto &Macros : MacroLists) {
42  OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
43  if (Macros.IsDebugMacro)
44  Macros.Header.dumpMacroHeader(OS);
45  for (const Entry &E : Macros.Macros) {
46  // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
47  // this check handles the case of corrupted ".debug_macinfo" section.
48  if (IndLevel > 0)
49  IndLevel -= (E.Type == DW_MACINFO_end_file);
50  // Print indentation.
51  for (unsigned I = 0; I < IndLevel; I++)
52  OS << " ";
53  IndLevel += (E.Type == DW_MACINFO_start_file);
54  // Based on which version we are handling choose appropriate macro forms.
55  if (Macros.IsDebugMacro)
57  << (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
58  : MacroString(E.Type));
59  else
61  switch (E.Type) {
62  default:
63  // Got a corrupted ".debug_macinfo/.debug_macro" section (invalid
64  // macinfo type).
65  break;
66  // debug_macro and debug_macinfo share some common encodings.
67  // DW_MACRO_define == DW_MACINFO_define
68  // DW_MACRO_undef == DW_MACINFO_undef
69  // DW_MACRO_start_file == DW_MACINFO_start_file
70  // DW_MACRO_end_file == DW_MACINFO_end_file
71  // For readability/uniformity we are using DW_MACRO_*.
72  //
73  // The GNU .debug_macro extension's entries have the same encoding
74  // as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
75  case DW_MACRO_define:
76  case DW_MACRO_undef:
77  case DW_MACRO_define_strp:
78  case DW_MACRO_undef_strp:
79  case DW_MACRO_define_strx:
80  case DW_MACRO_undef_strx:
81  OS << " - lineno: " << E.Line;
82  OS << " macro: " << E.MacroStr;
83  break;
84  case DW_MACRO_start_file:
85  OS << " - lineno: " << E.Line;
86  OS << " filenum: " << E.File;
87  break;
88  case DW_MACRO_import:
89  OS << format(" - import offset: 0x%0*" PRIx64,
90  2 * Macros.Header.getOffsetByteSize(), E.ImportOffset);
91  break;
92  case DW_MACRO_end_file:
93  break;
95  OS << " - constant: " << E.ExtConstant;
96  OS << " string: " << E.ExtStr;
97  break;
98  }
99  OS << "\n";
100  }
101  }
102 }
103 
104 Error DWARFDebugMacro::parseImpl(
106  Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
107  bool IsMacro) {
108  uint64_t Offset = 0;
109  MacroList *M = nullptr;
110  using MacroToUnitsMap = DenseMap<uint64_t, DWARFUnit *>;
111  MacroToUnitsMap MacroToUnits;
112  if (IsMacro && Data.isValidOffset(Offset)) {
113  // Keep a mapping from Macro contribution to CUs, this will
114  // be needed while retrieving macro from DW_MACRO_define_strx form.
115  for (const auto &U : Units.getValue())
116  if (auto CUDIE = U->getUnitDIE())
117  // Skip units which does not contibutes to macro section.
118  if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
119  MacroToUnits.try_emplace(*MacroOffset, U.get());
120  }
121  while (Data.isValidOffset(Offset)) {
122  if (!M) {
123  MacroLists.emplace_back();
124  M = &MacroLists.back();
125  M->Offset = Offset;
126  M->IsDebugMacro = IsMacro;
127  if (IsMacro) {
128  auto Err = M->Header.parseMacroHeader(Data, &Offset);
129  if (Err)
130  return Err;
131  }
132  }
133  // A macro list entry consists of:
134  M->Macros.emplace_back();
135  Entry &E = M->Macros.back();
136  // 1. Macinfo type
137  E.Type = Data.getULEB128(&Offset);
138 
139  if (E.Type == 0) {
140  // Reached end of a ".debug_macinfo/debug_macro" section contribution.
141  M = nullptr;
142  continue;
143  }
144 
145  switch (E.Type) {
146  default:
147  // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
148  // Push the corrupted entry to the list and halt parsing.
149  E.Type = DW_MACINFO_invalid;
150  return Error::success();
151  // debug_macro and debug_macinfo share some common encodings.
152  // DW_MACRO_define == DW_MACINFO_define
153  // DW_MACRO_undef == DW_MACINFO_undef
154  // DW_MACRO_start_file == DW_MACINFO_start_file
155  // DW_MACRO_end_file == DW_MACINFO_end_file
156  // For readibility/uniformity we are using DW_MACRO_*.
157  case DW_MACRO_define:
158  case DW_MACRO_undef:
159  // 2. Source line
160  E.Line = Data.getULEB128(&Offset);
161  // 3. Macro string
162  E.MacroStr = Data.getCStr(&Offset);
163  break;
164  case DW_MACRO_define_strp:
165  case DW_MACRO_undef_strp: {
166  if (!IsMacro) {
167  // DW_MACRO_define_strp is a new form introduced in DWARFv5, it is
168  // not supported in debug_macinfo[.dwo] sections. Assume it as an
169  // invalid entry, push it and halt parsing.
170  E.Type = DW_MACINFO_invalid;
171  return Error::success();
172  }
173  uint64_t StrOffset = 0;
174  // 2. Source line
175  E.Line = Data.getULEB128(&Offset);
176  // 3. Macro string
177  StrOffset =
178  Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
179  assert(StringExtractor && "String Extractor not found");
180  E.MacroStr = StringExtractor->getCStr(&StrOffset);
181  break;
182  }
183  case DW_MACRO_define_strx:
184  case DW_MACRO_undef_strx: {
185  if (!IsMacro) {
186  // DW_MACRO_define_strx is a new form introduced in DWARFv5, it is
187  // not supported in debug_macinfo[.dwo] sections. Assume it as an
188  // invalid entry, push it and halt parsing.
189  E.Type = DW_MACINFO_invalid;
190  return Error::success();
191  }
192  E.Line = Data.getULEB128(&Offset);
193  auto MacroContributionOffset = MacroToUnits.find(M->Offset);
194  if (MacroContributionOffset == MacroToUnits.end())
196  "Macro contribution of the unit not found");
197  Expected<uint64_t> StrOffset =
198  MacroContributionOffset->second->getStringOffsetSectionItem(
199  Data.getULEB128(&Offset));
200  if (!StrOffset)
201  return StrOffset.takeError();
202  E.MacroStr =
203  MacroContributionOffset->second->getStringExtractor().getCStr(
204  &*StrOffset);
205  break;
206  }
207  case DW_MACRO_start_file:
208  // 2. Source line
209  E.Line = Data.getULEB128(&Offset);
210  // 3. Source file id
211  E.File = Data.getULEB128(&Offset);
212  break;
213  case DW_MACRO_end_file:
214  break;
215  case DW_MACRO_import:
216  E.ImportOffset =
217  Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
218  break;
220  // 2. Vendor extension constant
221  E.ExtConstant = Data.getULEB128(&Offset);
222  // 3. Vendor extension string
223  E.ExtStr = Data.getCStr(&Offset);
224  break;
225  }
226  }
227  return Error::success();
228 }
229 
230 Error DWARFDebugMacro::MacroHeader::parseMacroHeader(DWARFDataExtractor Data,
231  uint64_t *Offset) {
232  Version = Data.getU16(Offset);
233  uint8_t FlagData = Data.getU8(Offset);
234 
235  // FIXME: Add support for parsing opcode_operands_table
236  if (FlagData & MACRO_OPCODE_OPERANDS_TABLE)
238  "opcode_operands_table is not supported");
239  Flags = FlagData;
240  if (Flags & MACRO_DEBUG_LINE_OFFSET)
241  DebugLineOffset = Data.getUnsigned(Offset, getOffsetByteSize());
242  return Error::success();
243 }
llvm::errc::invalid_argument
@ invalid_argument
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
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:39
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
DWARFContext.h
llvm::WithColor::get
raw_ostream & get()
Definition: WithColor.h:80
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
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
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:384
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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:316
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:92
uint64_t
llvm::DenseMap
Definition: DenseMap.h:714
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:385
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:1241
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::dwarf::DW_MACINFO_start_file
@ DW_MACINFO_start_file
Definition: Dwarf.h:383
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:599
llvm::dwarf::MacinfoString
StringRef MacinfoString(unsigned Encoding)
Definition: Dwarf.cpp:457
Version
uint64_t Version
Definition: RawMemProfReader.cpp:25
llvm::dwarf::DW_MACINFO_invalid
@ DW_MACINFO_invalid
Macinfo type for invalid results.
Definition: Dwarf.h:50
llvm::DenseMapBase::try_emplace
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:222
llvm::dwarf::DWARF64
@ DWARF64
Definition: Dwarf.h:92
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:635
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:283
llvm::dwarf::DWARF32
@ DWARF32
Definition: Dwarf.h:92
DWARFDataExtractor.h