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