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