1*f4a2713aSLionel Sambuc //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc 10*f4a2713aSLionel Sambuc #include "DWARFDebugAbbrev.h" 11*f4a2713aSLionel Sambuc #include "llvm/Support/Format.h" 12*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h" 13*f4a2713aSLionel Sambuc using namespace llvm; 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc bool DWARFAbbreviationDeclarationSet::extract(DataExtractor data, 16*f4a2713aSLionel Sambuc uint32_t* offset_ptr) { 17*f4a2713aSLionel Sambuc const uint32_t beginOffset = *offset_ptr; 18*f4a2713aSLionel Sambuc Offset = beginOffset; 19*f4a2713aSLionel Sambuc clear(); 20*f4a2713aSLionel Sambuc DWARFAbbreviationDeclaration abbrevDeclaration; 21*f4a2713aSLionel Sambuc uint32_t prevAbbrAode = 0; 22*f4a2713aSLionel Sambuc while (abbrevDeclaration.extract(data, offset_ptr)) { 23*f4a2713aSLionel Sambuc Decls.push_back(abbrevDeclaration); 24*f4a2713aSLionel Sambuc if (IdxOffset == 0) { 25*f4a2713aSLionel Sambuc IdxOffset = abbrevDeclaration.getCode(); 26*f4a2713aSLionel Sambuc } else { 27*f4a2713aSLionel Sambuc if (prevAbbrAode + 1 != abbrevDeclaration.getCode()) 28*f4a2713aSLionel Sambuc IdxOffset = UINT32_MAX;// Out of order indexes, we can't do O(1) lookups 29*f4a2713aSLionel Sambuc } 30*f4a2713aSLionel Sambuc prevAbbrAode = abbrevDeclaration.getCode(); 31*f4a2713aSLionel Sambuc } 32*f4a2713aSLionel Sambuc return beginOffset != *offset_ptr; 33*f4a2713aSLionel Sambuc } 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const { 36*f4a2713aSLionel Sambuc for (unsigned i = 0, e = Decls.size(); i != e; ++i) 37*f4a2713aSLionel Sambuc Decls[i].dump(OS); 38*f4a2713aSLionel Sambuc } 39*f4a2713aSLionel Sambuc 40*f4a2713aSLionel Sambuc const DWARFAbbreviationDeclaration* 41*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode) 42*f4a2713aSLionel Sambuc const { 43*f4a2713aSLionel Sambuc if (IdxOffset == UINT32_MAX) { 44*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationCollConstIter pos; 45*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationCollConstIter end = Decls.end(); 46*f4a2713aSLionel Sambuc for (pos = Decls.begin(); pos != end; ++pos) { 47*f4a2713aSLionel Sambuc if (pos->getCode() == abbrCode) 48*f4a2713aSLionel Sambuc return &(*pos); 49*f4a2713aSLionel Sambuc } 50*f4a2713aSLionel Sambuc } else { 51*f4a2713aSLionel Sambuc uint32_t idx = abbrCode - IdxOffset; 52*f4a2713aSLionel Sambuc if (idx < Decls.size()) 53*f4a2713aSLionel Sambuc return &Decls[idx]; 54*f4a2713aSLionel Sambuc } 55*f4a2713aSLionel Sambuc return NULL; 56*f4a2713aSLionel Sambuc } 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc DWARFDebugAbbrev::DWARFDebugAbbrev() : 59*f4a2713aSLionel Sambuc AbbrevCollMap(), 60*f4a2713aSLionel Sambuc PrevAbbrOffsetPos(AbbrevCollMap.end()) {} 61*f4a2713aSLionel Sambuc 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc void DWARFDebugAbbrev::parse(DataExtractor data) { 64*f4a2713aSLionel Sambuc uint32_t offset = 0; 65*f4a2713aSLionel Sambuc 66*f4a2713aSLionel Sambuc while (data.isValidOffset(offset)) { 67*f4a2713aSLionel Sambuc uint32_t initial_cu_offset = offset; 68*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationSet abbrevDeclSet; 69*f4a2713aSLionel Sambuc 70*f4a2713aSLionel Sambuc if (abbrevDeclSet.extract(data, &offset)) 71*f4a2713aSLionel Sambuc AbbrevCollMap[initial_cu_offset] = abbrevDeclSet; 72*f4a2713aSLionel Sambuc else 73*f4a2713aSLionel Sambuc break; 74*f4a2713aSLionel Sambuc } 75*f4a2713aSLionel Sambuc PrevAbbrOffsetPos = AbbrevCollMap.end(); 76*f4a2713aSLionel Sambuc } 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc void DWARFDebugAbbrev::dump(raw_ostream &OS) const { 79*f4a2713aSLionel Sambuc if (AbbrevCollMap.empty()) { 80*f4a2713aSLionel Sambuc OS << "< EMPTY >\n"; 81*f4a2713aSLionel Sambuc return; 82*f4a2713aSLionel Sambuc } 83*f4a2713aSLionel Sambuc 84*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationCollMapConstIter pos; 85*f4a2713aSLionel Sambuc for (pos = AbbrevCollMap.begin(); pos != AbbrevCollMap.end(); ++pos) { 86*f4a2713aSLionel Sambuc OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", pos->first); 87*f4a2713aSLionel Sambuc pos->second.dump(OS); 88*f4a2713aSLionel Sambuc } 89*f4a2713aSLionel Sambuc } 90*f4a2713aSLionel Sambuc 91*f4a2713aSLionel Sambuc const DWARFAbbreviationDeclarationSet* 92*f4a2713aSLionel Sambuc DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const { 93*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationCollMapConstIter end = AbbrevCollMap.end(); 94*f4a2713aSLionel Sambuc DWARFAbbreviationDeclarationCollMapConstIter pos; 95*f4a2713aSLionel Sambuc if (PrevAbbrOffsetPos != end && 96*f4a2713aSLionel Sambuc PrevAbbrOffsetPos->first == cu_abbr_offset) { 97*f4a2713aSLionel Sambuc return &(PrevAbbrOffsetPos->second); 98*f4a2713aSLionel Sambuc } else { 99*f4a2713aSLionel Sambuc pos = AbbrevCollMap.find(cu_abbr_offset); 100*f4a2713aSLionel Sambuc PrevAbbrOffsetPos = pos; 101*f4a2713aSLionel Sambuc } 102*f4a2713aSLionel Sambuc 103*f4a2713aSLionel Sambuc if (pos != AbbrevCollMap.end()) 104*f4a2713aSLionel Sambuc return &(pos->second); 105*f4a2713aSLionel Sambuc return NULL; 106*f4a2713aSLionel Sambuc } 107