LLVM  12.0.0git
AsmPrinterDwarf.cpp
Go to the documentation of this file.
1 //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
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 // This file implements the Dwarf emissions parts of AsmPrinter.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ByteStreamer.h"
14 #include "llvm/ADT/Twine.h"
17 #include "llvm/CodeGen/DIE.h"
19 #include "llvm/IR/DataLayout.h"
20 #include "llvm/MC/MCAsmInfo.h"
21 #include "llvm/MC/MCDwarf.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSection.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSymbol.h"
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "asm-printer"
33 
34 //===----------------------------------------------------------------------===//
35 // Dwarf Emission Helper Routines
36 //===----------------------------------------------------------------------===//
37 
38 /// EmitSLEB128 - emit the specified signed leb128 value.
39 void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
40  if (isVerbose() && Desc)
41  OutStreamer->AddComment(Desc);
42 
43  OutStreamer->emitSLEB128IntValue(Value);
44 }
45 
46 void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
47  unsigned PadTo) const {
48  if (isVerbose() && Desc)
49  OutStreamer->AddComment(Desc);
50 
51  OutStreamer->emitULEB128IntValue(Value, PadTo);
52 }
53 
54 /// Emit something like ".uleb128 Hi-Lo".
56  const MCSymbol *Lo) const {
57  OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
58 }
59 
60 static const char *DecodeDWARFEncoding(unsigned Encoding) {
61  switch (Encoding) {
63  return "absptr";
65  return "omit";
67  return "pcrel";
69  return "uleb128";
71  return "sleb128";
73  return "udata4";
75  return "udata8";
77  return "sdata4";
79  return "sdata8";
81  return "pcrel udata4";
83  return "pcrel sdata4";
85  return "pcrel udata8";
87  return "pcrel sdata8";
89  :
90  return "indirect pcrel udata4";
92  :
93  return "indirect pcrel sdata4";
95  :
96  return "indirect pcrel udata8";
98  :
99  return "indirect pcrel sdata8";
100  }
101 
102  return "<unknown encoding>";
103 }
104 
105 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
106 /// encoding. If verbose assembly output is enabled, we output comments
107 /// describing the encoding. Desc is an optional string saying what the
108 /// encoding is specifying (e.g. "LSDA").
109 void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
110  if (isVerbose()) {
111  if (Desc)
112  OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
113  Twine(DecodeDWARFEncoding(Val)));
114  else
115  OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
116  }
117 
118  OutStreamer->emitIntValue(Val, 1);
119 }
120 
121 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
122 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
123  if (Encoding == dwarf::DW_EH_PE_omit)
124  return 0;
125 
126  switch (Encoding & 0x07) {
127  default:
128  llvm_unreachable("Invalid encoded value.");
130  return MF->getDataLayout().getPointerSize();
132  return 2;
134  return 4;
136  return 8;
137  }
138 }
139 
141  unsigned Encoding) const {
142  if (GV) {
144 
145  const MCExpr *Exp =
146  TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
147  OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
148  } else
149  OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
150 }
151 
153  bool ForceOffset) const {
154  if (!ForceOffset) {
155  // On COFF targets, we have to emit the special .secrel32 directive.
157  OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
158  return;
159  }
160 
161  // If the format uses relocations with dwarf, refer to the symbol directly.
163  OutStreamer->emitSymbolValue(Label, 4);
164  return;
165  }
166  }
167 
168  // Otherwise, emit it as a label difference from the start of the section.
169  emitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
170 }
171 
174  assert(S.Symbol && "No symbol available");
176  return;
177  }
178 
179  // Just emit the offset directly; no need for symbol math.
180  emitInt32(S.Offset);
181 }
182 
183 void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
184  // TODO: Support DWARF64
185  emitLabelPlusOffset(Label, Offset, 4);
186 }
187 
189  unsigned Encoding) const {
190  // The least significant 3 bits specify the width of the encoding
191  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
193  else
194  emitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
195 }
196 
197 void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
198  // The least significant 3 bits specify the width of the encoding
199  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
200  emitULEB128(Value);
201  else
202  OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
203 }
204 
205 //===----------------------------------------------------------------------===//
206 // Dwarf Lowering Routines
207 //===----------------------------------------------------------------------===//
208 
210  switch (Inst.getOperation()) {
211  default:
212  llvm_unreachable("Unexpected instruction");
214  OutStreamer->emitCFIDefCfaOffset(Inst.getOffset());
215  break;
217  OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset());
218  break;
220  OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
221  break;
223  OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
224  break;
226  OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
227  break;
229  OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2());
230  break;
232  OutStreamer->emitCFIWindowSave();
233  break;
235  OutStreamer->emitCFINegateRAState();
236  break;
238  OutStreamer->emitCFISameValue(Inst.getRegister());
239  break;
241  OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
242  break;
244  OutStreamer->emitCFIEscape(Inst.getValues());
245  break;
247  OutStreamer->emitCFIRestore(Inst.getRegister());
248  break;
250  OutStreamer->emitCFIUndefined(Inst.getRegister());
251  break;
252  }
253 }
254 
255 void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
256  // Emit the code (index) for the abbreviation.
257  if (isVerbose())
258  OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
259  Twine::utohexstr(Die.getOffset()) + ":0x" +
260  Twine::utohexstr(Die.getSize()) + " " +
261  dwarf::TagString(Die.getTag()));
263 
264  // Emit the DIE attribute values.
265  for (const auto &V : Die.values()) {
266  dwarf::Attribute Attr = V.getAttribute();
267  assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
268 
269  if (isVerbose()) {
270  OutStreamer->AddComment(dwarf::AttributeString(Attr));
271  if (Attr == dwarf::DW_AT_accessibility)
272  OutStreamer->AddComment(
273  dwarf::AccessibilityString(V.getDIEInteger().getValue()));
274  }
275 
276  // Emit an attribute using the defined form.
277  V.emitValue(this);
278  }
279 
280  // Emit the DIE children if any.
281  if (Die.hasChildren()) {
282  for (auto &Child : Die.children())
283  emitDwarfDIE(Child);
284 
285  OutStreamer->AddComment("End Of Children Mark");
286  emitInt8(0);
287  }
288 }
289 
290 void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
291  // Emit the abbreviations code (base 1 index.)
292  emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
293 
294  // Emit the abbreviations data.
295  Abbrev.Emit(this);
296 }
unsigned getSize() const
Definition: DIE.h:762
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:210
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:96
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Attribute
Attributes.
Definition: Dwarf.h:103
child_range children()
Definition: DIE.h:771
bool hasChildren() const
Definition: DIE.h:763
bool needsDwarfSectionOffsetDirective() const
Definition: MCAsmInfo.h:491
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:99
void emitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
void emitDwarfDIE(const DIE &Die) const
Recursively emit Dwarf DIE tree.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
void emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label+Offset" where the size in bytes of the directive is specified by Siz...
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
bool doesDwarfUseRelocationsAcrossSections() const
Definition: MCAsmInfo.h:631
bool isVerbose() const
Return true if assembly output should contain comments.
Definition: AsmPrinter.h:222
Data for a string pool entry.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:102
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
void Emit(const AsmPrinter *AP) const
Print the abbreviation using the specified asm printer.
Definition: DIE.cpp:68
void emitSLEB128(int64_t Value, const char *Desc=nullptr) const
Emit the specified signed leb128 value.
StringRef AccessibilityString(unsigned Access)
Definition: Dwarf.cpp:264
unsigned getRegister2() const
Definition: MCDwarf.h:593
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:87
value_range values()
Definition: DIE.h:711
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size FIXME: The defaults need to be removed once all of the backends/clients are updat...
Definition: DataLayout.cpp:662
A structured debug information entry.
Definition: DIE.h:723
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:84
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
int getOffset() const
Definition: MCDwarf.h:598
OpType getOperation() const
Definition: MCDwarf.h:582
virtual const MCExpr * getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, MachineModuleInfo *MMI, MCStreamer &Streamer) const
Return an MCExpr to use for a reference to the specified global variable from exception handling info...
void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
StringRef getValues() const
Definition: MCDwarf.h:605
unsigned GetSizeOfEncodedValue(unsigned Encoding) const
Return the size of the encoding in bytes.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Encoding) const
Emit reference to a call site with a specified encoding.
unsigned getRegister() const
Definition: MCDwarf.h:585
void emitCFIInstruction(const MachineInstr &MI)
Definition: AsmPrinter.cpp:991
void emitDwarfStringOffset(DwarfStringPoolEntry S) const
Emit the 4-byte offset of a string from the start of its section.
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
MCSymbol * getBeginSymbol()
Definition: MCSection.h:120
void emitInt32(int Value) const
Emit a long directive and value.
static const char * DecodeDWARFEncoding(unsigned Encoding)
This file contains constants used for implementing Dwarf debug support.
void emitCallSiteValue(uint64_t Value, unsigned Encoding) const
Emit an integer value corresponding to the call site encoding.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:260
void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) const
Emit reference to a ttype global with a specified encoding.
void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const
dwarf::Tag getTag() const
Definition: DIE.h:759
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:79
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
unsigned getAbbrevNumber() const
Definition: DIE.h:758
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitInt8(int Value) const
Emit a byte directive and value.
LLVM Value Representation.
Definition: Value.h:74
unsigned getNumber() const
Definition: DIE.h:101
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:761
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset".