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