DWARFAbbreviationDeclaration.cpp revision 353358
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
18using namespace lldb_private;
19
20DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
21    : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
22
23DWARFAbbreviationDeclaration::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
28llvm::Expected<DWARFEnumState>
29DWARFAbbreviationDeclaration::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
70bool DWARFAbbreviationDeclaration::IsValid() {
71  return m_code != 0 && m_tag != 0;
72}
73
74uint32_t
75DWARFAbbreviationDeclaration::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
85bool DWARFAbbreviationDeclaration::
86operator==(const DWARFAbbreviationDeclaration &rhs) const {
87  return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
88         m_attributes == rhs.m_attributes;
89}
90