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