blob: bf01907558d6512c8cf376157f724be00bfddeda [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"
Bill Wendling88423ee2009-05-15 00:11:17 +000018#include "llvm/Target/TargetData.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000019#include "llvm/Support/ErrorHandling.h"
Chris Lattnerb01acfa2009-08-23 01:01:17 +000020#include "llvm/Support/Format.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000021using namespace llvm;
22
23//===----------------------------------------------------------------------===//
24// DIEAbbrevData Implementation
25//===----------------------------------------------------------------------===//
26
27/// Profile - Used to gather unique data for the abbreviation folding set.
28///
29void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
30 ID.AddInteger(Attribute);
31 ID.AddInteger(Form);
32}
33
34//===----------------------------------------------------------------------===//
35// DIEAbbrev Implementation
36//===----------------------------------------------------------------------===//
37
38/// Profile - Used to gather unique data for the abbreviation folding set.
39///
40void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
41 ID.AddInteger(Tag);
42 ID.AddInteger(ChildrenFlag);
43
44 // For each attribute description.
45 for (unsigned i = 0, N = Data.size(); i < N; ++i)
46 Data[i].Profile(ID);
47}
48
49/// Emit - Print the abbreviation using the specified asm printer.
50///
51void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
52 // Emit its Dwarf tag type.
53 Asm->EmitULEB128Bytes(Tag);
54 Asm->EOL(dwarf::TagString(Tag));
55
56 // Emit whether it has children DIEs.
57 Asm->EmitULEB128Bytes(ChildrenFlag);
58 Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
59
60 // For each attribute description.
61 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
62 const DIEAbbrevData &AttrData = Data[i];
63
64 // Emit attribute type.
65 Asm->EmitULEB128Bytes(AttrData.getAttribute());
66 Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
67
68 // Emit form type.
69 Asm->EmitULEB128Bytes(AttrData.getForm());
70 Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
71 }
72
73 // Mark end of abbreviation.
74 Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
75 Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
76}
77
78#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +000079void DIEAbbrev::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +000080 O << "Abbreviation @"
Chris Lattnerb01acfa2009-08-23 01:01:17 +000081 << format("0x%lx", (long)(intptr_t)this)
Bill Wendling88423ee2009-05-15 00:11:17 +000082 << " "
83 << dwarf::TagString(Tag)
84 << " "
85 << dwarf::ChildrenString(ChildrenFlag)
Chris Lattnerb01acfa2009-08-23 01:01:17 +000086 << '\n';
Bill Wendling88423ee2009-05-15 00:11:17 +000087
88 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
89 O << " "
90 << dwarf::AttributeString(Data[i].getAttribute())
91 << " "
92 << dwarf::FormEncodingString(Data[i].getForm())
Chris Lattnerb01acfa2009-08-23 01:01:17 +000093 << '\n';
Bill Wendling88423ee2009-05-15 00:11:17 +000094 }
95}
Chris Lattnerb01acfa2009-08-23 01:01:17 +000096void DIEAbbrev::dump() { print(errs()); }
Bill Wendling88423ee2009-05-15 00:11:17 +000097#endif
98
99//===----------------------------------------------------------------------===//
100// DIE Implementation
101//===----------------------------------------------------------------------===//
102
103DIE::~DIE() {
104 for (unsigned i = 0, N = Children.size(); i < N; ++i)
105 delete Children[i];
106}
107
108/// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
109///
110void DIE::AddSiblingOffset() {
111 DIEInteger *DI = new DIEInteger(0);
112 Values.insert(Values.begin(), DI);
113 Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
114}
115
Bill Wendling88423ee2009-05-15 00:11:17 +0000116#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000117void DIE::print(raw_ostream &O, unsigned IncIndent) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000118 IndentCount += IncIndent;
119 const std::string Indent(IndentCount, ' ');
120 bool isBlock = Abbrev.getTag() == 0;
121
122 if (!isBlock) {
123 O << Indent
124 << "Die: "
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000125 << format("0x%lx", (long)(intptr_t)this)
Bill Wendling88423ee2009-05-15 00:11:17 +0000126 << ", Offset: " << Offset
127 << ", Size: " << Size
128 << "\n";
129
130 O << Indent
131 << dwarf::TagString(Abbrev.getTag())
132 << " "
133 << dwarf::ChildrenString(Abbrev.getChildrenFlag());
134 } else {
135 O << "Size: " << Size;
136 }
137 O << "\n";
138
139 const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
140
141 IndentCount += 2;
142 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
143 O << Indent;
144
145 if (!isBlock)
146 O << dwarf::AttributeString(Data[i].getAttribute());
147 else
148 O << "Blk[" << i << "]";
149
150 O << " "
151 << dwarf::FormEncodingString(Data[i].getForm())
152 << " ";
153 Values[i]->print(O);
154 O << "\n";
155 }
156 IndentCount -= 2;
157
158 for (unsigned j = 0, M = Children.size(); j < M; ++j) {
159 Children[j]->print(O, 4);
160 }
161
162 if (!isBlock) O << "\n";
163 IndentCount -= IncIndent;
164}
165
166void DIE::dump() {
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000167 print(errs());
Bill Wendling88423ee2009-05-15 00:11:17 +0000168}
169#endif
170
171
172#ifndef NDEBUG
173void DIEValue::dump() {
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000174 print(errs());
Bill Wendling88423ee2009-05-15 00:11:17 +0000175}
176#endif
177
178//===----------------------------------------------------------------------===//
179// DIEInteger Implementation
180//===----------------------------------------------------------------------===//
181
182/// EmitValue - Emit integer of appropriate size.
183///
184void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
185 const AsmPrinter *Asm = D->getAsm();
186 switch (Form) {
187 case dwarf::DW_FORM_flag: // Fall thru
188 case dwarf::DW_FORM_ref1: // Fall thru
189 case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer); break;
190 case dwarf::DW_FORM_ref2: // Fall thru
191 case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer); break;
192 case dwarf::DW_FORM_ref4: // Fall thru
193 case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer); break;
194 case dwarf::DW_FORM_ref8: // Fall thru
195 case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer); break;
196 case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
197 case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
Torok Edwinc23197a2009-07-14 16:55:14 +0000198 default: llvm_unreachable("DIE Value form not supported yet");
Bill Wendling88423ee2009-05-15 00:11:17 +0000199 }
200}
201
202/// SizeOf - Determine size of integer value in bytes.
203///
204unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
205 switch (Form) {
206 case dwarf::DW_FORM_flag: // Fall thru
207 case dwarf::DW_FORM_ref1: // Fall thru
208 case dwarf::DW_FORM_data1: return sizeof(int8_t);
209 case dwarf::DW_FORM_ref2: // Fall thru
210 case dwarf::DW_FORM_data2: return sizeof(int16_t);
211 case dwarf::DW_FORM_ref4: // Fall thru
212 case dwarf::DW_FORM_data4: return sizeof(int32_t);
213 case dwarf::DW_FORM_ref8: // Fall thru
214 case dwarf::DW_FORM_data8: return sizeof(int64_t);
Chris Lattneraf76e592009-08-22 20:48:53 +0000215 case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
216 case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
Torok Edwinc23197a2009-07-14 16:55:14 +0000217 default: llvm_unreachable("DIE Value form not supported yet"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000218 }
219 return 0;
220}
221
Bill Wendling88423ee2009-05-15 00:11:17 +0000222#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000223void DIEInteger::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000224 O << "Int: " << (int64_t)Integer
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000225 << format(" 0x%llx", (unsigned long long)Integer);
Bill Wendling88423ee2009-05-15 00:11:17 +0000226}
227#endif
228
229//===----------------------------------------------------------------------===//
230// DIEString Implementation
231//===----------------------------------------------------------------------===//
232
233/// EmitValue - Emit string value.
234///
235void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
236 D->getAsm()->EmitString(Str);
237}
238
Bill Wendling88423ee2009-05-15 00:11:17 +0000239#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000240void DIEString::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000241 O << "Str: \"" << Str << "\"";
242}
243#endif
244
245//===----------------------------------------------------------------------===//
246// DIEDwarfLabel Implementation
247//===----------------------------------------------------------------------===//
248
249/// EmitValue - Emit label value.
250///
251void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
252 bool IsSmall = Form == dwarf::DW_FORM_data4;
253 D->EmitReference(Label, false, IsSmall);
254}
255
256/// SizeOf - Determine size of label value in bytes.
257///
258unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
259 if (Form == dwarf::DW_FORM_data4) return 4;
260 return TD->getPointerSize();
261}
262
Bill Wendling88423ee2009-05-15 00:11:17 +0000263#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000264void DIEDwarfLabel::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000265 O << "Lbl: ";
266 Label.print(O);
267}
268#endif
269
270//===----------------------------------------------------------------------===//
271// DIEObjectLabel Implementation
272//===----------------------------------------------------------------------===//
273
274/// EmitValue - Emit label value.
275///
276void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
277 bool IsSmall = Form == dwarf::DW_FORM_data4;
278 D->EmitReference(Label, false, IsSmall);
279}
280
281/// SizeOf - Determine size of label value in bytes.
282///
283unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
284 if (Form == dwarf::DW_FORM_data4) return 4;
285 return TD->getPointerSize();
286}
287
Bill Wendling88423ee2009-05-15 00:11:17 +0000288#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000289void DIEObjectLabel::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000290 O << "Obj: " << Label;
291}
292#endif
293
294//===----------------------------------------------------------------------===//
295// DIESectionOffset Implementation
296//===----------------------------------------------------------------------===//
297
298/// EmitValue - Emit delta value.
299///
300void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
301 bool IsSmall = Form == dwarf::DW_FORM_data4;
302 D->EmitSectionOffset(Label.getTag(), Section.getTag(),
303 Label.getNumber(), Section.getNumber(),
304 IsSmall, IsEH, UseSet);
305}
306
307/// SizeOf - Determine size of delta value in bytes.
308///
309unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
310 if (Form == dwarf::DW_FORM_data4) return 4;
311 return TD->getPointerSize();
312}
313
Bill Wendling88423ee2009-05-15 00:11:17 +0000314#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000315void DIESectionOffset::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000316 O << "Off: ";
317 Label.print(O);
318 O << "-";
319 Section.print(O);
320 O << "-" << IsEH << "-" << UseSet;
321}
322#endif
323
324//===----------------------------------------------------------------------===//
325// DIEDelta Implementation
326//===----------------------------------------------------------------------===//
327
328/// EmitValue - Emit delta value.
329///
330void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
331 bool IsSmall = Form == dwarf::DW_FORM_data4;
332 D->EmitDifference(LabelHi, LabelLo, IsSmall);
333}
334
335/// SizeOf - Determine size of delta value in bytes.
336///
337unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
338 if (Form == dwarf::DW_FORM_data4) return 4;
339 return TD->getPointerSize();
340}
341
Bill Wendling88423ee2009-05-15 00:11:17 +0000342#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000343void DIEDelta::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000344 O << "Del: ";
345 LabelHi.print(O);
346 O << "-";
347 LabelLo.print(O);
348}
349#endif
350
351//===----------------------------------------------------------------------===//
352// DIEEntry Implementation
353//===----------------------------------------------------------------------===//
354
355/// EmitValue - Emit debug information entry offset.
356///
357void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
358 D->getAsm()->EmitInt32(Entry->getOffset());
359}
360
Bill Wendling88423ee2009-05-15 00:11:17 +0000361#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000362void DIEEntry::print(raw_ostream &O) {
363 O << format("Die: 0x%lx", (long)(intptr_t)Entry);
Bill Wendling88423ee2009-05-15 00:11:17 +0000364}
365#endif
366
367//===----------------------------------------------------------------------===//
368// DIEBlock Implementation
369//===----------------------------------------------------------------------===//
370
371/// ComputeSize - calculate the size of the block.
372///
373unsigned DIEBlock::ComputeSize(const TargetData *TD) {
374 if (!Size) {
375 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
376 for (unsigned i = 0, N = Values.size(); i < N; ++i)
377 Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
378 }
379
380 return Size;
381}
382
383/// EmitValue - Emit block data.
384///
385void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
386 const AsmPrinter *Asm = D->getAsm();
387 switch (Form) {
388 case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
389 case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
390 case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
391 case dwarf::DW_FORM_block: Asm->EmitULEB128Bytes(Size); break;
Torok Edwinc23197a2009-07-14 16:55:14 +0000392 default: llvm_unreachable("Improper form for block"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000393 }
394
395 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
396 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
397 Asm->EOL();
398 Values[i]->EmitValue(D, AbbrevData[i].getForm());
399 }
400}
401
402/// SizeOf - Determine size of block data in bytes.
403///
404unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
405 switch (Form) {
406 case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
407 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
408 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
Chris Lattneraf76e592009-08-22 20:48:53 +0000409 case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
Torok Edwinc23197a2009-07-14 16:55:14 +0000410 default: llvm_unreachable("Improper form for block"); break;
Bill Wendling88423ee2009-05-15 00:11:17 +0000411 }
412 return 0;
413}
414
Bill Wendling88423ee2009-05-15 00:11:17 +0000415#ifndef NDEBUG
Chris Lattnerb01acfa2009-08-23 01:01:17 +0000416void DIEBlock::print(raw_ostream &O) {
Bill Wendling88423ee2009-05-15 00:11:17 +0000417 O << "Blk: ";
418 DIE::print(O, 5);
419}
420#endif