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