LLVM 20.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/MC/MCAsmInfo.h"
19#include "llvm/MC/MCDwarf.h"
20#include "llvm/MC/MCSection.h"
21#include "llvm/MC/MCStreamer.h"
22#include "llvm/MC/MCSymbol.h"
25#include <cstdint>
26using namespace llvm;
27
28#define DEBUG_TYPE "asm-printer"
29
30//===----------------------------------------------------------------------===//
31// Dwarf Emission Helper Routines
32//===----------------------------------------------------------------------===//
33
34static const char *DecodeDWARFEncoding(unsigned Encoding) {
35 switch (Encoding) {
37 return "absptr";
39 return "omit";
41 return "pcrel";
43 return "uleb128";
45 return "sleb128";
47 return "udata4";
49 return "udata8";
51 return "sdata4";
53 return "sdata8";
55 return "pcrel udata4";
57 return "pcrel sdata4";
59 return "pcrel udata8";
61 return "pcrel sdata8";
63 :
64 return "indirect pcrel udata4";
66 :
67 return "indirect pcrel sdata4";
69 :
70 return "indirect pcrel udata8";
72 :
73 return "indirect pcrel sdata8";
76 return "indirect datarel sdata4";
79 return "indirect datarel sdata8";
80 }
81
82 return "<unknown encoding>";
83}
84
85/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
86/// encoding. If verbose assembly output is enabled, we output comments
87/// describing the encoding. Desc is an optional string saying what the
88/// encoding is specifying (e.g. "LSDA").
89void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
90 if (isVerbose()) {
91 if (Desc)
92 OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
94 else
95 OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
96 }
97
98 OutStreamer->emitIntValue(Val, 1);
99}
100
101/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
102unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
103 if (Encoding == dwarf::DW_EH_PE_omit)
104 return 0;
105
106 switch (Encoding & 0x07) {
107 default:
108 llvm_unreachable("Invalid encoded value.");
110 return MAI->getCodePointerSize();
112 return 2;
114 return 4;
116 return 8;
117 }
118}
119
120void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
121 if (GV) {
123
124 const MCExpr *Exp =
125 TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
126 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
127 } else
128 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
129}
130
132 bool ForceOffset) const {
133 if (!ForceOffset) {
134 // On COFF targets, we have to emit the special .secrel32 directive.
136 assert(!isDwarf64() &&
137 "emitting DWARF64 is not implemented for COFF targets");
138 OutStreamer->emitCOFFSecRel32(Label, /*Offset=*/0);
139 return;
140 }
141
142 // If the format uses relocations with dwarf, refer to the symbol directly.
144 OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
145 return;
146 }
147 }
148
149 // Otherwise, emit it as a label difference from the start of the section.
150 emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
152}
153
156 assert(S.Symbol && "No symbol available");
158 return;
159 }
160
161 // Just emit the offset directly; no need for symbol math.
162 OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
163}
164
167}
168
170 assert(isDwarf64() || Value <= UINT32_MAX);
171 OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
172}
173
175 const Twine &Comment) const {
176 OutStreamer->emitDwarfUnitLength(Length, Comment);
177}
178
180 const Twine &Comment) const {
181 return OutStreamer->emitDwarfUnitLength(Prefix, Comment);
182}
183
185 unsigned Encoding) const {
186 // The least significant 3 bits specify the width of the encoding
187 if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
189 else
191}
192
193void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
194 // The least significant 3 bits specify the width of the encoding
195 if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
197 else
198 OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
199}
200
201//===----------------------------------------------------------------------===//
202// Dwarf Lowering Routines
203//===----------------------------------------------------------------------===//
204
206 SMLoc Loc = Inst.getLoc();
207 switch (Inst.getOperation()) {
208 default:
209 llvm_unreachable("Unexpected instruction");
211 OutStreamer->emitCFIDefCfaOffset(Inst.getOffset(), Loc);
212 break;
214 OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset(), Loc);
215 break;
217 OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset(), Loc);
218 break;
220 OutStreamer->emitCFIDefCfaRegister(Inst.getRegister(), Loc);
221 break;
223 OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
224 Inst.getAddressSpace(), Loc);
225 break;
227 OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset(), Loc);
228 break;
230 OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2(), Loc);
231 break;
233 OutStreamer->emitCFIWindowSave(Loc);
234 break;
236 OutStreamer->emitCFINegateRAState(Loc);
237 break;
239 OutStreamer->emitCFINegateRAStateWithPC(Loc);
240 break;
242 OutStreamer->emitCFISameValue(Inst.getRegister(), Loc);
243 break;
245 OutStreamer->emitCFIGnuArgsSize(Inst.getOffset(), Loc);
246 break;
248 OutStreamer->AddComment(Inst.getComment());
249 OutStreamer->emitCFIEscape(Inst.getValues(), Loc);
250 break;
252 OutStreamer->emitCFIRestore(Inst.getRegister(), Loc);
253 break;
255 OutStreamer->emitCFIUndefined(Inst.getRegister(), Loc);
256 break;
258 OutStreamer->emitCFIRememberState(Loc);
259 break;
261 OutStreamer->emitCFIRestoreState(Loc);
262 break;
264 OutStreamer->emitCFIValOffset(Inst.getRegister(), Inst.getOffset(), Loc);
265 break;
266 }
267}
268
269void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
270 // Emit the code (index) for the abbreviation.
271 if (isVerbose())
272 OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
273 Twine::utohexstr(Die.getOffset()) + ":0x" +
274 Twine::utohexstr(Die.getSize()) + " " +
275 dwarf::TagString(Die.getTag()));
277
278 // Emit the DIE attribute values.
279 for (const auto &V : Die.values()) {
280 dwarf::Attribute Attr = V.getAttribute();
281 assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
282
283 if (isVerbose()) {
284 OutStreamer->AddComment(dwarf::AttributeString(Attr));
285 if (Attr == dwarf::DW_AT_accessibility)
286 OutStreamer->AddComment(
287 dwarf::AccessibilityString(V.getDIEInteger().getValue()));
288 }
289
290 // Emit an attribute using the defined form.
291 V.emitValue(this);
292 }
293
294 // Emit the DIE children if any.
295 if (Die.hasChildren()) {
296 for (const auto &Child : Die.children())
297 emitDwarfDIE(Child);
298
299 OutStreamer->AddComment("End Of Children Mark");
300 emitInt8(0);
301 }
302}
303
304void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
305 // Emit the abbreviations code (base 1 index.)
306 emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
307
308 // Emit the abbreviations data.
309 Abbrev.Emit(this);
310}
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:408
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:89
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:92
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:107
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:101
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:257
bool doesDwarfUseRelocationsAcrossSections() const
Definition: AsmPrinter.h:322
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:587
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:518
unsigned getAddressSpace() const
Definition: MCDwarf.h:730
unsigned getRegister2() const
Definition: MCDwarf.h:725
unsigned getRegister() const
Definition: MCDwarf.h:713
SMLoc getLoc() const
Definition: MCDwarf.h:756
OpType getOperation() const
Definition: MCDwarf.h:710
StringRef getComment() const
Definition: MCDwarf.h:755
StringRef getValues() const
Definition: MCDwarf.h:750
int64_t getOffset() const
Definition: MCDwarf.h:735
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
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:336
#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:860
@ DW_EH_PE_pcrel
Definition: Dwarf.h:858
@ DW_EH_PE_sdata4
Definition: Dwarf.h:855
@ DW_EH_PE_udata2
Definition: Dwarf.h:850
@ DW_EH_PE_sdata8
Definition: Dwarf.h:856
@ DW_EH_PE_absptr
Definition: Dwarf.h:847
@ DW_EH_PE_udata4
Definition: Dwarf.h:851
@ DW_EH_PE_udata8
Definition: Dwarf.h:852
@ DW_EH_PE_uleb128
Definition: Dwarf.h:849
@ DW_EH_PE_indirect
Definition: Dwarf.h:863
@ DW_EH_PE_sleb128
Definition: Dwarf.h:853
@ DW_EH_PE_omit
Definition: Dwarf.h:848
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
Description of the encoding of one expression Op.
Data for a string pool entry.