LLVM  9.0.0svn
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/MCRegisterInfo.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "asm-printer"
32 
33 //===----------------------------------------------------------------------===//
34 // Dwarf Emission Helper Routines
35 //===----------------------------------------------------------------------===//
36 
37 /// EmitSLEB128 - emit the specified signed leb128 value.
38 void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
39  if (isVerbose() && Desc)
40  OutStreamer->AddComment(Desc);
41 
42  OutStreamer->EmitSLEB128IntValue(Value);
43 }
44 
45 void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
46  if (isVerbose() && Desc)
47  OutStreamer->AddComment(Desc);
48 
49  OutStreamer->EmitULEB128IntValue(Value);
50 }
51 
52 /// Emit something like ".uleb128 Hi-Lo".
54  const MCSymbol *Lo) const {
55  OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
56 }
57 
58 static const char *DecodeDWARFEncoding(unsigned Encoding) {
59  switch (Encoding) {
61  return "absptr";
63  return "omit";
65  return "pcrel";
67  return "uleb128";
69  return "sleb128";
71  return "udata4";
73  return "udata8";
75  return "sdata4";
77  return "sdata8";
79  return "pcrel udata4";
81  return "pcrel sdata4";
83  return "pcrel udata8";
85  return "pcrel sdata8";
87  :
88  return "indirect pcrel udata4";
90  :
91  return "indirect pcrel sdata4";
93  :
94  return "indirect pcrel udata8";
96  :
97  return "indirect pcrel sdata8";
98  }
99 
100  return "<unknown encoding>";
101 }
102 
103 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
104 /// encoding. If verbose assembly output is enabled, we output comments
105 /// describing the encoding. Desc is an optional string saying what the
106 /// encoding is specifying (e.g. "LSDA").
107 void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
108  if (isVerbose()) {
109  if (Desc)
110  OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
111  Twine(DecodeDWARFEncoding(Val)));
112  else
113  OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
114  }
115 
116  OutStreamer->EmitIntValue(Val, 1);
117 }
118 
119 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
120 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
121  if (Encoding == dwarf::DW_EH_PE_omit)
122  return 0;
123 
124  switch (Encoding & 0x07) {
125  default:
126  llvm_unreachable("Invalid encoded value.");
128  return MF->getDataLayout().getPointerSize();
130  return 2;
132  return 4;
134  return 8;
135  }
136 }
137 
139  unsigned Encoding) const {
140  if (GV) {
142 
143  const MCExpr *Exp =
144  TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
145  OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
146  } else
147  OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
148 }
149 
151  bool ForceOffset) const {
152  if (!ForceOffset) {
153  // On COFF targets, we have to emit the special .secrel32 directive.
155  OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
156  return;
157  }
158 
159  // If the format uses relocations with dwarf, refer to the symbol directly.
161  OutStreamer->EmitSymbolValue(Label, 4);
162  return;
163  }
164  }
165 
166  // Otherwise, emit it as a label difference from the start of the section.
167  EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
168 }
169 
172  assert(S.Symbol && "No symbol available");
174  return;
175  }
176 
177  // Just emit the offset directly; no need for symbol math.
178  emitInt32(S.Offset);
179 }
180 
181 void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
182  EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
183 }
184 
185 //===----------------------------------------------------------------------===//
186 // Dwarf Lowering Routines
187 //===----------------------------------------------------------------------===//
188 
190  switch (Inst.getOperation()) {
191  default:
192  llvm_unreachable("Unexpected instruction");
194  OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
195  break;
197  OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
198  break;
200  OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
201  break;
203  OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
204  break;
206  OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
207  break;
209  OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
210  break;
212  OutStreamer->EmitCFIWindowSave();
213  break;
215  OutStreamer->EmitCFINegateRAState();
216  break;
218  OutStreamer->EmitCFISameValue(Inst.getRegister());
219  break;
221  OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
222  break;
224  OutStreamer->EmitCFIEscape(Inst.getValues());
225  break;
227  OutStreamer->EmitCFIRestore(Inst.getRegister());
228  break;
229  }
230 }
231 
232 void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
233  // Emit the code (index) for the abbreviation.
234  if (isVerbose())
235  OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
236  Twine::utohexstr(Die.getOffset()) + ":0x" +
237  Twine::utohexstr(Die.getSize()) + " " +
238  dwarf::TagString(Die.getTag()));
240 
241  // Emit the DIE attribute values.
242  for (const auto &V : Die.values()) {
243  dwarf::Attribute Attr = V.getAttribute();
244  assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
245 
246  if (isVerbose()) {
247  OutStreamer->AddComment(dwarf::AttributeString(Attr));
248  if (Attr == dwarf::DW_AT_accessibility)
249  OutStreamer->AddComment(
250  dwarf::AccessibilityString(V.getDIEInteger().getValue()));
251  }
252 
253  // Emit an attribute using the defined form.
254  V.EmitValue(this);
255  }
256 
257  // Emit the DIE children if any.
258  if (Die.hasChildren()) {
259  for (auto &Child : Die.children())
260  emitDwarfDIE(Child);
261 
262  OutStreamer->AddComment("End Of Children Mark");
263  emitInt8(0);
264  }
265 }
266 
267 void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
268  // Emit the abbreviations code (base 1 index.)
269  EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
270 
271  // Emit the abbreviations data.
272  Abbrev.Emit(this);
273 }
unsigned getSize() const
Definition: DIE.h:700
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:206
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:93
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:114
child_range children()
Definition: DIE.h:709
bool hasChildren() const
Definition: DIE.h:701
bool needsDwarfSectionOffsetDirective() const
Definition: MCAsmInfo.h:466
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:96
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
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
bool doesDwarfUseRelocationsAcrossSections() const
Definition: MCAsmInfo.h:589
bool isVerbose() const
Return true if assembly output should contain comments.
Definition: AsmPrinter.h:199
Data for a string pool entry.
void EmitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:99
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
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...
void Emit(const AsmPrinter *AP) const
Print the abbreviation using the specified asm printer.
Definition: DIE.cpp:68
StringRef AccessibilityString(unsigned Access)
Definition: Dwarf.cpp:255
unsigned getRegister2() const
Definition: MCDwarf.h:568
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:84
value_range values()
Definition: DIE.h:649
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:628
A structured debug information entry.
Definition: DIE.h:661
void EmitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:81
int getOffset() const
Definition: MCDwarf.h:573
OpType getOperation() const
Definition: MCDwarf.h:557
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...
StringRef getValues() const
Definition: MCDwarf.h:580
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.
unsigned getRegister() const
Definition: MCDwarf.h:560
void emitCFIInstruction(const MachineInstr &MI)
Definition: AsmPrinter.cpp:927
void EmitSLEB128(int64_t Value, const char *Desc=nullptr) const
Emit the specified signed leb128 value.
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:109
void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const
Emit reference to a ttype global with a specified encoding.
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.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:266
void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const
dwarf::Tag getTag() const
Definition: DIE.h:697
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:78
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset".
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...
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:395
unsigned getAbbrevNumber() const
Definition: DIE.h:696
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitInt8(int Value) const
Emit a byte directive and value.
LLVM Value Representation.
Definition: Value.h:72
unsigned getNumber() const
Definition: DIE.h:100
void EmitULEB128(uint64_t Value, const char *Desc=nullptr) const
Emit the specified unsigned leb128 value.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:699