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