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