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