LLVM 19.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 "llvm/ADT/Twine.h"
16#include "llvm/CodeGen/DIE.h"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCDwarf.h"
21#include "llvm/MC/MCSection.h"
22#include "llvm/MC/MCStreamer.h"
23#include "llvm/MC/MCSymbol.h"
26#include <cstdint>
27using namespace llvm;
28
29#define DEBUG_TYPE "asm-printer"
30
31//===----------------------------------------------------------------------===//
32// Dwarf Emission Helper Routines
33//===----------------------------------------------------------------------===//
34
35static const char *DecodeDWARFEncoding(unsigned Encoding) {
36 switch (Encoding) {
38 return "absptr";
40 return "omit";
42 return "pcrel";
44 return "uleb128";
46 return "sleb128";
48 return "udata4";
50 return "udata8";
52 return "sdata4";
54 return "sdata8";
56 return "pcrel udata4";
58 return "pcrel sdata4";
60 return "pcrel udata8";
62 return "pcrel sdata8";
64 :
65 return "indirect pcrel udata4";
67 :
68 return "indirect pcrel sdata4";
70 :
71 return "indirect pcrel udata8";
73 :
74 return "indirect pcrel sdata8";
77 return "indirect datarel sdata4";
80 return "indirect datarel sdata8";
81 }
82
83 return "<unknown encoding>";
84}
85
86/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
87/// encoding. If verbose assembly output is enabled, we output comments
88/// describing the encoding. Desc is an optional string saying what the
89/// encoding is specifying (e.g. "LSDA").
90void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
91 if (isVerbose()) {
92 if (Desc)
93 OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
95 else
96 OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
97 }
98
99 OutStreamer->emitIntValue(Val, 1);
100}
101
102/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
103unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
104 if (Encoding == dwarf::DW_EH_PE_omit)
105 return 0;
106
107 switch (Encoding & 0x07) {
108 default:
109 llvm_unreachable("Invalid encoded value.");
111 return MAI->getCodePointerSize();
113 return 2;
115 return 4;
117 return 8;
118 }
119}
120
121void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
122 if (GV) {
124
125 const MCExpr *Exp =
126 TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
127 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
128 } else
129 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
130}
131
133 bool ForceOffset) const {
134 if (!ForceOffset) {
135 // On COFF targets, we have to emit the special .secrel32 directive.
137 assert(!isDwarf64() &&
138 "emitting DWARF64 is not implemented for COFF targets");
139 OutStreamer->emitCOFFSecRel32(Label, /*Offset=*/0);
140 return;
141 }
142
143 // If the format uses relocations with dwarf, refer to the symbol directly.
145 OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
146 return;
147 }
148 }
149
150 // Otherwise, emit it as a label difference from the start of the section.
151 emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
153}
154
157 assert(S.Symbol && "No symbol available");
159 return;
160 }
161
162 // Just emit the offset directly; no need for symbol math.
163 OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
164}
165
168}
169
171 assert(isDwarf64() || Value <= UINT32_MAX);
172 OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
173}
174
176 const Twine &Comment) const {
177 OutStreamer->emitDwarfUnitLength(Length, Comment);
178}
179
181 const Twine &Comment) const {
182 return OutStreamer->emitDwarfUnitLength(Prefix, Comment);
183}
184
186 unsigned Encoding) const {
187 // The least significant 3 bits specify the width of the encoding
188 if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
190 else
192}
193
194void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
195 // The least significant 3 bits specify the width of the encoding
196 if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
198 else
199 OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
200}
201
202//===----------------------------------------------------------------------===//
203// Dwarf Lowering Routines
204//===----------------------------------------------------------------------===//
205
207 SMLoc Loc = Inst.getLoc();
208 switch (Inst.getOperation()) {
209 default:
210 llvm_unreachable("Unexpected instruction");
212 OutStreamer->emitCFIDefCfaOffset(Inst.getOffset(), Loc);
213 break;
215 OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset(), Loc);
216 break;
218 OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset(), Loc);
219 break;
221 OutStreamer->emitCFIDefCfaRegister(Inst.getRegister(), Loc);
222 break;
224 OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
225 Inst.getAddressSpace(), Loc);
226 break;
228 OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset(), Loc);
229 break;
231 OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2(), Loc);
232 break;
234 OutStreamer->emitCFIWindowSave(Loc);
235 break;
237 OutStreamer->emitCFINegateRAState(Loc);
238 break;
240 OutStreamer->emitCFISameValue(Inst.getRegister(), Loc);
241 break;
243 OutStreamer->emitCFIGnuArgsSize(Inst.getOffset(), Loc);
244 break;
246 OutStreamer->AddComment(Inst.getComment());
247 OutStreamer->emitCFIEscape(Inst.getValues(), Loc);
248 break;
250 OutStreamer->emitCFIRestore(Inst.getRegister(), Loc);
251 break;
253 OutStreamer->emitCFIUndefined(Inst.getRegister(), Loc);
254 break;
256 OutStreamer->emitCFIRememberState(Loc);
257 break;
259 OutStreamer->emitCFIRestoreState(Loc);
260 break;
261 }
262}
263
264void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
265 // Emit the code (index) for the abbreviation.
266 if (isVerbose())
267 OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
268 Twine::utohexstr(Die.getOffset()) + ":0x" +
269 Twine::utohexstr(Die.getSize()) + " " +
270 dwarf::TagString(Die.getTag()));
272
273 // Emit the DIE attribute values.
274 for (const auto &V : Die.values()) {
275 dwarf::Attribute Attr = V.getAttribute();
276 assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
277
278 if (isVerbose()) {
279 OutStreamer->AddComment(dwarf::AttributeString(Attr));
280 if (Attr == dwarf::DW_AT_accessibility)
281 OutStreamer->AddComment(
282 dwarf::AccessibilityString(V.getDIEInteger().getValue()));
283 }
284
285 // Emit an attribute using the defined form.
286 V.emitValue(this);
287 }
288
289 // Emit the DIE children if any.
290 if (Die.hasChildren()) {
291 for (const auto &Child : Die.children())
292 emitDwarfDIE(Child);
293
294 OutStreamer->AddComment("End Of Children Mark");
295 emitInt8(0);
296 }
297}
298
299void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
300 // Emit the abbreviations code (base 1 index.)
301 emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
302
303 // Emit the abbreviations data.
304 Abbrev.Emit(this);
305}
static const char * DecodeDWARFEncoding(unsigned Encoding)
This file contains constants used for implementing Dwarf debug support.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:398
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
bool isDwarf64() const
unsigned GetSizeOfEncodedValue(unsigned Encoding) const
Return the size of the encoding in bytes.
void emitDwarfDIE(const DIE &Die) const
Recursively emit Dwarf DIE tree.
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
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...
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:87
void emitDwarfStringOffset(DwarfStringPoolEntry S) const
Emit the 4- or 8-byte offset of a string from the start of its section.
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...
virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding)
Emit reference to a ttype global with a specified encoding.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:90
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset" or ".quad Label + Offset" depending on the DWARF format.
void emitInt8(int Value) const
Emit a byte directive and value.
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
void emitEncodingByte(unsigned Val, const char *Desc=nullptr) const
Emit a .byte 42 directive that corresponds to an encoding.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:105
void emitCFIInstruction(const MachineInstr &MI)
void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Encoding) const
Emit reference to a call site with a specified encoding.
void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:99
unsigned int getDwarfOffsetByteSize() const
Returns 4 for DWARF32 and 8 for DWARF64.
bool isVerbose() const
Return true if assembly output should contain comments.
Definition: AsmPrinter.h:265
bool doesDwarfUseRelocationsAcrossSections() const
Definition: AsmPrinter.h:330
void emitCallSiteValue(uint64_t Value, unsigned Encoding) const
Emit an integer value corresponding to the call site encoding.
void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:79
unsigned getNumber() const
Definition: DIE.h:101
void Emit(const AsmPrinter *AP) const
Print the abbreviation using the specified asm printer.
Definition: DIE.cpp:62
value_range values()
Definition: DIE.h:807
A structured debug information entry.
Definition: DIE.h:819
unsigned getAbbrevNumber() const
Definition: DIE.h:854
unsigned getSize() const
Definition: DIE.h:862
child_range children()
Definition: DIE.h:875
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:857
bool hasChildren() const
Definition: DIE.h:867
dwarf::Tag getTag() const
Definition: DIE.h:855
bool needsDwarfSectionOffsetDirective() const
Definition: MCAsmInfo.h:621
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:546
unsigned getAddressSpace() const
Definition: MCDwarf.h:675
unsigned getRegister2() const
Definition: MCDwarf.h:670
unsigned getRegister() const
Definition: MCDwarf.h:661
SMLoc getLoc() const
Definition: MCDwarf.h:694
int getOffset() const
Definition: MCDwarf.h:680
OpType getOperation() const
Definition: MCDwarf.h:658
StringRef getComment() const
Definition: MCDwarf.h:693
StringRef getValues() const
Definition: MCDwarf.h:688
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
Represents a location in source code.
Definition: SMLoc.h:23
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...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
LLVM Value Representation.
Definition: Value.h:74
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
StringRef AccessibilityString(unsigned Access)
Definition: Dwarf.cpp:304
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Attribute
Attributes.
Definition: Dwarf.h:123
@ DW_EH_PE_datarel
Definition: Dwarf.h:536
@ DW_EH_PE_pcrel
Definition: Dwarf.h:534
@ DW_EH_PE_sdata4
Definition: Dwarf.h:531
@ DW_EH_PE_udata2
Definition: Dwarf.h:526
@ DW_EH_PE_sdata8
Definition: Dwarf.h:532
@ DW_EH_PE_absptr
Definition: Dwarf.h:523
@ DW_EH_PE_udata4
Definition: Dwarf.h:527
@ DW_EH_PE_udata8
Definition: Dwarf.h:528
@ DW_EH_PE_uleb128
Definition: Dwarf.h:525
@ DW_EH_PE_indirect
Definition: Dwarf.h:539
@ DW_EH_PE_sleb128
Definition: Dwarf.h:529
@ DW_EH_PE_omit
Definition: Dwarf.h:524
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
@ Length
Definition: DWP.cpp:456
Description of the encoding of one expression Op.
Data for a string pool entry.