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