blob: 3f144c0659f062ae1497420060b4ac5de7c6cce9 [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"
Adrian Prantl92da14b2015-03-02 22:02:33 +000015#include "DwarfDebug.h"
Adrian Prantlb16d9eb2015-01-12 22:19:22 +000016#include "DwarfExpression.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000018#include "llvm/BinaryFormat/Dwarf.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000019#include "llvm/CodeGen/AsmPrinter.h"
Frederic Riss9412d632015-03-04 02:30:17 +000020#include "llvm/CodeGen/DIE.h"
Adrian Prantlb846acc2015-03-02 22:02:36 +000021#include "llvm/CodeGen/MachineFunction.h"
Eric Christopher73302642015-02-19 23:29:42 +000022#include "llvm/CodeGen/MachineModuleInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/DataLayout.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000024#include "llvm/MC/MCAsmInfo.h"
Eric Christopher73302642015-02-19 23:29:42 +000025#include "llvm/MC/MCRegisterInfo.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000026#include "llvm/MC/MCSection.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000027#include "llvm/MC/MCStreamer.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000028#include "llvm/MC/MCSymbol.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000029#include "llvm/MC/MachineLocation.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000030#include "llvm/Support/ErrorHandling.h"
Chris Lattnere619c0d2010-04-04 20:20:50 +000031#include "llvm/Target/TargetLoweringObjectFile.h"
32#include "llvm/Target/TargetMachine.h"
Adrian Prantl92da14b2015-03-02 22:02:33 +000033#include "llvm/Target/TargetSubtargetInfo.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000034using namespace llvm;
35
Chandler Carruth1b9dde02014-04-22 02:02:50 +000036#define DEBUG_TYPE "asm-printer"
37
Chris Lattneraabc6042010-04-04 23:41:46 +000038//===----------------------------------------------------------------------===//
39// Dwarf Emission Helper Routines
40//===----------------------------------------------------------------------===//
41
Chris Lattner9efd1182010-04-04 19:09:29 +000042/// EmitSLEB128 - emit the specified signed leb128 value.
David Blaikie5acff7e2013-06-23 18:31:11 +000043void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
Chris Lattner9efd1182010-04-04 19:09:29 +000044 if (isVerbose() && Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +000045 OutStreamer->AddComment(Desc);
Chris Lattner9efd1182010-04-04 19:09:29 +000046
Lang Hames9ff69c82015-04-24 19:11:51 +000047 OutStreamer->EmitSLEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000048}
49
Maksim Panchenko07b754d2015-09-19 04:01:19 +000050/// EmitULEB128 - emit the specified unsigned leb128 value.
Sam Clegg66a99e42017-09-15 20:34:47 +000051void AsmPrinter::EmitPaddedULEB128(uint64_t Value, unsigned PadTo,
52 const char *Desc) const {
Chris Lattner9efd1182010-04-04 19:09:29 +000053 if (isVerbose() && Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +000054 OutStreamer->AddComment(Desc);
Rafael Espindola38d07562010-11-04 18:17:08 +000055
Sam Clegg66a99e42017-09-15 20:34:47 +000056 OutStreamer->EmitPaddedULEB128IntValue(Value, PadTo);
57}
58
59void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
60 if (isVerbose() && Desc)
61 OutStreamer->AddComment(Desc);
62
63 OutStreamer->EmitULEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000064}
65
Chris Lattnerb75af3c2010-04-04 20:04:21 +000066static const char *DecodeDWARFEncoding(unsigned Encoding) {
67 switch (Encoding) {
Eric Christopher596077b2013-12-04 22:26:43 +000068 case dwarf::DW_EH_PE_absptr:
69 return "absptr";
70 case dwarf::DW_EH_PE_omit:
71 return "omit";
72 case dwarf::DW_EH_PE_pcrel:
73 return "pcrel";
74 case dwarf::DW_EH_PE_udata4:
75 return "udata4";
76 case dwarf::DW_EH_PE_udata8:
77 return "udata8";
78 case dwarf::DW_EH_PE_sdata4:
79 return "sdata4";
80 case dwarf::DW_EH_PE_sdata8:
81 return "sdata8";
82 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
83 return "pcrel udata4";
84 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
85 return "pcrel sdata4";
86 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
87 return "pcrel udata8";
88 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
89 return "pcrel sdata8";
90 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
91 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000092 return "indirect pcrel udata4";
Eric Christopher596077b2013-12-04 22:26:43 +000093 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
94 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000095 return "indirect pcrel sdata4";
Eric Christopher596077b2013-12-04 22:26:43 +000096 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
97 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +000098 return "indirect pcrel udata8";
Eric Christopher596077b2013-12-04 22:26:43 +000099 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
100 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000101 return "indirect pcrel sdata8";
102 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000103
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000104 return "<unknown encoding>";
105}
106
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000107/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
108/// encoding. If verbose assembly output is enabled, we output comments
109/// describing the encoding. Desc is an optional string saying what the
110/// encoding is specifying (e.g. "LSDA").
Chris Lattneraabc6042010-04-04 23:41:46 +0000111void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000112 if (isVerbose()) {
Eric Christophercb7119e2013-12-04 22:29:02 +0000113 if (Desc)
Lang Hames9ff69c82015-04-24 19:11:51 +0000114 OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
115 Twine(DecodeDWARFEncoding(Val)));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000116 else
Lang Hames9ff69c82015-04-24 19:11:51 +0000117 OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000118 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000119
Lang Hames9ff69c82015-04-24 19:11:51 +0000120 OutStreamer->EmitIntValue(Val, 1);
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000121}
122
Chris Lattnere619c0d2010-04-04 20:20:50 +0000123/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
124unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
125 if (Encoding == dwarf::DW_EH_PE_omit)
126 return 0;
Eric Christopher1d6bd412012-11-20 20:34:47 +0000127
Chris Lattnere619c0d2010-04-04 20:20:50 +0000128 switch (Encoding & 0x07) {
Eric Christopher596077b2013-12-04 22:26:43 +0000129 default:
130 llvm_unreachable("Invalid encoded value.");
131 case dwarf::DW_EH_PE_absptr:
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000132 return MF->getDataLayout().getPointerSize();
Eric Christopher596077b2013-12-04 22:26:43 +0000133 case dwarf::DW_EH_PE_udata2:
134 return 2;
135 case dwarf::DW_EH_PE_udata4:
136 return 4;
137 case dwarf::DW_EH_PE_udata8:
138 return 8;
Chris Lattnere619c0d2010-04-04 20:20:50 +0000139 }
140}
141
Eric Christopher1d6bd412012-11-20 20:34:47 +0000142void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
143 unsigned Encoding) const {
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000144 if (GV) {
145 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
Eric Christopher1d6bd412012-11-20 20:34:47 +0000146
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000147 const MCExpr *Exp =
Eric Christopher4367c7f2016-09-16 07:33:15 +0000148 TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
Lang Hames9ff69c82015-04-24 19:11:51 +0000149 OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000150 } else
Lang Hames9ff69c82015-04-24 19:11:51 +0000151 OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
Chris Lattnere619c0d2010-04-04 20:20:50 +0000152}
Chris Lattner70a4fce2010-04-04 23:25:33 +0000153
Rafael Espindola857546e2015-06-16 23:22:02 +0000154void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
155 bool ForceOffset) const {
156 if (!ForceOffset) {
157 // On COFF targets, we have to emit the special .secrel32 directive.
158 if (MAI->needsDwarfSectionOffsetDirective()) {
Keno Fischerf7d84ee2017-01-02 03:00:19 +0000159 OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
Rafael Espindola857546e2015-06-16 23:22:02 +0000160 return;
161 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000162
Rafael Espindola857546e2015-06-16 23:22:02 +0000163 // If the format uses relocations with dwarf, refer to the symbol directly.
164 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
165 OutStreamer->EmitSymbolValue(Label, 4);
166 return;
167 }
Duncan Sandsb847bf52011-03-12 13:07:37 +0000168 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000169
Chris Lattner70a4fce2010-04-04 23:25:33 +0000170 // Otherwise, emit it as a label difference from the start of the section.
Rafael Espindola063d7252015-03-10 16:58:10 +0000171 EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
Chris Lattner70a4fce2010-04-04 23:25:33 +0000172}
173
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000174void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
175 if (MAI->doesDwarfUseRelocationsAcrossSections()) {
Rafael Espindola857546e2015-06-16 23:22:02 +0000176 emitDwarfSymbolReference(S.getSymbol());
Duncan P. N. Exon Smith1e0d94e2015-05-24 16:48:54 +0000177 return;
178 }
179
180 // Just emit the offset directly; no need for symbol math.
181 EmitInt32(S.getOffset());
182}
183
Chris Lattneraabc6042010-04-04 23:41:46 +0000184//===----------------------------------------------------------------------===//
185// Dwarf Lowering Routines
186//===----------------------------------------------------------------------===//
Chris Lattner70a4fce2010-04-04 23:25:33 +0000187
Rafael Espindola227144c2013-05-13 01:16:13 +0000188void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
189 switch (Inst.getOperation()) {
190 default:
191 llvm_unreachable("Unexpected instruction");
192 case MCCFIInstruction::OpDefCfaOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000193 OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000194 break;
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000195 case MCCFIInstruction::OpAdjustCfaOffset:
196 OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
197 break;
Rafael Espindola227144c2013-05-13 01:16:13 +0000198 case MCCFIInstruction::OpDefCfa:
Lang Hames9ff69c82015-04-24 19:11:51 +0000199 OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000200 break;
201 case MCCFIInstruction::OpDefCfaRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000202 OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
Rafael Espindola227144c2013-05-13 01:16:13 +0000203 break;
204 case MCCFIInstruction::OpOffset:
Lang Hames9ff69c82015-04-24 19:11:51 +0000205 OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
Rafael Espindola227144c2013-05-13 01:16:13 +0000206 break;
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000207 case MCCFIInstruction::OpRegister:
Lang Hames9ff69c82015-04-24 19:11:51 +0000208 OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000209 break;
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000210 case MCCFIInstruction::OpWindowSave:
Lang Hames9ff69c82015-04-24 19:11:51 +0000211 OutStreamer->EmitCFIWindowSave();
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000212 break;
Oliver Stannardb14c6252014-04-02 16:10:33 +0000213 case MCCFIInstruction::OpSameValue:
Lang Hames9ff69c82015-04-24 19:11:51 +0000214 OutStreamer->EmitCFISameValue(Inst.getRegister());
Oliver Stannardb14c6252014-04-02 16:10:33 +0000215 break;
Michael Kuperstein259f1502015-10-07 07:01:31 +0000216 case MCCFIInstruction::OpGnuArgsSize:
217 OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
218 break;
219 case MCCFIInstruction::OpEscape:
220 OutStreamer->EmitCFIEscape(Inst.getValues());
221 break;
Francis Visoiu Mistrih66d2c262017-11-02 12:00:58 +0000222 case MCCFIInstruction::OpRestore:
223 OutStreamer->EmitCFIRestore(Inst.getRegister());
224 break;
Rafael Espindolabeb74c32011-04-15 20:32:03 +0000225 }
226}
Frederic Riss9412d632015-03-04 02:30:17 +0000227
228void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
Frederic Riss9412d632015-03-04 02:30:17 +0000229 // Emit the code (index) for the abbreviation.
230 if (isVerbose())
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000231 OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
232 Twine::utohexstr(Die.getOffset()) + ":0x" +
233 Twine::utohexstr(Die.getSize()) + " " +
234 dwarf::TagString(Die.getTag()));
235 EmitULEB128(Die.getAbbrevNumber());
Frederic Riss9412d632015-03-04 02:30:17 +0000236
Frederic Riss9412d632015-03-04 02:30:17 +0000237 // Emit the DIE attribute values.
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000238 for (const auto &V : Die.values()) {
239 dwarf::Attribute Attr = V.getAttribute();
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000240 assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
Frederic Riss9412d632015-03-04 02:30:17 +0000241
242 if (isVerbose()) {
Lang Hames9ff69c82015-04-24 19:11:51 +0000243 OutStreamer->AddComment(dwarf::AttributeString(Attr));
Frederic Riss9412d632015-03-04 02:30:17 +0000244 if (Attr == dwarf::DW_AT_accessibility)
Duncan P. N. Exon Smithe7e1d0c2015-05-27 22:14:58 +0000245 OutStreamer->AddComment(
Duncan P. N. Exon Smith88a8fc52015-05-27 22:44:06 +0000246 dwarf::AccessibilityString(V.getDIEInteger().getValue()));
Frederic Riss9412d632015-03-04 02:30:17 +0000247 }
248
249 // Emit an attribute using the defined form.
Duncan P. N. Exon Smith9dbb5012015-06-24 18:48:11 +0000250 V.EmitValue(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000251 }
252
253 // Emit the DIE children if any.
Duncan P. N. Exon Smith815a6eb52015-05-27 22:31:41 +0000254 if (Die.hasChildren()) {
Duncan P. N. Exon Smith8d3197f2015-05-28 19:56:34 +0000255 for (auto &Child : Die.children())
Duncan P. N. Exon Smith827200c2015-06-25 23:52:10 +0000256 emitDwarfDIE(Child);
Frederic Riss9412d632015-03-04 02:30:17 +0000257
Lang Hames9ff69c82015-04-24 19:11:51 +0000258 OutStreamer->AddComment("End Of Children Mark");
Frederic Riss9412d632015-03-04 02:30:17 +0000259 EmitInt8(0);
260 }
261}
262
David Blaikie6196aa02015-11-18 00:34:10 +0000263void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
264 // Emit the abbreviations code (base 1 index.)
265 EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
Frederic Riss9412d632015-03-04 02:30:17 +0000266
David Blaikie6196aa02015-11-18 00:34:10 +0000267 // Emit the abbreviations data.
268 Abbrev.Emit(this);
Frederic Riss9412d632015-03-04 02:30:17 +0000269}