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