blob: afce3ad3133b3376ae4445a639842cb4e5a15452 [file] [log] [blame]
Chris Lattner9efd1182010-04-04 19:09:29 +00001//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Dwarf emissions parts of AsmPrinter.
11//
12//===----------------------------------------------------------------------===//
13
Eric Christopher29e874d2014-03-07 22:40:37 +000014#include "ByteStreamer.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000016#include "llvm/BinaryFormat/Dwarf.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000017#include "llvm/CodeGen/AsmPrinter.h"
Frederic Riss9412d632015-03-04 02:30:17 +000018#include "llvm/CodeGen/DIE.h"
Adrian Prantlb846acc2015-03-02 22:02:36 +000019#include "llvm/CodeGen/MachineFunction.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/DataLayout.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000021#include "llvm/MC/MCAsmInfo.h"
Eric Christopher73302642015-02-19 23:29:42 +000022#include "llvm/MC/MCRegisterInfo.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000023#include "llvm/MC/MCSection.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000024#include "llvm/MC/MCStreamer.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000025#include "llvm/MC/MCSymbol.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000026#include "llvm/MC/MachineLocation.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000027#include "llvm/Support/ErrorHandling.h"
David Blaikie6054e652018-03-23 23:58:19 +000028#include "llvm/Target/TargetLoweringObjectFile.h"
Chris Lattnere619c0d2010-04-04 20:20:50 +000029#include "llvm/Target/TargetMachine.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000030using namespace llvm;
31
Chandler Carruth1b9dde02014-04-22 02:02:50 +000032#define DEBUG_TYPE "asm-printer"
33
Chris Lattneraabc6042010-04-04 23:41:46 +000034//===----------------------------------------------------------------------===//
35// Dwarf Emission Helper Routines
36//===----------------------------------------------------------------------===//
37
Chris Lattner9efd1182010-04-04 19:09:29 +000038/// EmitSLEB128 - emit the specified signed leb128 value.
David Blaikie5acff7e2013-06-23 18:31:11 +000039void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
Chris Lattner9efd1182010-04-04 19:09:29 +000040 if (isVerbose() && Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +000041 OutStreamer->AddComment(Desc);
Chris Lattner9efd1182010-04-04 19:09:29 +000042
Lang Hames9ff69c82015-04-24 19:11:51 +000043 OutStreamer->EmitSLEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000044}
45
Sam Clegg66a99e42017-09-15 20:34:47 +000046void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
47 if (isVerbose() && Desc)
48 OutStreamer->AddComment(Desc);
49
50 OutStreamer->EmitULEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000051}
52
Rafael Espindolad09b4162018-02-09 17:00:25 +000053/// Emit something like ".uleb128 Hi-Lo".
54void AsmPrinter::EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
55 const MCSymbol *Lo) const {
56 OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
57}
58
Chris Lattnerb75af3c2010-04-04 20:04:21 +000059static const char *DecodeDWARFEncoding(unsigned Encoding) {
60 switch (Encoding) {
Eric Christopher596077b2013-12-04 22:26:43 +000061 case dwarf::DW_EH_PE_absptr:
62 return "absptr";
63 case dwarf::DW_EH_PE_omit:
64 return "omit";
65 case dwarf::DW_EH_PE_pcrel:
66 return "pcrel";
Rafael Espindolad09b4162018-02-09 17:00:25 +000067 case dwarf::DW_EH_PE_uleb128:
68 return "uleb128";
69 case dwarf::DW_EH_PE_sleb128:
70 return "sleb128";
Eric Christopher596077b2013-12-04 22:26:43 +000071 case dwarf::DW_EH_PE_udata4:
72 return "udata4";
73 case dwarf::DW_EH_PE_udata8:
74 return "udata8";
75 case dwarf::DW_EH_PE_sdata4:
76 return "sdata4";
77 case dwarf::DW_EH_PE_sdata8:
78 return "sdata8";
79 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
80 return "pcrel udata4";
81 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
82 return "pcrel sdata4";
83 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
84 return "pcrel udata8";
85 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
86 return "pcrel sdata8";
87 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
88 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000089 return "indirect pcrel udata4";
Eric Christopher596077b2013-12-04 22:26:43 +000090 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
91 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000092 return "indirect pcrel sdata4";
Eric Christopher596077b2013-12-04 22:26:43 +000093 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
94 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000095 return "indirect pcrel udata8";
Eric Christopher596077b2013-12-04 22:26:43 +000096 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
97 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000098 return "indirect pcrel sdata8";
99 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000100
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000101 return "<unknown encoding>";
102}
103
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000104/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
105/// encoding. If verbose assembly output is enabled, we output comments
106/// describing the encoding. Desc is an optional string saying what the
107/// encoding is specifying (e.g. "LSDA").
Chris Lattneraabc6042010-04-04 23:41:46 +0000108void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000109 if (isVerbose()) {
Eric Christophercb7119e2013-12-04 22:29:02 +0000110 if (Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +0000111 OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
112 Twine(DecodeDWARFEncoding(Val)));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000113 else
Lang Hames9ff69c82015-04-24 19:11:51 +0000114 OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000115 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000116
Lang Hames9ff69c82015-04-24 19:11:51 +0000117 OutStreamer->EmitIntValue(Val, 1);
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000118}
119
Chris Lattnere619c0d2010-04-04 20:20:50 +0000120/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
121unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
122 if (Encoding == dwarf::DW_EH_PE_omit)
123 return 0;
Eric Christopher1d6bd412012-11-20 20:34:47 +0000124
Chris Lattnere619c0d2010-04-04 20:20:50 +0000125 switch (Encoding & 0x07) {
Eric Christopher596077b2013-12-04 22:26:43 +0000126 default:
127 llvm_unreachable("Invalid encoded value.");
128 case dwarf::DW_EH_PE_absptr:
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000129 return MF->getDataLayout().getPointerSize();
Eric Christopher596077b2013-12-04 22:26:43 +0000130 case dwarf::DW_EH_PE_udata2:
131 return 2;
132 case dwarf::DW_EH_PE_udata4:
133 return 4;
134 case dwarf::DW_EH_PE_udata8:
135 return 8;
Chris Lattnere619c0d2010-04-04 20:20:50 +0000136 }
137}
138
Eric Christopher1d6bd412012-11-20 20:34:47 +0000139void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
140 unsigned Encoding) const {
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000141 if (GV) {
142 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
Eric Christopher1d6bd412012-11-20 20:34:47 +0000143
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000144 const MCExpr *Exp =
Eric Christopher4367c7f2016-09-16 07:33:15 +0000145 TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
Lang Hames9ff69c82015-04-24 19:11:51 +0000146 OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000147 } else
Lang Hames9ff69c82015-04-24 19:11:51 +0000148 OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
Chris Lattnere619c0d2010-04-04 20:20:50 +0000149}
Chris Lattner70a4fce2010-04-04 23:25:33 +0000150
Rafael Espindola857546e2015-06-16 23:22:02 +0000151void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
152 bool ForceOffset) const {
153 if (!ForceOffset) {
154 // On COFF targets, we have to emit the special .secrel32 directive.
155 if (MAI->needsDwarfSectionOffsetDirective()) {
Keno Fischerf7d84ee2017-01-02 03:00:19 +0000156 OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
Rafael Espindola857546e2015-06-16 23:22:02 +0000157 return;
158 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000159
Rafael Espindola857546e2015-06-16 23:22:02 +0000160 // If the format uses relocations with dwarf, refer to the symbol directly.
161 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
162 OutStreamer->EmitSymbolValue(Label, 4);
163 return;
164 }
Duncan Sandsb847bf52011-03-12 13:07:37 +0000165 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000166
Chris Lattner70a4fce2010-04-04 23:25:33 +0000167 // Otherwise, emit it as a label difference from the start of the section.
Rafael Espindola063d7252015-03-10 16:58:10 +0000168 EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
Chris Lattner70a4fce2010-04-04 23:25:33 +0000169}
170
Wolfgang Pieb20a74532018-01-11 02:35:00 +0000171void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000172 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
Wolfgang Pieb20a74532018-01-11 02:35:00 +0000173 assert(S.Symbol && "No symbol available");
174 emitDwarfSymbolReference(S.Symbol);
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000175 return;
176 }
177
178 // Just emit the offset directly; no need for symbol math.
Rafael Espindola4b4d85f2018-03-29 23:32:54 +0000179 emitInt32(S.Offset);
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000180}
181
Alexey Bataev07254642018-03-22 16:43:21 +0000182void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
183 EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
184}
185
Chris Lattneraabc6042010-04-04 23:41:46 +0000186//===----------------------------------------------------------------------===//
187// Dwarf Lowering Routines
188//===----------------------------------------------------------------------===//
Chris Lattner70a4fce2010-04-04 23:25:33 +0000189
Rafael Espindola227144c2013-05-13 01:16:13 +0000190void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
191 switch (Inst.getOperation()) {
192 default:
193 llvm_unreachable("Unexpected instruction");
194 case MCCFIInstruction::OpDefCfaOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000195 OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000196 break;
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000197 case MCCFIInstruction::OpAdjustCfaOffset:
198 OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
199 break;
Rafael Espindola227144c2013-05-13 01:16:13 +0000200 case MCCFIInstruction::OpDefCfa:
Lang Hames9ff69c82015-04-24 19:11:51 +0000201 OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000202 break;
203 case MCCFIInstruction::OpDefCfaRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000204 OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
Rafael Espindola227144c2013-05-13 01:16:13 +0000205 break;
206 case MCCFIInstruction::OpOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000207 OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000208 break;
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000209 case MCCFIInstruction::OpRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000210 OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000211 break;
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000212 case MCCFIInstruction::OpWindowSave:
Lang Hames9ff69c82015-04-24 19:11:51 +0000213 OutStreamer->EmitCFIWindowSave();
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000214 break;
Luke Cheesemanf57d7d82018-12-18 10:37:42 +0000215 case MCCFIInstruction::OpNegateRAState:
216 OutStreamer->EmitCFINegateRAState();
217 break;
Oliver Stannardb14c6252014-04-02 16:10:33 +0000218 case MCCFIInstruction::OpSameValue:
Lang Hames9ff69c82015-04-24 19:11:51 +0000219 OutStreamer->EmitCFISameValue(Inst.getRegister());
Oliver Stannardb14c6252014-04-02 16:10:33 +0000220 break;
Michael Kuperstein259f1502015-10-07 07:01:31 +0000221 case MCCFIInstruction::OpGnuArgsSize:
222 OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
223 break;
224 case MCCFIInstruction::OpEscape:
225 OutStreamer->EmitCFIEscape(Inst.getValues());
226 break;
Francis Visoiu Mistrih66d2c262017-11-02 12:00:58 +0000227 case MCCFIInstruction::OpRestore:
228 OutStreamer->EmitCFIRestore(Inst.getRegister());
229 break;
Rafael Espindolabeb74c32011-04-15 20:32:03 +0000230 }
231}
Frederic Riss9412d632015-03-04 02:30:17 +0000232
233void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
Frederic Riss9412d632015-03-04 02:30:17 +0000234 // Emit the code (index) for the abbreviation.
235 if (isVerbose())
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000236 OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
237 Twine::utohexstr(Die.getOffset()) + ":0x" +
238 Twine::utohexstr(Die.getSize()) + " " +
239 dwarf::TagString(Die.getTag()));
240 EmitULEB128(Die.getAbbrevNumber());
Frederic Riss9412d632015-03-04 02:30:17 +0000241
Frederic Riss9412d632015-03-04 02:30:17 +0000242 // Emit the DIE attribute values.
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000243 for (const auto &V : Die.values()) {
244 dwarf::Attribute Attr = V.getAttribute();
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000245 assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
Frederic Riss9412d632015-03-04 02:30:17 +0000246
247 if (isVerbose()) {
Lang Hames9ff69c82015-04-24 19:11:51 +0000248 OutStreamer->AddComment(dwarf::AttributeString(Attr));
Frederic Riss9412d632015-03-04 02:30:17 +0000249 if (Attr == dwarf::DW_AT_accessibility)
Duncan P. N. Exon Smithe7e1d0c2015-05-27 22:14:58 +0000250 OutStreamer->AddComment(
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000251 dwarf::AccessibilityString(V.getDIEInteger().getValue()));
Frederic Riss9412d632015-03-04 02:30:17 +0000252 }
253
254 // Emit an attribute using the defined form.
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000255 V.EmitValue(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000256 }
257
258 // Emit the DIE children if any.
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000259 if (Die.hasChildren()) {
Duncan P. N. Exon Smith8d3197f2015-05-28 19:56:34 +0000260 for (auto &Child : Die.children())
Duncan P. N. Exon Smith827200c2015-06-25 23:52:10 +0000261 emitDwarfDIE(Child);
Frederic Riss9412d632015-03-04 02:30:17 +0000262
Lang Hames9ff69c82015-04-24 19:11:51 +0000263 OutStreamer->AddComment("End Of Children Mark");
Rafael Espindola4b4d85f2018-03-29 23:32:54 +0000264 emitInt8(0);
Frederic Riss9412d632015-03-04 02:30:17 +0000265 }
266}
267
David Blaikie6196aa02015-11-18 00:34:10 +0000268void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
269 // Emit the abbreviations code (base 1 index.)
270 EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
Frederic Riss9412d632015-03-04 02:30:17 +0000271
David Blaikie6196aa02015-11-18 00:34:10 +0000272 // Emit the abbreviations data.
273 Abbrev.Emit(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000274}