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