172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// 272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// The LLVM Compiler Infrastructure 472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source 672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details. 772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===// 972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h" 1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h" 1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm; 1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() { 1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer clear(); 17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFAbbreviationDeclarationSet::clear() { 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset = 0; 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FirstAbbrCode = 0; 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Decls.clear(); 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data, 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t *OffsetPtr) { 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines clear(); 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const uint32_t BeginOffset = *OffsetPtr; 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset = BeginOffset; 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWARFAbbreviationDeclaration AbbrDecl; 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t PrevAbbrCode = 0; 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (AbbrDecl.extract(Data, OffsetPtr)) { 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (FirstAbbrCode == 0) { 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FirstAbbrCode = AbbrDecl.getCode(); 3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } else { 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (PrevAbbrCode + 1 != AbbrDecl.getCode()) { 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Codes are not consecutive, can't do O(1) lookups. 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FirstAbbrCode = UINT32_MAX; 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PrevAbbrCode = AbbrDecl.getCode(); 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Decls.push_back(std::move(AbbrDecl)); 4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return BeginOffset != *OffsetPtr; 4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const { 4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &Decl : Decls) 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decl.dump(OS); 5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst DWARFAbbreviationDeclaration * 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFAbbreviationDeclarationSet::getAbbreviationDeclaration( 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t AbbrCode) const { 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (FirstAbbrCode == UINT32_MAX) { 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &Decl : Decls) { 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Decl.getCode() == AbbrCode) 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &Decl; 5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size()) 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return &Decls[AbbrCode - FirstAbbrCode]; 6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugAbbrev::DWARFDebugAbbrev() { 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines clear(); 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugAbbrev::clear() { 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AbbrDeclSets.clear(); 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PrevAbbrOffsetPos = AbbrDeclSets.end(); 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugAbbrev::extract(DataExtractor Data) { 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines clear(); 7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t Offset = 0; 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWARFAbbreviationDeclarationSet AbbrDecls; 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (Data.isValidOffset(Offset)) { 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t CUAbbrOffset = Offset; 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!AbbrDecls.extract(Data, &Offset)) 8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer break; 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls); 8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugAbbrev::dump(raw_ostream &OS) const { 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (AbbrDeclSets.empty()) { 9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer OS << "< EMPTY >\n"; 9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer return; 9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &I : AbbrDeclSets) { 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first); 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.second.dump(OS); 9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFAbbreviationDeclarationSet* 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const { 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto End = AbbrDeclSets.end(); 104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) { 1054aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer return &(PrevAbbrOffsetPos->second); 10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto Pos = AbbrDeclSets.find(CUAbbrOffset); 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Pos != End) { 110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PrevAbbrOffsetPos = Pos; 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return &(Pos->second); 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 11572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 116