xref: /aosp_15_r20/external/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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 Worker DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
16*9880d681SAndroid Build Coastguard Worker   clear();
17*9880d681SAndroid Build Coastguard Worker }
18*9880d681SAndroid Build Coastguard Worker 
clear()19*9880d681SAndroid Build Coastguard Worker void 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 Worker bool 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 Worker void 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 Worker DWARFAbbreviationDeclarationSet::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 Worker DWARFDebugAbbrev::DWARFDebugAbbrev() {
68*9880d681SAndroid Build Coastguard Worker   clear();
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker 
clear()71*9880d681SAndroid Build Coastguard Worker void 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 Worker void 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 Worker void 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 Worker DWARFDebugAbbrev::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