LLVM  13.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 #include <cstdint>
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "asm-printer"
34 
35 //===----------------------------------------------------------------------===//
36 // Dwarf Emission Helper Routines
37 //===----------------------------------------------------------------------===//
38 
39 /// EmitSLEB128 - emit the specified signed leb128 value.
40 void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
41  if (isVerbose() && Desc)
42  OutStreamer->AddComment(Desc);
43 
44  OutStreamer->emitSLEB128IntValue(Value);
45 }
46 
47 void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
48  unsigned PadTo) const {
49  if (isVerbose() && Desc)
50  OutStreamer->AddComment(Desc);
51 
52  OutStreamer->emitULEB128IntValue(Value, PadTo);
53 }
54 
55 /// Emit something like ".uleb128 Hi-Lo".
57  const MCSymbol *Lo) const {
58  OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
59 }
60 
61 static const char *DecodeDWARFEncoding(unsigned Encoding) {
62  switch (Encoding) {
64  return "absptr";
66  return "omit";
68  return "pcrel";
70  return "uleb128";
72  return "sleb128";
74  return "udata4";
76  return "udata8";
78  return "sdata4";
80  return "sdata8";
82  return "pcrel udata4";
84  return "pcrel sdata4";
86  return "pcrel udata8";
88  return "pcrel sdata8";
90  :
91  return "indirect pcrel udata4";
93  :
94  return "indirect pcrel sdata4";
96  :
97  return "indirect pcrel udata8";
99  :
100  return "indirect pcrel sdata8";
103  return "indirect datarel sdata4";
106  return "indirect datarel sdata8";
107  }
108 
109  return "<unknown encoding>";
110 }
111 
112 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
113 /// encoding. If verbose assembly output is enabled, we output comments
114 /// describing the encoding. Desc is an optional string saying what the
115 /// encoding is specifying (e.g. "LSDA").
116 void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
117  if (isVerbose()) {
118  if (Desc)
119  OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
120  Twine(DecodeDWARFEncoding(Val)));
121  else
122  OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
123  }
124 
125  OutStreamer->emitIntValue(Val, 1);
126 }
127 
128 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
129 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
130  if (Encoding == dwarf::DW_EH_PE_omit)
131  return 0;
132 
133  switch (Encoding & 0x07) {
134  default:
135  llvm_unreachable("Invalid encoded value.");
137  return MF->getDataLayout().getPointerSize();
139  return 2;
141  return 4;
143  return 8;
144  }
145 }
146 
147 void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
148  if (GV) {
150 
151  const MCExpr *Exp =
152  TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
153  OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
154  } else
155  OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
156 }
157 
159  bool ForceOffset) const {
160  if (!ForceOffset) {
161  // On COFF targets, we have to emit the special .secrel32 directive.
163  assert(!isDwarf64() &&
164  "emitting DWARF64 is not implemented for COFF targets");
165  OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
166  return;
167  }
168 
169  // If the format uses relocations with dwarf, refer to the symbol directly.
171  OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
172  return;
173  }
174  }
175 
176  // Otherwise, emit it as a label difference from the start of the section.
177  emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
179 }
180 
183  assert(S.Symbol && "No symbol available");
184  emitDwarfSymbolReference(S.Symbol);
185  return;
186  }
187 
188  // Just emit the offset directly; no need for symbol math.
189  OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
190 }
191 
192 void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
194 }
195 
197  assert(isDwarf64() || Value <= UINT32_MAX);
198  OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
199 }
200 
201 void AsmPrinter::emitDwarfUnitLength(uint64_t Length,
202  const Twine &Comment) const {
203  OutStreamer->emitDwarfUnitLength(Length, Comment);
204 }
205 
207  const Twine &Comment) const {
208  return OutStreamer->emitDwarfUnitLength(Prefix, Comment);
209 }
210 
212  unsigned Encoding) const {
213  // The least significant 3 bits specify the width of the encoding
214  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
216  else
218 }
219 
220 void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
221  // The least significant 3 bits specify the width of the encoding
222  if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
224  else
225  OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
226 }
227 
228 //===----------------------------------------------------------------------===//
229 // Dwarf Lowering Routines
230 //===----------------------------------------------------------------------===//
231 
233  switch (Inst.getOperation()) {
234  default:
235  llvm_unreachable("Unexpected instruction");
237  OutStreamer->emitCFIDefCfaOffset(Inst.getOffset());
238  break;
240  OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset());
241  break;
243  OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
244  break;
246  OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
247  break;
249  OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
250  break;
252  OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2());
253  break;
255  OutStreamer->emitCFIWindowSave();
256  break;
258  OutStreamer->emitCFINegateRAState();
259  break;
261  OutStreamer->emitCFISameValue(Inst.getRegister());
262  break;
264  OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
265  break;
267  OutStreamer->AddComment(Inst.getComment());
268  OutStreamer->emitCFIEscape(Inst.getValues());
269  break;
271  OutStreamer->emitCFIRestore(Inst.getRegister());
272  break;
274  OutStreamer->emitCFIUndefined(Inst.getRegister());
275  break;
276  }
277 }
278 
279 void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
280  // Emit the code (index) for the abbreviation.
281  if (isVerbose())
282  OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
283  Twine::utohexstr(Die.getOffset()) + ":0x" +
284  Twine::utohexstr(Die.getSize()) + " " +
285  dwarf::TagString(Die.getTag()));
287 
288  // Emit the DIE attribute values.
289  for (const auto &V : Die.values()) {
290  dwarf::Attribute Attr = V.getAttribute();
291  assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
292 
293  if (isVerbose()) {
294  OutStreamer->AddComment(dwarf::AttributeString(Attr));
295  if (Attr == dwarf::DW_AT_accessibility)
296  OutStreamer->AddComment(
297  dwarf::AccessibilityString(V.getDIEInteger().getValue()));
298  }
299 
300  // Emit an attribute using the defined form.
301  V.emitValue(this);
302  }
303 
304  // Emit the DIE children if any.
305  if (Die.hasChildren()) {
306  for (auto &Child : Die.children())
307  emitDwarfDIE(Child);
308 
309  OutStreamer->AddComment("End Of Children Mark");
310  emitInt8(0);
311  }
312 }
313 
314 void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
315  // Emit the abbreviations code (base 1 index.)
316  emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
317 
318  // Emit the abbreviations data.
319  Abbrev.Emit(this);
320 }
llvm::MCCFIInstruction::OpWindowSave
@ OpWindowSave
Definition: MCDwarf.h:457
AsmPrinter.h
llvm::AsmPrinter::emitLabelDifference
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...
Definition: AsmPrinter.cpp:2395
llvm::AsmPrinter::emitLabelDifferenceAsULEB128
void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
Definition: AsmPrinterDwarf.cpp:56
MCDwarf.h
llvm
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::dwarf::DW_EH_PE_sdata4
@ DW_EH_PE_sdata4
Definition: Dwarf.h:440
llvm::MCCFIInstruction::OpDefCfaRegister
@ OpDefCfaRegister
Definition: MCDwarf.h:448
llvm::MCCFIInstruction::getComment
StringRef getComment() const
Definition: MCDwarf.h:614
llvm::AsmPrinter::emitULEB128
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
Definition: AsmPrinterDwarf.cpp:47
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
llvm::MCCFIInstruction::OpOffset
@ OpOffset
Definition: MCDwarf.h:447
llvm::AsmPrinter::MAI
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:88
llvm::MipsISD::Lo
@ Lo
Definition: MipsISelLowering.h:79
ErrorHandling.h
llvm::AsmPrinter::emitSLEB128
void emitSLEB128(int64_t Value, const char *Desc=nullptr) const
Emit the specified signed leb128 value.
Definition: AsmPrinterDwarf.cpp:40
llvm::dwarf::DW_EH_PE_sdata8
@ DW_EH_PE_sdata8
Definition: Dwarf.h:441
llvm::AsmPrinter::getDwarfOffsetByteSize
unsigned int getDwarfOffsetByteSize() const
Returns 4 for DWARF32 and 8 for DWARF64.
Definition: AsmPrinter.cpp:3586
llvm::AsmPrinter::emitDwarfOffset
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset" or ".quad Label + Offset" depending on the DWARF format.
Definition: AsmPrinterDwarf.cpp:192
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::DIE
A structured debug information entry.
Definition: DIE.h:739
llvm::DIE::getTag
dwarf::Tag getTag() const
Definition: DIE.h:775
llvm::AsmPrinter::emitCallSiteOffset
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Encoding) const
Emit reference to a call site with a specified encoding.
Definition: AsmPrinterDwarf.cpp:211
llvm::dwarf::Attribute
Attribute
Attributes.
Definition: Dwarf.h:124
llvm::dwarf::AccessibilityString
StringRef AccessibilityString(unsigned Access)
Definition: Dwarf.cpp:270
llvm::MipsISD::Hi
@ Hi
Definition: MipsISelLowering.h:75
llvm::DIEValueList::values
value_range values()
Definition: DIE.h:727
llvm::TargetLoweringObjectFile
Definition: TargetLoweringObjectFile.h:43
llvm::MCCFIInstruction::OpDefCfa
@ OpDefCfa
Definition: MCDwarf.h:450
llvm::DIEAbbrev
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:79
llvm::MCCFIInstruction::OpUndefined
@ OpUndefined
Definition: MCDwarf.h:455
llvm::AsmPrinter::emitDwarfAbbrev
void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const
Definition: AsmPrinterDwarf.cpp:314
TargetMachine.h
llvm::dwarf::DW_EH_PE_indirect
@ DW_EH_PE_indirect
Definition: Dwarf.h:448
llvm::dwarf::DW_EH_PE_udata2
@ DW_EH_PE_udata2
Definition: Dwarf.h:435
llvm::AsmPrinter::OutStreamer
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:97
Twine.h
llvm::DIEAbbrev::Emit
void Emit(const AsmPrinter *AP) const
Print the abbreviation using the specified asm printer.
Definition: DIE.cpp:68
MCSymbol.h
llvm::MCCFIInstruction::getOffset
int getOffset() const
Definition: MCDwarf.h:602
llvm::MCAsmInfo::needsDwarfSectionOffsetDirective
bool needsDwarfSectionOffsetDirective() const
Definition: MCAsmInfo.h:601
llvm::MCCFIInstruction::getOperation
OpType getOperation() const
Definition: MCDwarf.h:586
llvm::AsmPrinter::emitDwarfSymbolReference
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
Definition: AsmPrinterDwarf.cpp:158
llvm::AsmPrinter::emitInt8
void emitInt8(int Value) const
Emit a byte directive and value.
Definition: AsmPrinter.cpp:2379
llvm::MCCFIInstruction::getRegister
unsigned getRegister() const
Definition: MCDwarf.h:589
llvm::DIE::getSize
unsigned getSize() const
Definition: DIE.h:778
llvm::MCCFIInstruction
Definition: MCDwarf.h:441
DIE.h
llvm::dwarf::DW_EH_PE_udata4
@ DW_EH_PE_udata4
Definition: Dwarf.h:436
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
llvm::DwarfStringPoolEntry
Data for a string pool entry.
Definition: DwarfStringPoolEntry.h:20
llvm::dwarf::DW_EH_PE_udata8
@ DW_EH_PE_udata8
Definition: Dwarf.h:437
llvm::MCCFIInstruction::OpDefCfaOffset
@ OpDefCfaOffset
Definition: MCDwarf.h:449
llvm::MCCFIInstruction::OpRestore
@ OpRestore
Definition: MCDwarf.h:454
llvm::AsmPrinter::emitLabelPlusOffset
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...
Definition: AsmPrinter.cpp:2403
llvm::dwarf::DW_EH_PE_pcrel
@ DW_EH_PE_pcrel
Definition: Dwarf.h:443
llvm::AsmPrinter::GetSizeOfEncodedValue
unsigned GetSizeOfEncodedValue(unsigned Encoding) const
Return the size of the encoding in bytes.
Definition: AsmPrinterDwarf.cpp:129
llvm::MCCFIInstruction::OpSameValue
@ OpSameValue
Definition: MCDwarf.h:444
MCRegisterInfo.h
llvm::MCCFIInstruction::getRegister2
unsigned getRegister2() const
Definition: MCDwarf.h:597
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AsmPrinter::emitDwarfUnitLength
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
Definition: AsmPrinterDwarf.cpp:201
llvm::AsmPrinter::MF
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:100
llvm::MCCFIInstruction::OpAdjustCfaOffset
@ OpAdjustCfaOffset
Definition: MCDwarf.h:452
llvm::AsmPrinter::emitDwarfLengthOrOffset
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
Definition: AsmPrinterDwarf.cpp:196
MCSection.h
llvm::AsmPrinter::emitCFIInstruction
void emitCFIInstruction(const MachineInstr &MI)
Definition: AsmPrinter.cpp:1075
ByteStreamer.h
llvm::MCCFIInstruction::OpEscape
@ OpEscape
Definition: MCDwarf.h:453
llvm::dwarf::DW_EH_PE_datarel
@ DW_EH_PE_datarel
Definition: Dwarf.h:445
llvm::dwarf::DW_EH_PE_uleb128
@ DW_EH_PE_uleb128
Definition: Dwarf.h:434
MCAsmInfo.h
DataLayout.h
Dwarf.h
llvm::MCCFIInstruction::getValues
StringRef getValues() const
Definition: MCDwarf.h:609
MachineLocation.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
TargetLoweringObjectFile.h
llvm::DIE::children
child_range children()
Definition: DIE.h:787
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::MCAsmInfo::doesDwarfUseRelocationsAcrossSections
bool doesDwarfUseRelocationsAcrossSections() const
Definition: MCAsmInfo.h:772
DecodeDWARFEncoding
static const char * DecodeDWARFEncoding(unsigned Encoding)
Definition: AsmPrinterDwarf.cpp:61
llvm::AsmPrinter::MMI
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:103
llvm::dwarf::DW_EH_PE_sleb128
@ DW_EH_PE_sleb128
Definition: Dwarf.h:438
llvm::dwarf::DW_EH_PE_absptr
@ DW_EH_PE_absptr
Definition: Dwarf.h:432
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
llvm::AsmPrinter::isDwarf64
bool isDwarf64() const
Definition: AsmPrinter.cpp:3582
llvm::MCCFIInstruction::OpGnuArgsSize
@ OpGnuArgsSize
Definition: MCDwarf.h:459
llvm::MCCFIInstruction::OpRegister
@ OpRegister
Definition: MCDwarf.h:456
llvm::DIE::getAbbrevNumber
unsigned getAbbrevNumber() const
Definition: DIE.h:774
llvm::AsmPrinter::emitTTypeReference
virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding)
Emit reference to a ttype global with a specified encoding.
Definition: AsmPrinterDwarf.cpp:147
llvm::AsmPrinter::TM
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:85
llvm::AsmPrinter::getObjFileLowering
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:223
MCStreamer.h
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:433
llvm::DIE::hasChildren
bool hasChildren() const
Definition: DIE.h:779
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:260
llvm::AsmPrinter::emitDwarfStringOffset
void emitDwarfStringOffset(DwarfStringPoolEntry S) const
Emit the 4- or 8-byte offset of a string from the start of its section.
Definition: AsmPrinterDwarf.cpp:181
llvm::AsmPrinter::emitDwarfDIE
void emitDwarfDIE(const DIE &Die) const
Recursively emit Dwarf DIE tree.
Definition: AsmPrinterDwarf.cpp:279
llvm::AsmPrinter::emitCallSiteValue
void emitCallSiteValue(uint64_t Value, unsigned Encoding) const
Emit an integer value corresponding to the call site encoding.
Definition: AsmPrinterDwarf.cpp:220
llvm::DIEAbbrev::getNumber
unsigned getNumber() const
Definition: DIE.h:101
llvm::dwarf::TagString
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
llvm::AsmPrinter::isVerbose
bool isVerbose() const
Return true if assembly output should contain comments.
Definition: AsmPrinter.h:238
llvm::DIE::getOffset
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:777
llvm::MCCFIInstruction::OpNegateRAState
@ OpNegateRAState
Definition: MCDwarf.h:458
MachineFunction.h
llvm::AsmPrinter::emitEncodingByte
void emitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
Definition: AsmPrinterDwarf.cpp:116
llvm::TargetLoweringObjectFile::getTTypeGlobalReference
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...
Definition: TargetLoweringObjectFile.cpp:398
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::dwarf::AttributeString
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
llvm::DataLayout::getPointerSize
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:701