Home | History | Annotate | Download | only in DWARF
      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"
     13 using namespace llvm;
     14 
     15 DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
     16   clear();
     17 }
     18 
     19 void DWARFAbbreviationDeclarationSet::clear() {
     20   Offset = 0;
     21   FirstAbbrCode = 0;
     22   Decls.clear();
     23 }
     24 
     25 bool 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 
     47 void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
     48   for (const auto &Decl : Decls)
     49     Decl.dump(OS);
     50 }
     51 
     52 const DWARFAbbreviationDeclaration *
     53 DWARFAbbreviationDeclarationSet::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 
     67 DWARFDebugAbbrev::DWARFDebugAbbrev() {
     68   clear();
     69 }
     70 
     71 void DWARFDebugAbbrev::clear() {
     72   AbbrDeclSets.clear();
     73   PrevAbbrOffsetPos = AbbrDeclSets.end();
     74 }
     75 
     76 void 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 
     89 void 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 
    101 const DWARFAbbreviationDeclarationSet*
    102 DWARFDebugAbbrev::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