xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1*dda28197Spatrick //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "DWARFDebugAbbrev.h"
10061da546Spatrick #include "DWARFDataExtractor.h"
11061da546Spatrick #include "lldb/Utility/Stream.h"
12061da546Spatrick 
13061da546Spatrick using namespace lldb;
14061da546Spatrick using namespace lldb_private;
15061da546Spatrick 
16061da546Spatrick // DWARFAbbreviationDeclarationSet::Clear()
Clear()17061da546Spatrick void DWARFAbbreviationDeclarationSet::Clear() {
18061da546Spatrick   m_idx_offset = 0;
19061da546Spatrick   m_decls.clear();
20061da546Spatrick }
21061da546Spatrick 
22061da546Spatrick // DWARFAbbreviationDeclarationSet::Extract()
23061da546Spatrick llvm::Error
extract(const DWARFDataExtractor & data,lldb::offset_t * offset_ptr)24061da546Spatrick DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data,
25061da546Spatrick                                          lldb::offset_t *offset_ptr) {
26061da546Spatrick   const lldb::offset_t begin_offset = *offset_ptr;
27061da546Spatrick   m_offset = begin_offset;
28061da546Spatrick   Clear();
29061da546Spatrick   DWARFAbbreviationDeclaration abbrevDeclaration;
30061da546Spatrick   dw_uleb128_t prev_abbr_code = 0;
31061da546Spatrick   while (true) {
32061da546Spatrick     llvm::Expected<DWARFEnumState> es =
33061da546Spatrick         abbrevDeclaration.extract(data, offset_ptr);
34061da546Spatrick     if (!es)
35061da546Spatrick       return es.takeError();
36061da546Spatrick     if (*es == DWARFEnumState::Complete)
37061da546Spatrick       break;
38061da546Spatrick     m_decls.push_back(abbrevDeclaration);
39061da546Spatrick     if (m_idx_offset == 0)
40061da546Spatrick       m_idx_offset = abbrevDeclaration.Code();
41061da546Spatrick     else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) {
42061da546Spatrick       // Out of order indexes, we can't do O(1) lookups...
43061da546Spatrick       m_idx_offset = UINT32_MAX;
44061da546Spatrick     }
45061da546Spatrick     prev_abbr_code = abbrevDeclaration.Code();
46061da546Spatrick   }
47061da546Spatrick   return llvm::ErrorSuccess();
48061da546Spatrick }
49061da546Spatrick 
50061da546Spatrick // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
51061da546Spatrick const DWARFAbbreviationDeclaration *
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const52061da546Spatrick DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
53061da546Spatrick     dw_uleb128_t abbrCode) const {
54061da546Spatrick   if (m_idx_offset == UINT32_MAX) {
55061da546Spatrick     DWARFAbbreviationDeclarationCollConstIter pos;
56061da546Spatrick     DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
57061da546Spatrick     for (pos = m_decls.begin(); pos != end; ++pos) {
58061da546Spatrick       if (pos->Code() == abbrCode)
59061da546Spatrick         return &(*pos);
60061da546Spatrick     }
61061da546Spatrick   } else {
62061da546Spatrick     uint32_t idx = abbrCode - m_idx_offset;
63061da546Spatrick     if (idx < m_decls.size())
64061da546Spatrick       return &m_decls[idx];
65061da546Spatrick   }
66061da546Spatrick   return nullptr;
67061da546Spatrick }
68061da546Spatrick 
69061da546Spatrick 
70061da546Spatrick // DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const71061da546Spatrick void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
72061da546Spatrick     std::set<dw_form_t> &invalid_forms) const {
73061da546Spatrick   for (const auto &abbr_decl : m_decls) {
74061da546Spatrick     const size_t num_attrs = abbr_decl.NumAttributes();
75061da546Spatrick     for (size_t i=0; i<num_attrs; ++i) {
76061da546Spatrick       dw_form_t form = abbr_decl.GetFormByIndex(i);
77061da546Spatrick       if (!DWARFFormValue::FormIsSupported(form))
78061da546Spatrick         invalid_forms.insert(form);
79061da546Spatrick     }
80061da546Spatrick   }
81061da546Spatrick }
82061da546Spatrick 
83061da546Spatrick // Encode
84061da546Spatrick //
85061da546Spatrick // Encode the abbreviation table onto the end of the buffer provided into a
86061da546Spatrick // byte representation as would be found in a ".debug_abbrev" debug information
87061da546Spatrick // section.
88061da546Spatrick // void
89061da546Spatrick // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
90061da546Spatrick // const
91061da546Spatrick //{
92061da546Spatrick //  DWARFAbbreviationDeclarationCollConstIter pos;
93061da546Spatrick //  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
94061da546Spatrick //  for (pos = m_decls.begin(); pos != end; ++pos)
95061da546Spatrick //      pos->Append(debug_abbrev_buf);
96061da546Spatrick //  debug_abbrev_buf.Append8(0);
97061da546Spatrick //}
98061da546Spatrick 
99061da546Spatrick // DWARFDebugAbbrev constructor
DWARFDebugAbbrev()100061da546Spatrick DWARFDebugAbbrev::DWARFDebugAbbrev()
101061da546Spatrick     : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
102061da546Spatrick 
103061da546Spatrick // DWARFDebugAbbrev::Parse()
parse(const DWARFDataExtractor & data)104061da546Spatrick llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) {
105061da546Spatrick   lldb::offset_t offset = 0;
106061da546Spatrick 
107061da546Spatrick   while (data.ValidOffset(offset)) {
108061da546Spatrick     uint32_t initial_cu_offset = offset;
109061da546Spatrick     DWARFAbbreviationDeclarationSet abbrevDeclSet;
110061da546Spatrick 
111061da546Spatrick     llvm::Error error = abbrevDeclSet.extract(data, &offset);
112061da546Spatrick     if (error)
113061da546Spatrick       return error;
114061da546Spatrick 
115061da546Spatrick     m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
116061da546Spatrick   }
117061da546Spatrick   m_prev_abbr_offset_pos = m_abbrevCollMap.end();
118061da546Spatrick   return llvm::ErrorSuccess();
119061da546Spatrick }
120061da546Spatrick 
121061da546Spatrick // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
122061da546Spatrick const DWARFAbbreviationDeclarationSet *
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const123061da546Spatrick DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
124061da546Spatrick     dw_offset_t cu_abbr_offset) const {
125061da546Spatrick   DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
126061da546Spatrick   DWARFAbbreviationDeclarationCollMapConstIter pos;
127061da546Spatrick   if (m_prev_abbr_offset_pos != end &&
128061da546Spatrick       m_prev_abbr_offset_pos->first == cu_abbr_offset)
129061da546Spatrick     return &(m_prev_abbr_offset_pos->second);
130061da546Spatrick   else {
131061da546Spatrick     pos = m_abbrevCollMap.find(cu_abbr_offset);
132061da546Spatrick     m_prev_abbr_offset_pos = pos;
133061da546Spatrick   }
134061da546Spatrick 
135061da546Spatrick   if (pos != m_abbrevCollMap.end())
136061da546Spatrick     return &(pos->second);
137061da546Spatrick   return nullptr;
138061da546Spatrick }
139061da546Spatrick 
140061da546Spatrick // DWARFDebugAbbrev::GetUnsupportedForms()
GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const141061da546Spatrick void DWARFDebugAbbrev::GetUnsupportedForms(
142061da546Spatrick     std::set<dw_form_t> &invalid_forms) const {
143061da546Spatrick   for (const auto &pair : m_abbrevCollMap)
144061da546Spatrick     pair.second.GetUnsupportedForms(invalid_forms);
145061da546Spatrick }
146