1 //===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "DWARFAbbreviationDeclaration.h"
10 
11 #include "lldb/Core/dwarf.h"
12 #include "lldb/Utility/Stream.h"
13 
14 #include "llvm/Object/Error.h"
15 
16 #include "DWARFFormValue.h"
17 
18 using namespace lldb_private;
19 
20 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
21     : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
22 
23 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
24                                                            uint8_t has_children)
25     : m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
26       m_attributes() {}
27 
28 llvm::Expected<DWARFEnumState>
29 DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
30                                       lldb::offset_t *offset_ptr) {
31   m_code = data.GetULEB128(offset_ptr);
32   if (m_code == 0)
33     return DWARFEnumState::Complete;
34 
35   m_attributes.clear();
36   m_tag = data.GetULEB128(offset_ptr);
37   if (m_tag == DW_TAG_null)
38     return llvm::make_error<llvm::object::GenericBinaryError>(
39         "abbrev decl requires non-null tag.");
40 
41   m_has_children = data.GetU8(offset_ptr);
42 
43   while (data.ValidOffset(*offset_ptr)) {
44     dw_attr_t attr = data.GetULEB128(offset_ptr);
45     dw_form_t form = data.GetULEB128(offset_ptr);
46 
47     // This is the last attribute for this abbrev decl, but there may still be
48     // more abbrev decls, so return MoreItems to indicate to the caller that
49     // they should call this function again.
50     if (!attr && !form)
51       return DWARFEnumState::MoreItems;
52 
53     if (!attr || !form)
54       return llvm::make_error<llvm::object::GenericBinaryError>(
55           "malformed abbreviation declaration attribute");
56 
57     DWARFFormValue::ValueType val;
58 
59     if (form == DW_FORM_implicit_const)
60       val.value.sval = data.GetULEB128(offset_ptr);
61 
62     m_attributes.push_back(DWARFAttribute(attr, form, val));
63   }
64 
65   return llvm::make_error<llvm::object::GenericBinaryError>(
66       "abbreviation declaration attribute list not terminated with a null "
67       "entry");
68 }
69 
70 bool DWARFAbbreviationDeclaration::IsValid() {
71   return m_code != 0 && m_tag != 0;
72 }
73 
74 uint32_t
75 DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
76   uint32_t i;
77   const uint32_t kNumAttributes = m_attributes.size();
78   for (i = 0; i < kNumAttributes; ++i) {
79     if (m_attributes[i].get_attr() == attr)
80       return i;
81   }
82   return DW_INVALID_INDEX;
83 }
84 
85 bool DWARFAbbreviationDeclaration::
86 operator==(const DWARFAbbreviationDeclaration &rhs) const {
87   return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
88          m_attributes == rhs.m_attributes;
89 }
90