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