blob: 7a62b6bfc6a4502424f9f72b8534eb8b16f63a97 [file] [log] [blame]
Chris Lattner9efd1182010-04-04 19:09:29 +00001//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner9efd1182010-04-04 19:09:29 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Dwarf emissions parts of AsmPrinter.
10//
11//===----------------------------------------------------------------------===//
12
Eric Christopher29e874d2014-03-07 22:40:37 +000013#include "ByteStreamer.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000014#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000015#include "llvm/BinaryFormat/Dwarf.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000016#include "llvm/CodeGen/AsmPrinter.h"
Frederic Riss9412d632015-03-04 02:30:17 +000017#include "llvm/CodeGen/DIE.h"
Adrian Prantlb846acc2015-03-02 22:02:36 +000018#include "llvm/CodeGen/MachineFunction.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000019#include "llvm/IR/DataLayout.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000020#include "llvm/MC/MCAsmInfo.h"
Eric Christopher73302642015-02-19 23:29:42 +000021#include "llvm/MC/MCRegisterInfo.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000022#include "llvm/MC/MCSection.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000023#include "llvm/MC/MCStreamer.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000024#include "llvm/MC/MCSymbol.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000025#include "llvm/MC/MachineLocation.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000026#include "llvm/Support/ErrorHandling.h"
David Blaikie6054e652018-03-23 23:58:19 +000027#include "llvm/Target/TargetLoweringObjectFile.h"
Chris Lattnere619c0d2010-04-04 20:20:50 +000028#include "llvm/Target/TargetMachine.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000029using namespace llvm;
30
Chandler Carruth1b9dde02014-04-22 02:02:50 +000031#define DEBUG_TYPE "asm-printer"
32
Chris Lattneraabc6042010-04-04 23:41:46 +000033//===----------------------------------------------------------------------===//
34// Dwarf Emission Helper Routines
35//===----------------------------------------------------------------------===//
36
Chris Lattner9efd1182010-04-04 19:09:29 +000037/// EmitSLEB128 - emit the specified signed leb128 value.
David Blaikie5acff7e2013-06-23 18:31:11 +000038void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
Chris Lattner9efd1182010-04-04 19:09:29 +000039 if (isVerbose() && Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +000040 OutStreamer->AddComment(Desc);
Chris Lattner9efd1182010-04-04 19:09:29 +000041
Lang Hames9ff69c82015-04-24 19:11:51 +000042 OutStreamer->EmitSLEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000043}
44
Sam Clegg66a99e42017-09-15 20:34:47 +000045void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
46 if (isVerbose() && Desc)
47 OutStreamer->AddComment(Desc);
48
49 OutStreamer->EmitULEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000050}
51
Rafael Espindolad09b4162018-02-09 17:00:25 +000052/// Emit something like ".uleb128 Hi-Lo".
53void AsmPrinter::EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
54 const MCSymbol *Lo) const {
55 OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
56}
57
Chris Lattnerb75af3c2010-04-04 20:04:21 +000058static const char *DecodeDWARFEncoding(unsigned Encoding) {
59 switch (Encoding) {
Eric Christopher596077b2013-12-04 22:26:43 +000060 case dwarf::DW_EH_PE_absptr:
61 return "absptr";
62 case dwarf::DW_EH_PE_omit:
63 return "omit";
64 case dwarf::DW_EH_PE_pcrel:
65 return "pcrel";
Rafael Espindolad09b4162018-02-09 17:00:25 +000066 case dwarf::DW_EH_PE_uleb128:
67 return "uleb128";
68 case dwarf::DW_EH_PE_sleb128:
69 return "sleb128";
Eric Christopher596077b2013-12-04 22:26:43 +000070 case dwarf::DW_EH_PE_udata4:
71 return "udata4";
72 case dwarf::DW_EH_PE_udata8:
73 return "udata8";
74 case dwarf::DW_EH_PE_sdata4:
75 return "sdata4";
76 case dwarf::DW_EH_PE_sdata8:
77 return "sdata8";
78 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
79 return "pcrel udata4";
80 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
81 return "pcrel sdata4";
82 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
83 return "pcrel udata8";
84 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
85 return "pcrel sdata8";
86 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
87 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000088 return "indirect pcrel udata4";
Eric Christopher596077b2013-12-04 22:26:43 +000089 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
90 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000091 return "indirect pcrel sdata4";
Eric Christopher596077b2013-12-04 22:26:43 +000092 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
93 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000094 return "indirect pcrel udata8";
Eric Christopher596077b2013-12-04 22:26:43 +000095 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
96 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000097 return "indirect pcrel sdata8";
98 }
Eric Christopher1d6bd412012-11-20 20:34:47 +000099
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000100 return "<unknown encoding>";
101}
102
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000103/// 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").
Chris Lattneraabc6042010-04-04 23:41:46 +0000107void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000108 if (isVerbose()) {
Eric Christophercb7119e2013-12-04 22:29:02 +0000109 if (Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +0000110 OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
111 Twine(DecodeDWARFEncoding(Val)));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000112 else
Lang Hames9ff69c82015-04-24 19:11:51 +0000113 OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000114 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000115
Lang Hames9ff69c82015-04-24 19:11:51 +0000116 OutStreamer->EmitIntValue(Val, 1);
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000117}
118
Chris Lattnere619c0d2010-04-04 20:20:50 +0000119/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
120unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
121 if (Encoding == dwarf::DW_EH_PE_omit)
122 return 0;
Eric Christopher1d6bd412012-11-20 20:34:47 +0000123
Chris Lattnere619c0d2010-04-04 20:20:50 +0000124 switch (Encoding & 0x07) {
Eric Christopher596077b2013-12-04 22:26:43 +0000125 default:
126 llvm_unreachable("Invalid encoded value.");
127 case dwarf::DW_EH_PE_absptr:
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000128 return MF->getDataLayout().getPointerSize();
Eric Christopher596077b2013-12-04 22:26:43 +0000129 case dwarf::DW_EH_PE_udata2:
130 return 2;
131 case dwarf::DW_EH_PE_udata4:
132 return 4;
133 case dwarf::DW_EH_PE_udata8:
134 return 8;
Chris Lattnere619c0d2010-04-04 20:20:50 +0000135 }
136}
137
Eric Christopher1d6bd412012-11-20 20:34:47 +0000138void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
139 unsigned Encoding) const {
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000140 if (GV) {
141 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
Eric Christopher1d6bd412012-11-20 20:34:47 +0000142
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000143 const MCExpr *Exp =
Eric Christopher4367c7f2016-09-16 07:33:15 +0000144 TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
Lang Hames9ff69c82015-04-24 19:11:51 +0000145 OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000146 } else
Lang Hames9ff69c82015-04-24 19:11:51 +0000147 OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
Chris Lattnere619c0d2010-04-04 20:20:50 +0000148}
Chris Lattner70a4fce2010-04-04 23:25:33 +0000149
Rafael Espindola857546e2015-06-16 23:22:02 +0000150void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
151 bool ForceOffset) const {
152 if (!ForceOffset) {
153 // On COFF targets, we have to emit the special .secrel32 directive.
154 if (MAI->needsDwarfSectionOffsetDirective()) {
Keno Fischerf7d84ee2017-01-02 03:00:19 +0000155 OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
Rafael Espindola857546e2015-06-16 23:22:02 +0000156 return;
157 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000158
Rafael Espindola857546e2015-06-16 23:22:02 +0000159 // If the format uses relocations with dwarf, refer to the symbol directly.
160 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
161 OutStreamer->EmitSymbolValue(Label, 4);
162 return;
163 }
Duncan Sandsb847bf52011-03-12 13:07:37 +0000164 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000165
Chris Lattner70a4fce2010-04-04 23:25:33 +0000166 // Otherwise, emit it as a label difference from the start of the section.
Rafael Espindola063d7252015-03-10 16:58:10 +0000167 EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
Chris Lattner70a4fce2010-04-04 23:25:33 +0000168}
169
Wolfgang Pieb20a74532018-01-11 02:35:00 +0000170void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000171 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
Wolfgang Pieb20a74532018-01-11 02:35:00 +0000172 assert(S.Symbol && "No symbol available");
173 emitDwarfSymbolReference(S.Symbol);
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000174 return;
175 }
176
177 // Just emit the offset directly; no need for symbol math.
Rafael Espindola4b4d85f2018-03-29 23:32:54 +0000178 emitInt32(S.Offset);
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000179}
180
Alexey Bataev07254642018-03-22 16:43:21 +0000181void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
182 EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
183}
184
Chris Lattneraabc6042010-04-04 23:41:46 +0000185//===----------------------------------------------------------------------===//
186// Dwarf Lowering Routines
187//===----------------------------------------------------------------------===//
Chris Lattner70a4fce2010-04-04 23:25:33 +0000188
Rafael Espindola227144c2013-05-13 01:16:13 +0000189void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
190 switch (Inst.getOperation()) {
191 default:
192 llvm_unreachable("Unexpected instruction");
193 case MCCFIInstruction::OpDefCfaOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000194 OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000195 break;
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000196 case MCCFIInstruction::OpAdjustCfaOffset:
197 OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
198 break;
Rafael Espindola227144c2013-05-13 01:16:13 +0000199 case MCCFIInstruction::OpDefCfa:
Lang Hames9ff69c82015-04-24 19:11:51 +0000200 OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000201 break;
202 case MCCFIInstruction::OpDefCfaRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000203 OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
Rafael Espindola227144c2013-05-13 01:16:13 +0000204 break;
205 case MCCFIInstruction::OpOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000206 OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000207 break;
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000208 case MCCFIInstruction::OpRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000209 OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000210 break;
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000211 case MCCFIInstruction::OpWindowSave:
Lang Hames9ff69c82015-04-24 19:11:51 +0000212 OutStreamer->EmitCFIWindowSave();
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000213 break;
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000214 case MCCFIInstruction::OpNegateRAState:
215 OutStreamer->EmitCFINegateRAState();
216 break;
Oliver Stannardb14c6252014-04-02 16:10:33 +0000217 case MCCFIInstruction::OpSameValue:
Lang Hames9ff69c82015-04-24 19:11:51 +0000218 OutStreamer->EmitCFISameValue(Inst.getRegister());
Oliver Stannardb14c6252014-04-02 16:10:33 +0000219 break;
Michael Kuperstein259f1502015-10-07 07:01:31 +0000220 case MCCFIInstruction::OpGnuArgsSize:
221 OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
222 break;
223 case MCCFIInstruction::OpEscape:
224 OutStreamer->EmitCFIEscape(Inst.getValues());
225 break;
Francis Visoiu Mistrih66d2c262017-11-02 12:00:58 +0000226 case MCCFIInstruction::OpRestore:
227 OutStreamer->EmitCFIRestore(Inst.getRegister());
228 break;
Rafael Espindolabeb74c32011-04-15 20:32:03 +0000229 }
230}
Frederic Riss9412d632015-03-04 02:30:17 +0000231
232void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
Frederic Riss9412d632015-03-04 02:30:17 +0000233 // Emit the code (index) for the abbreviation.
234 if (isVerbose())
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000235 OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
236 Twine::utohexstr(Die.getOffset()) + ":0x" +
237 Twine::utohexstr(Die.getSize()) + " " +
238 dwarf::TagString(Die.getTag()));
239 EmitULEB128(Die.getAbbrevNumber());
Frederic Riss9412d632015-03-04 02:30:17 +0000240
Frederic Riss9412d632015-03-04 02:30:17 +0000241 // Emit the DIE attribute values.
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000242 for (const auto &V : Die.values()) {
243 dwarf::Attribute Attr = V.getAttribute();
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000244 assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
Frederic Riss9412d632015-03-04 02:30:17 +0000245
246 if (isVerbose()) {
Lang Hames9ff69c82015-04-24 19:11:51 +0000247 OutStreamer->AddComment(dwarf::AttributeString(Attr));
Frederic Riss9412d632015-03-04 02:30:17 +0000248 if (Attr == dwarf::DW_AT_accessibility)
Duncan P. N. Exon Smithe7e1d0c2015-05-27 22:14:58 +0000249 OutStreamer->AddComment(
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000250 dwarf::AccessibilityString(V.getDIEInteger().getValue()));
Frederic Riss9412d632015-03-04 02:30:17 +0000251 }
252
253 // Emit an attribute using the defined form.
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000254 V.EmitValue(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000255 }
256
257 // Emit the DIE children if any.
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000258 if (Die.hasChildren()) {
Duncan P. N. Exon Smith8d3197f2015-05-28 19:56:34 +0000259 for (auto &Child : Die.children())
Duncan P. N. Exon Smith827200c2015-06-25 23:52:10 +0000260 emitDwarfDIE(Child);
Frederic Riss9412d632015-03-04 02:30:17 +0000261
Lang Hames9ff69c82015-04-24 19:11:51 +0000262 OutStreamer->AddComment("End Of Children Mark");
Rafael Espindola4b4d85f2018-03-29 23:32:54 +0000263 emitInt8(0);
Frederic Riss9412d632015-03-04 02:30:17 +0000264 }
265}
266
David Blaikie6196aa02015-11-18 00:34:10 +0000267void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
268 // Emit the abbreviations code (base 1 index.)
269 EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
Frederic Riss9412d632015-03-04 02:30:17 +0000270
David Blaikie6196aa02015-11-18 00:34:10 +0000271 // Emit the abbreviations data.
272 Abbrev.Emit(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000273}