DIE.cpp revision 6f01d9c2f0a97b0dccde93a232c88f088877819f
1//===--- 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"
17#include "llvm/MC/MCAsmInfo.h"
18#include "llvm/Target/TargetData.h"
19#include "llvm/Support/ErrorHandling.h"
20#include "llvm/Support/Format.h"
21using 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
79void DIEAbbrev::print(raw_ostream &O) {
80  O << "Abbreviation @"
81    << format("0x%lx", (long)(intptr_t)this)
82    << "  "
83    << dwarf::TagString(Tag)
84    << " "
85    << dwarf::ChildrenString(ChildrenFlag)
86    << '\n';
87
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())
93      << '\n';
94  }
95}
96void DIEAbbrev::dump() { print(errs()); }
97#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
116#ifndef NDEBUG
117void DIE::print(raw_ostream &O, unsigned IncIndent) {
118  IndentCount += IncIndent;
119  const std::string Indent(IndentCount, ' ');
120  bool isBlock = Abbrev.getTag() == 0;
121
122  if (!isBlock) {
123    O << Indent
124      << "Die: "
125      << format("0x%lx", (long)(intptr_t)this)
126      << ", 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() {
167  print(errs());
168}
169#endif
170
171
172#ifndef NDEBUG
173void DIEValue::dump() {
174  print(errs());
175}
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;
198  default: llvm_unreachable("DIE Value form not supported yet");
199  }
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);
215  case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
216  case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
217  default: llvm_unreachable("DIE Value form not supported yet"); break;
218  }
219  return 0;
220}
221
222#ifndef NDEBUG
223void DIEInteger::print(raw_ostream &O) {
224  O << "Int: " << (int64_t)Integer
225    << format("  0x%llx", (unsigned long long)Integer);
226}
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
239#ifndef NDEBUG
240void DIEString::print(raw_ostream &O) {
241  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
263#ifndef NDEBUG
264void DIEDwarfLabel::print(raw_ostream &O) {
265  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
288#ifndef NDEBUG
289void DIEObjectLabel::print(raw_ostream &O) {
290  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
314#ifndef NDEBUG
315void DIESectionOffset::print(raw_ostream &O) {
316  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
342#ifndef NDEBUG
343void DIEDelta::print(raw_ostream &O) {
344  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
361#ifndef NDEBUG
362void DIEEntry::print(raw_ostream &O) {
363  O << format("Die: 0x%lx", (long)(intptr_t)Entry);
364}
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;
392  default: llvm_unreachable("Improper form for block");         break;
393  }
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);
409  case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
410  default: llvm_unreachable("Improper form for block"); break;
411  }
412  return 0;
413}
414
415#ifndef NDEBUG
416void DIEBlock::print(raw_ostream &O) {
417  O << "Blk: ";
418  DIE::print(O, 5);
419}
420#endif
421