DIE.cpp revision 138c7ff4431ac423bea28f9381a14c5239dfb920
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/ADT/Twine.h"
17#include "llvm/CodeGen/AsmPrinter.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/Target/TargetData.h"
22#include "llvm/Support/Allocator.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/Format.h"
26#include "llvm/Support/FormattedStream.h"
27using namespace llvm;
28
29//===----------------------------------------------------------------------===//
30// DIEAbbrevData Implementation
31//===----------------------------------------------------------------------===//
32
33/// Profile - Used to gather unique data for the abbreviation folding set.
34///
35void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
36  ID.AddInteger(Attribute);
37  ID.AddInteger(Form);
38}
39
40//===----------------------------------------------------------------------===//
41// DIEAbbrev Implementation
42//===----------------------------------------------------------------------===//
43
44/// Profile - Used to gather unique data for the abbreviation folding set.
45///
46void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
47  ID.AddInteger(Tag);
48  ID.AddInteger(ChildrenFlag);
49
50  // For each attribute description.
51  for (unsigned i = 0, N = Data.size(); i < N; ++i)
52    Data[i].Profile(ID);
53}
54
55/// Emit - Print the abbreviation using the specified asm printer.
56///
57void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
58  // Emit its Dwarf tag type.
59  // FIXME: Doing work even in non-asm-verbose runs.
60  DP->EmitULEB128(Tag, dwarf::TagString(Tag));
61
62  // Emit whether it has children DIEs.
63  // FIXME: Doing work even in non-asm-verbose runs.
64  DP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
65
66  // For each attribute description.
67  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
68    const DIEAbbrevData &AttrData = Data[i];
69
70    // Emit attribute type.
71    // FIXME: Doing work even in non-asm-verbose runs.
72    DP->EmitULEB128(AttrData.getAttribute(),
73                    dwarf::AttributeString(AttrData.getAttribute()));
74
75    // Emit form type.
76    // FIXME: Doing work even in non-asm-verbose runs.
77    DP->EmitULEB128(AttrData.getForm(),
78                    dwarf::FormEncodingString(AttrData.getForm()));
79  }
80
81  // Mark end of abbreviation.
82  DP->EmitULEB128(0, "EOM(1)");
83  DP->EmitULEB128(0, "EOM(2)");
84}
85
86#ifndef NDEBUG
87void DIEAbbrev::print(raw_ostream &O) {
88  O << "Abbreviation @"
89    << format("0x%lx", (long)(intptr_t)this)
90    << "  "
91    << dwarf::TagString(Tag)
92    << " "
93    << dwarf::ChildrenString(ChildrenFlag)
94    << '\n';
95
96  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
97    O << "  "
98      << dwarf::AttributeString(Data[i].getAttribute())
99      << "  "
100      << dwarf::FormEncodingString(Data[i].getForm())
101      << '\n';
102  }
103}
104void DIEAbbrev::dump() { print(dbgs()); }
105#endif
106
107//===----------------------------------------------------------------------===//
108// DIE Implementation
109//===----------------------------------------------------------------------===//
110
111DIE::~DIE() {
112  for (unsigned i = 0, N = Children.size(); i < N; ++i)
113    delete Children[i];
114}
115
116/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
117///
118DIEValue *DIE::addSiblingOffset(BumpPtrAllocator &A) {
119  DIEInteger *DI = new (A) DIEInteger(0);
120  Values.insert(Values.begin(), DI);
121  Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
122  return DI;
123}
124
125#ifndef NDEBUG
126void DIE::print(raw_ostream &O, unsigned IncIndent) {
127  IndentCount += IncIndent;
128  const std::string Indent(IndentCount, ' ');
129  bool isBlock = Abbrev.getTag() == 0;
130
131  if (!isBlock) {
132    O << Indent
133      << "Die: "
134      << format("0x%lx", (long)(intptr_t)this)
135      << ", Offset: " << Offset
136      << ", Size: " << Size << "\n";
137
138    O << Indent
139      << dwarf::TagString(Abbrev.getTag())
140      << " "
141      << dwarf::ChildrenString(Abbrev.getChildrenFlag()) << "\n";
142  } else {
143    O << "Size: " << Size << "\n";
144  }
145
146  const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
147
148  IndentCount += 2;
149  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
150    O << Indent;
151
152    if (!isBlock)
153      O << dwarf::AttributeString(Data[i].getAttribute());
154    else
155      O << "Blk[" << i << "]";
156
157    O <<  "  "
158      << dwarf::FormEncodingString(Data[i].getForm())
159      << " ";
160    Values[i]->print(O);
161    O << "\n";
162  }
163  IndentCount -= 2;
164
165  for (unsigned j = 0, M = Children.size(); j < M; ++j) {
166    Children[j]->print(O, 4);
167  }
168
169  if (!isBlock) O << "\n";
170  IndentCount -= IncIndent;
171}
172
173void DIE::dump() {
174  print(dbgs());
175}
176#endif
177
178
179#ifndef NDEBUG
180void DIEValue::dump() {
181  print(dbgs());
182}
183#endif
184
185//===----------------------------------------------------------------------===//
186// DIEInteger Implementation
187//===----------------------------------------------------------------------===//
188
189/// EmitValue - Emit integer of appropriate size.
190///
191void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
192  const AsmPrinter *Asm = D->getAsm();
193  unsigned Size = ~0U;
194  switch (Form) {
195  case dwarf::DW_FORM_flag:  // Fall thru
196  case dwarf::DW_FORM_ref1:  // Fall thru
197  case dwarf::DW_FORM_data1: Size = 1; break;
198  case dwarf::DW_FORM_ref2:  // Fall thru
199  case dwarf::DW_FORM_data2: Size = 2; break;
200  case dwarf::DW_FORM_ref4:  // Fall thru
201  case dwarf::DW_FORM_data4: Size = 4; break;
202  case dwarf::DW_FORM_ref8:  // Fall thru
203  case dwarf::DW_FORM_data8: Size = 8; break;
204  case dwarf::DW_FORM_udata: D->EmitULEB128(Integer); return;
205  case dwarf::DW_FORM_sdata: D->EmitSLEB128(Integer, ""); return;
206  default: llvm_unreachable("DIE Value form not supported yet");
207  }
208  Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
209}
210
211/// SizeOf - Determine size of integer value in bytes.
212///
213unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
214  switch (Form) {
215  case dwarf::DW_FORM_flag:  // Fall thru
216  case dwarf::DW_FORM_ref1:  // Fall thru
217  case dwarf::DW_FORM_data1: return sizeof(int8_t);
218  case dwarf::DW_FORM_ref2:  // Fall thru
219  case dwarf::DW_FORM_data2: return sizeof(int16_t);
220  case dwarf::DW_FORM_ref4:  // Fall thru
221  case dwarf::DW_FORM_data4: return sizeof(int32_t);
222  case dwarf::DW_FORM_ref8:  // Fall thru
223  case dwarf::DW_FORM_data8: return sizeof(int64_t);
224  case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
225  case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
226  default: llvm_unreachable("DIE Value form not supported yet"); break;
227  }
228  return 0;
229}
230
231#ifndef NDEBUG
232void DIEInteger::print(raw_ostream &O) {
233  O << "Int: " << (int64_t)Integer
234    << format("  0x%llx", (unsigned long long)Integer);
235}
236#endif
237
238//===----------------------------------------------------------------------===//
239// DIEString Implementation
240//===----------------------------------------------------------------------===//
241
242/// EmitValue - Emit string value.
243///
244void DIEString::EmitValue(DwarfPrinter *D, unsigned Form) const {
245  D->getAsm()->OutStreamer.EmitBytes(Str, /*addrspace*/0);
246  // Emit nul terminator.
247  D->getAsm()->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
248}
249
250#ifndef NDEBUG
251void DIEString::print(raw_ostream &O) {
252  O << "Str: \"" << Str << "\"";
253}
254#endif
255
256//===----------------------------------------------------------------------===//
257// DIELabel Implementation
258//===----------------------------------------------------------------------===//
259
260/// EmitValue - Emit label value.
261///
262void DIELabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
263  bool IsSmall = Form == dwarf::DW_FORM_data4;
264  unsigned Size = IsSmall ? 4 : D->getTargetData()->getPointerSize();
265  D->getAsm()->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
266}
267
268/// SizeOf - Determine size of label value in bytes.
269///
270unsigned DIELabel::SizeOf(const TargetData *TD, unsigned Form) const {
271  if (Form == dwarf::DW_FORM_data4) return 4;
272  return TD->getPointerSize();
273}
274
275#ifndef NDEBUG
276void DIELabel::print(raw_ostream &O) {
277  O << "Lbl: " << Label->getName();
278}
279#endif
280
281//===----------------------------------------------------------------------===//
282// DIEDelta Implementation
283//===----------------------------------------------------------------------===//
284
285/// EmitValue - Emit delta value.
286///
287void DIEDelta::EmitValue(DwarfPrinter *D, unsigned Form) const {
288  bool IsSmall = Form == dwarf::DW_FORM_data4;
289  D->EmitDifference(LabelHi, LabelLo, IsSmall);
290}
291
292/// SizeOf - Determine size of delta value in bytes.
293///
294unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
295  if (Form == dwarf::DW_FORM_data4) return 4;
296  return TD->getPointerSize();
297}
298
299#ifndef NDEBUG
300void DIEDelta::print(raw_ostream &O) {
301  O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
302}
303#endif
304
305//===----------------------------------------------------------------------===//
306// DIEEntry Implementation
307//===----------------------------------------------------------------------===//
308
309/// EmitValue - Emit debug information entry offset.
310///
311void DIEEntry::EmitValue(DwarfPrinter *D, unsigned Form) const {
312  D->getAsm()->EmitInt32(Entry->getOffset());
313}
314
315#ifndef NDEBUG
316void DIEEntry::print(raw_ostream &O) {
317  O << format("Die: 0x%lx", (long)(intptr_t)Entry);
318}
319#endif
320
321//===----------------------------------------------------------------------===//
322// DIEBlock Implementation
323//===----------------------------------------------------------------------===//
324
325/// ComputeSize - calculate the size of the block.
326///
327unsigned DIEBlock::ComputeSize(const TargetData *TD) {
328  if (!Size) {
329    const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
330    for (unsigned i = 0, N = Values.size(); i < N; ++i)
331      Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
332  }
333
334  return Size;
335}
336
337/// EmitValue - Emit block data.
338///
339void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const {
340  const AsmPrinter *Asm = D->getAsm();
341  switch (Form) {
342  case dwarf::DW_FORM_block1: Asm->EmitInt8(Size);         break;
343  case dwarf::DW_FORM_block2: Asm->EmitInt16(Size);        break;
344  case dwarf::DW_FORM_block4: Asm->EmitInt32(Size);        break;
345  case dwarf::DW_FORM_block:  D->EmitULEB128(Size);        break;
346  default: llvm_unreachable("Improper form for block");    break;
347  }
348
349  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
350  for (unsigned i = 0, N = Values.size(); i < N; ++i)
351    Values[i]->EmitValue(D, AbbrevData[i].getForm());
352}
353
354/// SizeOf - Determine size of block data in bytes.
355///
356unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
357  switch (Form) {
358  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
359  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
360  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
361  case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
362  default: llvm_unreachable("Improper form for block"); break;
363  }
364  return 0;
365}
366
367#ifndef NDEBUG
368void DIEBlock::print(raw_ostream &O) {
369  O << "Blk: ";
370  DIE::print(O, 5);
371}
372#endif
373