Line data Source code
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 : #include <algorithm>
14 : #include <cinttypes>
15 : #include <cstdint>
16 :
17 : using namespace llvm;
18 :
19 3334 : DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
20 3334 : clear();
21 3334 : }
22 :
23 6946 : void DWARFAbbreviationDeclarationSet::clear() {
24 6946 : Offset = 0;
25 6946 : FirstAbbrCode = 0;
26 : Decls.clear();
27 6946 : }
28 :
29 3612 : bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
30 : uint32_t *OffsetPtr) {
31 3612 : clear();
32 3612 : const uint32_t BeginOffset = *OffsetPtr;
33 3612 : Offset = BeginOffset;
34 3612 : DWARFAbbreviationDeclaration AbbrDecl;
35 : uint32_t PrevAbbrCode = 0;
36 31459 : while (AbbrDecl.extract(Data, OffsetPtr)) {
37 27847 : if (FirstAbbrCode == 0) {
38 3322 : FirstAbbrCode = AbbrDecl.getCode();
39 : } else {
40 24525 : if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
41 : // Codes are not consecutive, can't do O(1) lookups.
42 3 : FirstAbbrCode = UINT32_MAX;
43 : }
44 : }
45 27847 : PrevAbbrCode = AbbrDecl.getCode();
46 27847 : Decls.push_back(std::move(AbbrDecl));
47 : }
48 3612 : return BeginOffset != *OffsetPtr;
49 : }
50 :
51 229 : void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
52 1708 : for (const auto &Decl : Decls)
53 1479 : Decl.dump(OS);
54 229 : }
55 :
56 : const DWARFAbbreviationDeclaration *
57 31763 : DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
58 : uint32_t AbbrCode) const {
59 31763 : if (FirstAbbrCode == UINT32_MAX) {
60 13 : for (const auto &Decl : Decls) {
61 13 : if (Decl.getCode() == AbbrCode)
62 : return &Decl;
63 : }
64 : return nullptr;
65 : }
66 31757 : if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
67 : return nullptr;
68 63514 : return &Decls[AbbrCode - FirstAbbrCode];
69 : }
70 :
71 3374 : DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
72 :
73 3374 : void DWARFDebugAbbrev::clear() {
74 : AbbrDeclSets.clear();
75 3374 : PrevAbbrOffsetPos = AbbrDeclSets.end();
76 3374 : }
77 :
78 1687 : void DWARFDebugAbbrev::extract(DataExtractor Data) {
79 1687 : clear();
80 : this->Data = Data;
81 1687 : }
82 :
83 249 : void DWARFDebugAbbrev::parse() const {
84 249 : if (!Data)
85 0 : return;
86 249 : uint32_t Offset = 0;
87 249 : DWARFAbbreviationDeclarationSet AbbrDecls;
88 : auto I = AbbrDeclSets.begin();
89 1552 : while (Data->isValidOffset(Offset)) {
90 527 : while (I != AbbrDeclSets.end() && I->first < Offset)
91 : ++I;
92 : uint32_t CUAbbrOffset = Offset;
93 527 : if (!AbbrDecls.extract(*Data, &Offset))
94 : break;
95 527 : AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
96 : }
97 : Data = None;
98 : }
99 :
100 217 : void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
101 217 : parse();
102 :
103 217 : if (AbbrDeclSets.empty()) {
104 0 : OS << "< EMPTY >\n";
105 0 : return;
106 : }
107 :
108 446 : for (const auto &I : AbbrDeclSets) {
109 458 : OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
110 229 : I.second.dump(OS);
111 : }
112 : }
113 :
114 : const DWARFAbbreviationDeclarationSet*
115 4125 : DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
116 : const auto End = AbbrDeclSets.end();
117 4125 : if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
118 803 : return &(PrevAbbrOffsetPos->second);
119 : }
120 :
121 : const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
122 3322 : if (Pos != End) {
123 236 : PrevAbbrOffsetPos = Pos;
124 236 : return &(Pos->second);
125 : }
126 :
127 3086 : if (Data && CUAbbrOffset < Data->getData().size()) {
128 3085 : uint32_t Offset = CUAbbrOffset;
129 3085 : DWARFAbbreviationDeclarationSet AbbrDecls;
130 3085 : if (!AbbrDecls.extract(*Data, &Offset))
131 : return nullptr;
132 3085 : PrevAbbrOffsetPos =
133 3085 : AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
134 : .first;
135 3085 : return &PrevAbbrOffsetPos->second;
136 : }
137 :
138 : return nullptr;
139 : }
|