1 //===-- DWARFDebugAbbrev.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/DWARFDebugAbbrev.h" 11 #include "llvm/Support/Format.h" 12 #include "llvm/Support/raw_ostream.h" 13 using namespace llvm; 14 15 DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() { 16 clear(); 17 } 18 19 void DWARFAbbreviationDeclarationSet::clear() { 20 Offset = 0; 21 FirstAbbrCode = 0; 22 Decls.clear(); 23 } 24 25 bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data, 26 uint32_t *OffsetPtr) { 27 clear(); 28 const uint32_t BeginOffset = *OffsetPtr; 29 Offset = BeginOffset; 30 DWARFAbbreviationDeclaration AbbrDecl; 31 uint32_t PrevAbbrCode = 0; 32 while (AbbrDecl.extract(Data, OffsetPtr)) { 33 if (FirstAbbrCode == 0) { 34 FirstAbbrCode = AbbrDecl.getCode(); 35 } else { 36 if (PrevAbbrCode + 1 != AbbrDecl.getCode()) { 37 // Codes are not consecutive, can't do O(1) lookups. 38 FirstAbbrCode = UINT32_MAX; 39 } 40 } 41 PrevAbbrCode = AbbrDecl.getCode(); 42 Decls.push_back(std::move(AbbrDecl)); 43 } 44 return BeginOffset != *OffsetPtr; 45 } 46 47 void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const { 48 for (const auto &Decl : Decls) 49 Decl.dump(OS); 50 } 51 52 const DWARFAbbreviationDeclaration * 53 DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration( 54 uint32_t AbbrCode) const { 55 if (FirstAbbrCode == UINT32_MAX) { 56 for (const auto &Decl : Decls) { 57 if (Decl.getCode() == AbbrCode) 58 return &Decl; 59 } 60 return nullptr; 61 } 62 if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size()) 63 return nullptr; 64 return &Decls[AbbrCode - FirstAbbrCode]; 65 } 66 67 DWARFDebugAbbrev::DWARFDebugAbbrev() { 68 clear(); 69 } 70 71 void DWARFDebugAbbrev::clear() { 72 AbbrDeclSets.clear(); 73 PrevAbbrOffsetPos = AbbrDeclSets.end(); 74 } 75 76 void DWARFDebugAbbrev::extract(DataExtractor Data) { 77 clear(); 78 79 uint32_t Offset = 0; 80 DWARFAbbreviationDeclarationSet AbbrDecls; 81 while (Data.isValidOffset(Offset)) { 82 uint32_t CUAbbrOffset = Offset; 83 if (!AbbrDecls.extract(Data, &Offset)) 84 break; 85 AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls); 86 } 87 } 88 89 void DWARFDebugAbbrev::dump(raw_ostream &OS) const { 90 if (AbbrDeclSets.empty()) { 91 OS << "< EMPTY >\n"; 92 return; 93 } 94 95 for (const auto &I : AbbrDeclSets) { 96 OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first); 97 I.second.dump(OS); 98 } 99 } 100 101 const DWARFAbbreviationDeclarationSet* 102 DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const { 103 const auto End = AbbrDeclSets.end(); 104 if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) { 105 return &(PrevAbbrOffsetPos->second); 106 } 107 108 const auto Pos = AbbrDeclSets.find(CUAbbrOffset); 109 if (Pos != End) { 110 PrevAbbrOffsetPos = Pos; 111 return &(Pos->second); 112 } 113 114 return nullptr; 115 } 116