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