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