1 //===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===// 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 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 11 #include "llvm/Support/Dwarf.h" 12 #include "llvm/Support/Format.h" 13 #include "llvm/Support/raw_ostream.h" 14 using namespace llvm; 15 using namespace dwarf; 16 17 void DWARFAbbreviationDeclaration::clear() { 18 Code = 0; 19 Tag = DW_TAG_null; 20 HasChildren = false; 21 AttributeSpecs.clear(); 22 } 23 24 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() { 25 clear(); 26 } 27 28 bool 29 DWARFAbbreviationDeclaration::extract(DataExtractor Data, 30 uint32_t* OffsetPtr) { 31 clear(); 32 Code = Data.getULEB128(OffsetPtr); 33 if (Code == 0) { 34 return false; 35 } 36 Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr)); 37 if (Tag == DW_TAG_null) { 38 clear(); 39 return false; 40 } 41 uint8_t ChildrenByte = Data.getU8(OffsetPtr); 42 HasChildren = (ChildrenByte == DW_CHILDREN_yes); 43 44 while (true) { 45 auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr)); 46 auto F = static_cast<Form>(Data.getULEB128(OffsetPtr)); 47 if (A && F) { 48 AttributeSpecs.push_back(AttributeSpec(A, F)); 49 } else if (A == 0 && F == 0) { 50 // We successfully reached the end of this abbreviation declaration 51 // since both attribute and form are zero. 52 break; 53 } else { 54 // Attribute and form pairs must either both be non-zero, in which case 55 // they are added to the abbreviation declaration, or both be zero to 56 // terminate the abbrevation declaration. In this case only one was 57 // zero which is an error. 58 clear(); 59 return false; 60 } 61 } 62 return true; 63 } 64 65 void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { 66 auto tagString = TagString(getTag()); 67 OS << '[' << getCode() << "] "; 68 if (!tagString.empty()) 69 OS << tagString; 70 else 71 OS << format("DW_TAG_Unknown_%x", getTag()); 72 OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n'; 73 for (const AttributeSpec &Spec : AttributeSpecs) { 74 OS << '\t'; 75 auto attrString = AttributeString(Spec.Attr); 76 if (!attrString.empty()) 77 OS << attrString; 78 else 79 OS << format("DW_AT_Unknown_%x", Spec.Attr); 80 OS << '\t'; 81 auto formString = FormEncodingString(Spec.Form); 82 if (!formString.empty()) 83 OS << formString; 84 else 85 OS << format("DW_FORM_Unknown_%x", Spec.Form); 86 OS << '\n'; 87 } 88 OS << '\n'; 89 } 90 91 uint32_t 92 DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute attr) const { 93 for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) { 94 if (AttributeSpecs[i].Attr == attr) 95 return i; 96 } 97 return -1U; 98 } 99