1 //===- DWARFDebugAbbrev.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
10 #include "llvm/Support/Format.h"
11 #include "llvm/Support/raw_ostream.h"
18 DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
22 void DWARFAbbreviationDeclarationSet::clear() {
28 bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data
,
29 uint32_t *OffsetPtr
) {
31 const uint32_t BeginOffset
= *OffsetPtr
;
33 DWARFAbbreviationDeclaration AbbrDecl
;
34 uint32_t PrevAbbrCode
= 0;
35 while (AbbrDecl
.extract(Data
, OffsetPtr
)) {
36 if (FirstAbbrCode
== 0) {
37 FirstAbbrCode
= AbbrDecl
.getCode();
39 if (PrevAbbrCode
+ 1 != AbbrDecl
.getCode()) {
40 // Codes are not consecutive, can't do O(1) lookups.
41 FirstAbbrCode
= UINT32_MAX
;
44 PrevAbbrCode
= AbbrDecl
.getCode();
45 Decls
.push_back(std::move(AbbrDecl
));
47 return BeginOffset
!= *OffsetPtr
;
50 void DWARFAbbreviationDeclarationSet::dump(raw_ostream
&OS
) const {
51 for (const auto &Decl
: Decls
)
55 const DWARFAbbreviationDeclaration
*
56 DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
57 uint32_t AbbrCode
) const {
58 if (FirstAbbrCode
== UINT32_MAX
) {
59 for (const auto &Decl
: Decls
) {
60 if (Decl
.getCode() == AbbrCode
)
65 if (AbbrCode
< FirstAbbrCode
|| AbbrCode
>= FirstAbbrCode
+ Decls
.size())
67 return &Decls
[AbbrCode
- FirstAbbrCode
];
70 DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
72 void DWARFDebugAbbrev::clear() {
74 PrevAbbrOffsetPos
= AbbrDeclSets
.end();
77 void DWARFDebugAbbrev::extract(DataExtractor Data
) {
82 void DWARFDebugAbbrev::parse() const {
86 auto I
= AbbrDeclSets
.begin();
87 while (Data
->isValidOffset(Offset
)) {
88 while (I
!= AbbrDeclSets
.end() && I
->first
< Offset
)
90 uint32_t CUAbbrOffset
= Offset
;
91 DWARFAbbreviationDeclarationSet AbbrDecls
;
92 if (!AbbrDecls
.extract(*Data
, &Offset
))
94 AbbrDeclSets
.insert(I
, std::make_pair(CUAbbrOffset
, std::move(AbbrDecls
)));
99 void DWARFDebugAbbrev::dump(raw_ostream
&OS
) const {
102 if (AbbrDeclSets
.empty()) {
107 for (const auto &I
: AbbrDeclSets
) {
108 OS
<< format("Abbrev table for offset: 0x%8.8" PRIx64
"\n", I
.first
);
113 const DWARFAbbreviationDeclarationSet
*
114 DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset
) const {
115 const auto End
= AbbrDeclSets
.end();
116 if (PrevAbbrOffsetPos
!= End
&& PrevAbbrOffsetPos
->first
== CUAbbrOffset
) {
117 return &(PrevAbbrOffsetPos
->second
);
120 const auto Pos
= AbbrDeclSets
.find(CUAbbrOffset
);
122 PrevAbbrOffsetPos
= Pos
;
123 return &(Pos
->second
);
126 if (Data
&& CUAbbrOffset
< Data
->getData().size()) {
127 uint32_t Offset
= CUAbbrOffset
;
128 DWARFAbbreviationDeclarationSet AbbrDecls
;
129 if (!AbbrDecls
.extract(*Data
, &Offset
))
132 AbbrDeclSets
.insert(std::make_pair(CUAbbrOffset
, std::move(AbbrDecls
)))
134 return &PrevAbbrOffsetPos
->second
;