blob: e740a56312e962cdd8555bfd8a592b4260d83f2c [file] [log] [blame]
Bill Wendling88423ee2009-05-15 00:11:17 +00001//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
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// Data structures for DWARF info entries.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DIE.h"
15#include "DwarfPrinter.h"
16#include "llvm/CodeGen/AsmPrinter.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000017#include "llvm/MC/MCAsmInfo.h"
Chris Lattner858431d2010-01-16 18:50:28 +000018#include "llvm/MC/MCSymbol.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000019#include "llvm/Target/TargetData.h"
David Greene0c8b6e62009-12-24 00:27:55 +000020#include "llvm/Support/Debug.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000021#include "llvm/Support/ErrorHandling.h"
Chris Lattnerb01acfa2009-08-23 01:01:17 +000022#include "llvm/Support/Format.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000023using namespace llvm;
24
25//===----------------------------------------------------------------------===//
26// DIEAbbrevData Implementation
27//===----------------------------------------------------------------------===//
28
29/// Profile - Used to gather unique data for the abbreviation folding set.
30///
31void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
32 ID.AddInteger(Attribute);
33 ID.AddInteger(Form);
34}
35
36//===----------------------------------------------------------------------===//
37// DIEAbbrev Implementation
38//===----------------------------------------------------------------------===//
39
40/// Profile - Used to gather unique data for the abbreviation folding set.
41///
42void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
43 ID.AddInteger(Tag);
44 ID.AddInteger(ChildrenFlag);
45
46 // For each attribute description.
47 for (unsigned i = 0, N = Data.size(); i < N; ++i)
48 Data[i].Profile(ID);
49}
50
51/// Emit - Print the abbreviation using the specified asm printer.
52///
53void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
54 // Emit its Dwarf tag type.
55 Asm->EmitULEB128Bytes(Tag);
56 Asm->EOL(dwarf::TagString(Tag));
57
58 // Emit whether it has children DIEs.
59 Asm->EmitULEB128Bytes(ChildrenFlag);
60 Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
61
62 // For each attribute description.
63 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
64 const DIEAbbrevData &AttrData = Data[i];
65
66 // Emit attribute type.
67 Asm->EmitULEB128Bytes(AttrData.getAttribute());
68 Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
69
70 // Emit form type.
71 Asm->EmitULEB128Bytes(AttrData.getForm());
72 Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
73 }
74
75 // Mark end of abbreviation.
76 Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
77 Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
78}
79
80#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +000081void DIEAbbrev::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +000082 O << "Abbreviation @"
Chris Lattnerb01acfa2009-08-23 01:01:17 +000083 << format("0x%lx", (long)(intptr_t)this)
Bill Wendling88423ee2009-05-15 00:11:17 +000084 << " "
85 << dwarf::TagString(Tag)
86 << " "
87 << dwarf::ChildrenString(ChildrenFlag)
Chris Lattnerb01acfa2009-08-23 01:01:17 +000088 << '\n';
Bill Wendling88423ee2009-05-15 00:11:17 +000089
90 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
91 O << " "
92 << dwarf::AttributeString(Data[i].getAttribute())
93 << " "
94 << dwarf::FormEncodingString(Data[i].getForm())
Chris Lattnerb01acfa2009-08-23 01:01:17 +000095 << '\n';
Bill Wendling88423ee2009-05-15 00:11:17 +000096 }
97}
David Greene0c8b6e62009-12-24 00:27:55 +000098void DIEAbbrev::dump() { print(dbgs()); }
Bill Wendling88423ee2009-05-15 00:11:17 +000099#endif
100
101//===----------------------------------------------------------------------===//
102// DIE Implementation
103//===----------------------------------------------------------------------===//
104
105DIE::~DIE() {
106 for (unsigned i = 0, N = Children.size(); i < N; ++i)
107 delete Children[i];
108}
109
Devang Patel2c4ceb12009-11-21 02:48:08 +0000110/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
Bill Wendling88423ee2009-05-15 00:11:17 +0000111///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000112void DIE::addSiblingOffset() {
Bill Wendling88423ee2009-05-15 00:11:17 +0000113 DIEInteger *DI = new DIEInteger(0);
114 Values.insert(Values.begin(), DI);
115 Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
116}
117
Bill Wendling88423ee2009-05-15 00:11:17 +0000118#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000119void DIE::print(raw_ostream &O, unsigned IncIndent) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000120 IndentCount += IncIndent;
121 const std::string Indent(IndentCount, ' ');
122 bool isBlock = Abbrev.getTag() == 0;
123
124 if (!isBlock) {
125 O << Indent
126 << "Die: "
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000127 << format("0x%lx", (long)(intptr_t)this)
Bill Wendling88423ee2009-05-15 00:11:17 +0000128 << ", Offset: " << Offset
129 << ", Size: " << Size
130 << "\n";
131
132 O << Indent
133 << dwarf::TagString(Abbrev.getTag())
134 << " "
135 << dwarf::ChildrenString(Abbrev.getChildrenFlag());
136 } else {
137 O << "Size: " << Size;
138 }
139 O << "\n";
140
141 const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
142
143 IndentCount += 2;
144 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
145 O << Indent;
146
147 if (!isBlock)
148 O << dwarf::AttributeString(Data[i].getAttribute());
149 else
150 O << "Blk[" << i << "]";
151
152 O << " "
153 << dwarf::FormEncodingString(Data[i].getForm())
154 << " ";
155 Values[i]->print(O);
156 O << "\n";
157 }
158 IndentCount -= 2;
159
160 for (unsigned j = 0, M = Children.size(); j < M; ++j) {
161 Children[j]->print(O, 4);
162 }
163
164 if (!isBlock) O << "\n";
165 IndentCount -= IncIndent;
166}
167
168void DIE::dump() {
David Greene0c8b6e62009-12-24 00:27:55 +0000169 print(dbgs());
Bill Wendling88423ee2009-05-15 00:11:17 +0000170}
171#endif
172
173
174#ifndef NDEBUG
175void DIEValue::dump() {
David Greene0c8b6e62009-12-24 00:27:55 +0000176 print(dbgs());
Bill Wendling88423ee2009-05-15 00:11:17 +0000177}
178#endif
179
180//===----------------------------------------------------------------------===//
181// DIEInteger Implementation
182//===----------------------------------------------------------------------===//
183
184/// EmitValue - Emit integer of appropriate size.
185///
186void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
187 const AsmPrinter *Asm = D->getAsm();
188 switch (Form) {
189 case dwarf::DW_FORM_flag: // Fall thru
190 case dwarf::DW_FORM_ref1: // Fall thru
191 case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer); break;
192 case dwarf::DW_FORM_ref2: // Fall thru
193 case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer); break;
194 case dwarf::DW_FORM_ref4: // Fall thru
195 case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer); break;
196 case dwarf::DW_FORM_ref8: // Fall thru
197 case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer); break;
198 case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
199 case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
Torok Edwinc23197a2009-07-14 16:55:14 +0000200 default: llvm_unreachable("DIE Value form not supported yet");
Bill Wendling88423ee2009-05-15 00:11:17 +0000201 }
202}
203
204/// SizeOf - Determine size of integer value in bytes.
205///
206unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
207 switch (Form) {
208 case dwarf::DW_FORM_flag: // Fall thru
209 case dwarf::DW_FORM_ref1: // Fall thru
210 case dwarf::DW_FORM_data1: return sizeof(int8_t);
211 case dwarf::DW_FORM_ref2: // Fall thru
212 case dwarf::DW_FORM_data2: return sizeof(int16_t);
213 case dwarf::DW_FORM_ref4: // Fall thru
214 case dwarf::DW_FORM_data4: return sizeof(int32_t);
215 case dwarf::DW_FORM_ref8: // Fall thru
216 case dwarf::DW_FORM_data8: return sizeof(int64_t);
Chris Lattneraf76e592009-08-22 20:48:53 +0000217 case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
218 case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
Torok Edwinc23197a2009-07-14 16:55:14 +0000219 default: llvm_unreachable("DIE Value form not supported yet"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000220 }
221 return 0;
222}
223
Bill Wendling88423ee2009-05-15 00:11:17 +0000224#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000225void DIEInteger::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000226 O << "Int: " << (int64_t)Integer
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000227 << format(" 0x%llx", (unsigned long long)Integer);
Bill Wendling88423ee2009-05-15 00:11:17 +0000228}
229#endif
230
231//===----------------------------------------------------------------------===//
232// DIEString Implementation
233//===----------------------------------------------------------------------===//
234
235/// EmitValue - Emit string value.
236///
237void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
238 D->getAsm()->EmitString(Str);
239}
240
Bill Wendling88423ee2009-05-15 00:11:17 +0000241#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000242void DIEString::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000243 O << "Str: \"" << Str << "\"";
244}
245#endif
246
247//===----------------------------------------------------------------------===//
248// DIEDwarfLabel Implementation
249//===----------------------------------------------------------------------===//
250
251/// EmitValue - Emit label value.
252///
253void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
254 bool IsSmall = Form == dwarf::DW_FORM_data4;
255 D->EmitReference(Label, false, IsSmall);
256}
257
258/// SizeOf - Determine size of label value in bytes.
259///
260unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
261 if (Form == dwarf::DW_FORM_data4) return 4;
262 return TD->getPointerSize();
263}
264
Bill Wendling88423ee2009-05-15 00:11:17 +0000265#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000266void DIEDwarfLabel::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000267 O << "Lbl: ";
268 Label.print(O);
269}
270#endif
271
272//===----------------------------------------------------------------------===//
273// DIEObjectLabel Implementation
274//===----------------------------------------------------------------------===//
275
276/// EmitValue - Emit label value.
277///
278void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
279 bool IsSmall = Form == dwarf::DW_FORM_data4;
Chris Lattner858431d2010-01-16 18:50:28 +0000280 D->EmitReference(Sym, false, IsSmall);
Bill Wendling88423ee2009-05-15 00:11:17 +0000281}
282
283/// SizeOf - Determine size of label value in bytes.
284///
285unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
286 if (Form == dwarf::DW_FORM_data4) return 4;
287 return TD->getPointerSize();
288}
289
Bill Wendling88423ee2009-05-15 00:11:17 +0000290#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000291void DIEObjectLabel::print(raw_ostream &O) {
Chris Lattner858431d2010-01-16 18:50:28 +0000292 O << "Obj: " << Sym->getName();
Bill Wendling88423ee2009-05-15 00:11:17 +0000293}
294#endif
295
296//===----------------------------------------------------------------------===//
297// DIESectionOffset Implementation
298//===----------------------------------------------------------------------===//
299
300/// EmitValue - Emit delta value.
301///
302void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
303 bool IsSmall = Form == dwarf::DW_FORM_data4;
304 D->EmitSectionOffset(Label.getTag(), Section.getTag(),
305 Label.getNumber(), Section.getNumber(),
306 IsSmall, IsEH, UseSet);
307}
308
309/// SizeOf - Determine size of delta value in bytes.
310///
311unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
312 if (Form == dwarf::DW_FORM_data4) return 4;
313 return TD->getPointerSize();
314}
315
Bill Wendling88423ee2009-05-15 00:11:17 +0000316#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000317void DIESectionOffset::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000318 O << "Off: ";
319 Label.print(O);
320 O << "-";
321 Section.print(O);
322 O << "-" << IsEH << "-" << UseSet;
323}
324#endif
325
326//===----------------------------------------------------------------------===//
327// DIEDelta Implementation
328//===----------------------------------------------------------------------===//
329
330/// EmitValue - Emit delta value.
331///
332void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
333 bool IsSmall = Form == dwarf::DW_FORM_data4;
334 D->EmitDifference(LabelHi, LabelLo, IsSmall);
335}
336
337/// SizeOf - Determine size of delta value in bytes.
338///
339unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
340 if (Form == dwarf::DW_FORM_data4) return 4;
341 return TD->getPointerSize();
342}
343
Bill Wendling88423ee2009-05-15 00:11:17 +0000344#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000345void DIEDelta::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000346 O << "Del: ";
347 LabelHi.print(O);
348 O << "-";
349 LabelLo.print(O);
350}
351#endif
352
353//===----------------------------------------------------------------------===//
354// DIEEntry Implementation
355//===----------------------------------------------------------------------===//
356
357/// EmitValue - Emit debug information entry offset.
358///
359void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
360 D->getAsm()->EmitInt32(Entry->getOffset());
361}
362
Bill Wendling88423ee2009-05-15 00:11:17 +0000363#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000364void DIEEntry::print(raw_ostream &O) {
365 O << format("Die: 0x%lx", (long)(intptr_t)Entry);
Bill Wendling88423ee2009-05-15 00:11:17 +0000366}
367#endif
368
369//===----------------------------------------------------------------------===//
370// DIEBlock Implementation
371//===----------------------------------------------------------------------===//
372
373/// ComputeSize - calculate the size of the block.
374///
375unsigned DIEBlock::ComputeSize(const TargetData *TD) {
376 if (!Size) {
377 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
378 for (unsigned i = 0, N = Values.size(); i < N; ++i)
379 Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
380 }
381
382 return Size;
383}
384
385/// EmitValue - Emit block data.
386///
387void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
388 const AsmPrinter *Asm = D->getAsm();
389 switch (Form) {
390 case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
391 case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
392 case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
393 case dwarf::DW_FORM_block: Asm->EmitULEB128Bytes(Size); break;
Torok Edwinc23197a2009-07-14 16:55:14 +0000394 default: llvm_unreachable("Improper form for block"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000395 }
396
397 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
398 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
399 Asm->EOL();
400 Values[i]->EmitValue(D, AbbrevData[i].getForm());
401 }
402}
403
404/// SizeOf - Determine size of block data in bytes.
405///
406unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
407 switch (Form) {
408 case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
409 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
410 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
Chris Lattneraf76e592009-08-22 20:48:53 +0000411 case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
Torok Edwinc23197a2009-07-14 16:55:14 +0000412 default: llvm_unreachable("Improper form for block"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000413 }
414 return 0;
415}
416
Bill Wendling88423ee2009-05-15 00:11:17 +0000417#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000418void DIEBlock::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000419 O << "Blk: ";
420 DIE::print(O, 5);
421}
422#endif