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