blob: ce4aae3d319db74c1e8fa86712a63e27fb5b6467 [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 Prantlb16d9eb2015-01-12 22:19:22 +000015#include "DwarfExpression.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000016#include "llvm/CodeGen/AsmPrinter.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/ADT/Twine.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000018#include "llvm/IR/DataLayout.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000019#include "llvm/MC/MCAsmInfo.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000020#include "llvm/MC/MCSection.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000021#include "llvm/MC/MCStreamer.h"
Chris Lattner70a4fce2010-04-04 23:25:33 +000022#include "llvm/MC/MCSymbol.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000023#include "llvm/MC/MachineLocation.h"
24#include "llvm/Support/Dwarf.h"
25#include "llvm/Support/ErrorHandling.h"
Anton Korobeynikov2f931282011-01-10 12:39:04 +000026#include "llvm/Target/TargetFrameLowering.h"
Chris Lattnere619c0d2010-04-04 20:20:50 +000027#include "llvm/Target/TargetLoweringObjectFile.h"
28#include "llvm/Target/TargetMachine.h"
Chris Lattneraabc6042010-04-04 23:41:46 +000029#include "llvm/Target/TargetRegisterInfo.h"
Eric Christopherd9134482014-08-04 21:25:23 +000030#include "llvm/Target/TargetSubtargetInfo.h"
Chris Lattner9efd1182010-04-04 19:09:29 +000031using namespace llvm;
32
Chandler Carruth1b9dde02014-04-22 02:02:50 +000033#define DEBUG_TYPE "asm-printer"
34
Adrian Prantlb16d9eb2015-01-12 22:19:22 +000035/// DwarfExpression implementation for .debug_loc entries.
36class DebugLocDwarfExpression : public DwarfExpression {
37 ByteStreamer &BS;
38public:
39 DebugLocDwarfExpression(TargetMachine &TM, ByteStreamer &BS)
40 : DwarfExpression(TM), BS(BS) {}
41
42 void EmitOp(uint8_t Op, const char* Comment) override;
43 void EmitSigned(int Value) override;
44 void EmitUnsigned(unsigned Value) override;
45};
46
47void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char* Comment) {
48 BS.EmitInt8(Op, Comment
49 ? Twine(Comment)+Twine(" ")+Twine(dwarf::OperationEncodingString(Op))
50 : dwarf::OperationEncodingString(Op));
51}
52void DebugLocDwarfExpression::EmitSigned(int Value) {
53 BS.EmitSLEB128(Value, Twine(Value));
54}
55void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) {
56 BS.EmitULEB128(Value, Twine(Value));
57}
58
59
Chris Lattneraabc6042010-04-04 23:41:46 +000060//===----------------------------------------------------------------------===//
61// Dwarf Emission Helper Routines
62//===----------------------------------------------------------------------===//
63
Chris Lattner9efd1182010-04-04 19:09:29 +000064/// EmitSLEB128 - emit the specified signed leb128 value.
David Blaikie5acff7e2013-06-23 18:31:11 +000065void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
Chris Lattner9efd1182010-04-04 19:09:29 +000066 if (isVerbose() && Desc)
67 OutStreamer.AddComment(Desc);
Chris Lattner9efd1182010-04-04 19:09:29 +000068
Benjamin Kramerc74798d2011-11-05 11:52:44 +000069 OutStreamer.EmitSLEB128IntValue(Value);
Chris Lattner9efd1182010-04-04 19:09:29 +000070}
71
72/// EmitULEB128 - emit the specified signed leb128 value.
David Blaikie5acff7e2013-06-23 18:31:11 +000073void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc,
Chris Lattner9efd1182010-04-04 19:09:29 +000074 unsigned PadTo) const {
75 if (isVerbose() && Desc)
76 OutStreamer.AddComment(Desc);
Rafael Espindola38d07562010-11-04 18:17:08 +000077
Eric Christopherbf7bc492013-01-09 03:52:05 +000078 OutStreamer.EmitULEB128IntValue(Value, PadTo);
Chris Lattner9efd1182010-04-04 19:09:29 +000079}
80
Chris Lattnerbaf2be02010-04-04 20:01:25 +000081/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
82void AsmPrinter::EmitCFAByte(unsigned Val) const {
83 if (isVerbose()) {
Eric Christopher596077b2013-12-04 22:26:43 +000084 if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset + 64)
Eric Christopher1d6bd412012-11-20 20:34:47 +000085 OutStreamer.AddComment("DW_CFA_offset + Reg (" +
Eric Christopher596077b2013-12-04 22:26:43 +000086 Twine(Val - dwarf::DW_CFA_offset) + ")");
Chris Lattnerbaf2be02010-04-04 20:01:25 +000087 else
88 OutStreamer.AddComment(dwarf::CallFrameString(Val));
89 }
Eric Christopherce0cfce2013-01-09 01:35:34 +000090 OutStreamer.EmitIntValue(Val, 1);
Chris Lattnerbaf2be02010-04-04 20:01:25 +000091}
92
Chris Lattnerb75af3c2010-04-04 20:04:21 +000093static const char *DecodeDWARFEncoding(unsigned Encoding) {
94 switch (Encoding) {
Eric Christopher596077b2013-12-04 22:26:43 +000095 case dwarf::DW_EH_PE_absptr:
96 return "absptr";
97 case dwarf::DW_EH_PE_omit:
98 return "omit";
99 case dwarf::DW_EH_PE_pcrel:
100 return "pcrel";
101 case dwarf::DW_EH_PE_udata4:
102 return "udata4";
103 case dwarf::DW_EH_PE_udata8:
104 return "udata8";
105 case dwarf::DW_EH_PE_sdata4:
106 return "sdata4";
107 case dwarf::DW_EH_PE_sdata8:
108 return "sdata8";
109 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
110 return "pcrel udata4";
111 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
112 return "pcrel sdata4";
113 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
114 return "pcrel udata8";
115 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
116 return "pcrel sdata8";
117 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
118 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000119 return "indirect pcrel udata4";
Eric Christopher596077b2013-12-04 22:26:43 +0000120 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
121 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000122 return "indirect pcrel sdata4";
Eric Christopher596077b2013-12-04 22:26:43 +0000123 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
124 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000125 return "indirect pcrel udata8";
Eric Christopher596077b2013-12-04 22:26:43 +0000126 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
127 :
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000128 return "indirect pcrel sdata8";
129 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000130
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000131 return "<unknown encoding>";
132}
133
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000134/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
135/// encoding. If verbose assembly output is enabled, we output comments
136/// describing the encoding. Desc is an optional string saying what the
137/// encoding is specifying (e.g. "LSDA").
Chris Lattneraabc6042010-04-04 23:41:46 +0000138void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000139 if (isVerbose()) {
Eric Christophercb7119e2013-12-04 22:29:02 +0000140 if (Desc)
Eric Christopher596077b2013-12-04 22:26:43 +0000141 OutStreamer.AddComment(Twine(Desc) + " Encoding = " +
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000142 Twine(DecodeDWARFEncoding(Val)));
143 else
Eric Christopher596077b2013-12-04 22:26:43 +0000144 OutStreamer.AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000145 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000146
Eric Christopherce0cfce2013-01-09 01:35:34 +0000147 OutStreamer.EmitIntValue(Val, 1);
Chris Lattnerb75af3c2010-04-04 20:04:21 +0000148}
149
Chris Lattnere619c0d2010-04-04 20:20:50 +0000150/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
151unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
152 if (Encoding == dwarf::DW_EH_PE_omit)
153 return 0;
Eric Christopher1d6bd412012-11-20 20:34:47 +0000154
Chris Lattnere619c0d2010-04-04 20:20:50 +0000155 switch (Encoding & 0x07) {
Eric Christopher596077b2013-12-04 22:26:43 +0000156 default:
157 llvm_unreachable("Invalid encoded value.");
158 case dwarf::DW_EH_PE_absptr:
Eric Christopherd9134482014-08-04 21:25:23 +0000159 return TM.getSubtargetImpl()->getDataLayout()->getPointerSize();
Eric Christopher596077b2013-12-04 22:26:43 +0000160 case dwarf::DW_EH_PE_udata2:
161 return 2;
162 case dwarf::DW_EH_PE_udata4:
163 return 4;
164 case dwarf::DW_EH_PE_udata8:
165 return 8;
Chris Lattnere619c0d2010-04-04 20:20:50 +0000166 }
167}
168
Eric Christopher1d6bd412012-11-20 20:34:47 +0000169void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
170 unsigned Encoding) const {
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000171 if (GV) {
172 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
Eric Christopher1d6bd412012-11-20 20:34:47 +0000173
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000174 const MCExpr *Exp =
Rafael Espindoladaeafb42014-02-19 17:23:20 +0000175 TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI, OutStreamer);
Eric Christopherce0cfce2013-01-09 01:35:34 +0000176 OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
Anton Korobeynikov097b0e92012-11-19 21:17:20 +0000177 } else
Eric Christopherce0cfce2013-01-09 01:35:34 +0000178 OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
Chris Lattnere619c0d2010-04-04 20:20:50 +0000179}
Chris Lattner70a4fce2010-04-04 23:25:33 +0000180
181/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its
182/// section. This can be done with a special directive if the target supports
183/// it (e.g. cygwin) or by emitting it as an offset from a label at the start
184/// of the section.
185///
186/// SectionLabel is a temporary label emitted at the start of the section that
187/// Label lives in.
188void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
189 const MCSymbol *SectionLabel) const {
190 // On COFF targets, we have to emit the special .secrel32 directive.
Matt Arsenault034ca0f2013-04-22 22:49:11 +0000191 if (MAI->needsDwarfSectionOffsetDirective()) {
Rafael Espindolad3df3d32011-12-17 01:14:52 +0000192 OutStreamer.EmitCOFFSecRel32(Label);
Chris Lattner70a4fce2010-04-04 23:25:33 +0000193 return;
194 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000195
Chris Lattner70a4fce2010-04-04 23:25:33 +0000196 // Get the section that we're referring to, based on SectionLabel.
197 const MCSection &Section = SectionLabel->getSection();
Eric Christopher1d6bd412012-11-20 20:34:47 +0000198
Chris Lattner70a4fce2010-04-04 23:25:33 +0000199 // If Label has already been emitted, verify that it is in the same section as
200 // section label for sanity.
201 assert((!Label->isInSection() || &Label->getSection() == &Section) &&
202 "Section offset using wrong section base for label");
Eric Christopher1d6bd412012-11-20 20:34:47 +0000203
Duncan Sandsb847bf52011-03-12 13:07:37 +0000204 // If the section in question will end up with an address of 0 anyway, we can
205 // just emit an absolute reference to save a relocation.
206 if (Section.isBaseAddressKnownZero()) {
Eric Christopherce0cfce2013-01-09 01:35:34 +0000207 OutStreamer.EmitSymbolValue(Label, 4);
Duncan Sandsb847bf52011-03-12 13:07:37 +0000208 return;
209 }
Eric Christopher1d6bd412012-11-20 20:34:47 +0000210
Chris Lattner70a4fce2010-04-04 23:25:33 +0000211 // Otherwise, emit it as a label difference from the start of the section.
212 EmitLabelDifference(Label, SectionLabel, 4);
213}
214
Adrian Prantl42a0d8c2014-04-27 18:50:45 +0000215// Some targets do not provide a DWARF register number for every
216// register. This function attempts to emit a DWARF register by
217// emitting a piece of a super-register or by piecing together
218// multiple subregisters that alias the register.
Adrian Prantld34db652014-04-27 18:25:45 +0000219void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer,
220 const MachineLocation &MLoc,
221 unsigned PieceSizeInBits,
222 unsigned PieceOffsetInBits) const {
Adrian Prantl42a0d8c2014-04-27 18:50:45 +0000223 assert(MLoc.isReg() && "MLoc must be a register");
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000224 DebugLocDwarfExpression Expr(TM, Streamer);
225 Expr.AddMachineRegPiece(MLoc.getReg(), PieceSizeInBits, PieceOffsetInBits);
226}
Eric Christopher698a8ab2014-03-07 01:44:14 +0000227
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000228void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer,
229 unsigned PieceSizeInBits,
230 unsigned PieceOffsetInBits) const {
231 DebugLocDwarfExpression Expr(TM, Streamer);
232 Expr.AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
Eric Christopher698a8ab2014-03-07 01:44:14 +0000233}
234
235/// EmitDwarfRegOp - Emit dwarf register operation.
Eric Christopher29e874d2014-03-07 22:40:37 +0000236void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
237 const MachineLocation &MLoc,
Eric Christopher698a8ab2014-03-07 01:44:14 +0000238 bool Indirect) const {
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000239 DebugLocDwarfExpression Expr(TM, Streamer);
Eric Christopherd9134482014-08-04 21:25:23 +0000240 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
Eric Christopher698a8ab2014-03-07 01:44:14 +0000241 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
242 if (Reg < 0) {
243 // We assume that pointers are always in an addressable register.
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000244 if (Indirect || MLoc.isIndirect())
Eric Christopher698a8ab2014-03-07 01:44:14 +0000245 // FIXME: We have no reasonable way of handling errors in here. The
246 // caller might be in the middle of a dwarf expression. We should
247 // probably assert that Reg >= 0 once debug info generation is more
248 // mature.
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000249 return Expr.EmitOp(dwarf::DW_OP_nop,
250 "nop (could not find a dwarf register number)");
Eric Christopher698a8ab2014-03-07 01:44:14 +0000251
252 // Attempt to find a valid super- or sub-register.
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000253 return Expr.AddMachineRegPiece(MLoc.getReg());
Eric Christopher698a8ab2014-03-07 01:44:14 +0000254 }
255
256 if (MLoc.isIndirect())
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000257 Expr.AddRegIndirect(Reg, MLoc.getOffset(), Indirect);
Eric Christopher698a8ab2014-03-07 01:44:14 +0000258 else if (Indirect)
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000259 Expr.AddRegIndirect(Reg, 0, false);
Eric Christopher698a8ab2014-03-07 01:44:14 +0000260 else
Adrian Prantlb16d9eb2015-01-12 22:19:22 +0000261 Expr.AddReg(Reg);
Eric Christopher698a8ab2014-03-07 01:44:14 +0000262}
263
Chris Lattneraabc6042010-04-04 23:41:46 +0000264//===----------------------------------------------------------------------===//
265// Dwarf Lowering Routines
266//===----------------------------------------------------------------------===//
Chris Lattner70a4fce2010-04-04 23:25:33 +0000267
Rafael Espindola227144c2013-05-13 01:16:13 +0000268void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
269 switch (Inst.getOperation()) {
270 default:
271 llvm_unreachable("Unexpected instruction");
272 case MCCFIInstruction::OpDefCfaOffset:
273 OutStreamer.EmitCFIDefCfaOffset(Inst.getOffset());
274 break;
275 case MCCFIInstruction::OpDefCfa:
276 OutStreamer.EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
277 break;
278 case MCCFIInstruction::OpDefCfaRegister:
279 OutStreamer.EmitCFIDefCfaRegister(Inst.getRegister());
280 break;
281 case MCCFIInstruction::OpOffset:
282 OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
283 break;
Venkatraman Govindaraju4c0cdd72013-09-26 15:11:00 +0000284 case MCCFIInstruction::OpRegister:
285 OutStreamer.EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
286 break;
Venkatraman Govindaraju3816d432013-09-26 14:49:40 +0000287 case MCCFIInstruction::OpWindowSave:
288 OutStreamer.EmitCFIWindowSave();
289 break;
Oliver Stannardb14c6252014-04-02 16:10:33 +0000290 case MCCFIInstruction::OpSameValue:
291 OutStreamer.EmitCFISameValue(Inst.getRegister());
292 break;
Rafael Espindolabeb74c32011-04-15 20:32:03 +0000293 }
294}