1 //===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
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 "DWARFDebugAbbrev.h"
10 #include "DWARFDataExtractor.h"
11 #include "lldb/Utility/Stream.h"
14 using namespace lldb_private;
17 // DWARFAbbreviationDeclarationSet::Clear()
18 void DWARFAbbreviationDeclarationSet::Clear() {
23 // DWARFAbbreviationDeclarationSet::Extract()
25 DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data,
26 lldb::offset_t *offset_ptr) {
27 const lldb::offset_t begin_offset = *offset_ptr;
28 m_offset = begin_offset;
30 DWARFAbbreviationDeclaration abbrevDeclaration;
31 dw_uleb128_t prev_abbr_code = 0;
33 llvm::Expected<DWARFEnumState> es =
34 abbrevDeclaration.extract(data, offset_ptr);
36 return es.takeError();
37 if (*es == DWARFEnumState::Complete)
39 m_decls.push_back(abbrevDeclaration);
40 if (m_idx_offset == 0)
41 m_idx_offset = abbrevDeclaration.Code();
42 else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) {
43 // Out of order indexes, we can't do O(1) lookups...
44 m_idx_offset = UINT32_MAX;
46 prev_abbr_code = abbrevDeclaration.Code();
48 return llvm::ErrorSuccess();
51 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
52 const DWARFAbbreviationDeclaration *
53 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
54 dw_uleb128_t abbrCode) const {
55 if (m_idx_offset == UINT32_MAX) {
56 DWARFAbbreviationDeclarationCollConstIter pos;
57 DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
58 for (pos = m_decls.begin(); pos != end; ++pos) {
59 if (pos->Code() == abbrCode)
63 uint32_t idx = abbrCode - m_idx_offset;
64 if (idx < m_decls.size())
71 // DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
72 void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
73 std::set<dw_form_t> &invalid_forms) const {
74 for (const auto &abbr_decl : m_decls) {
75 const size_t num_attrs = abbr_decl.NumAttributes();
76 for (size_t i=0; i<num_attrs; ++i) {
77 dw_form_t form = abbr_decl.GetFormByIndex(i);
78 if (!DWARFFormValue::FormIsSupported(form))
79 invalid_forms.insert(form);
86 // Encode the abbreviation table onto the end of the buffer provided into a
87 // byte representation as would be found in a ".debug_abbrev" debug information
90 // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
93 // DWARFAbbreviationDeclarationCollConstIter pos;
94 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
95 // for (pos = m_decls.begin(); pos != end; ++pos)
96 // pos->Append(debug_abbrev_buf);
97 // debug_abbrev_buf.Append8(0);
100 // DWARFDebugAbbrev constructor
101 DWARFDebugAbbrev::DWARFDebugAbbrev()
102 : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
104 // DWARFDebugAbbrev::Parse()
105 llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) {
106 lldb::offset_t offset = 0;
108 while (data.ValidOffset(offset)) {
109 uint32_t initial_cu_offset = offset;
110 DWARFAbbreviationDeclarationSet abbrevDeclSet;
112 llvm::Error error = abbrevDeclSet.extract(data, &offset);
116 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
118 m_prev_abbr_offset_pos = m_abbrevCollMap.end();
119 return llvm::ErrorSuccess();
122 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
123 const DWARFAbbreviationDeclarationSet *
124 DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
125 dw_offset_t cu_abbr_offset) const {
126 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
127 DWARFAbbreviationDeclarationCollMapConstIter pos;
128 if (m_prev_abbr_offset_pos != end &&
129 m_prev_abbr_offset_pos->first == cu_abbr_offset)
130 return &(m_prev_abbr_offset_pos->second);
132 pos = m_abbrevCollMap.find(cu_abbr_offset);
133 m_prev_abbr_offset_pos = pos;
136 if (pos != m_abbrevCollMap.end())
137 return &(pos->second);
141 // DWARFDebugAbbrev::GetUnsupportedForms()
142 void DWARFDebugAbbrev::GetUnsupportedForms(
143 std::set<dw_form_t> &invalid_forms) const {
144 for (const auto &pair : m_abbrevCollMap)
145 pair.second.GetUnsupportedForms(invalid_forms);