1104477Ssam//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===// 2104477Ssam// 3104477Ssam// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4104477Ssam// See https://llvm.org/LICENSE.txt for license information. 5104477Ssam// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6104477Ssam// 7104477Ssam//===----------------------------------------------------------------------===// 8104477Ssam 9104477Ssam#include "DWARFAbbreviationDeclaration.h" 10104477Ssam 11104477Ssam#include "lldb/Core/dwarf.h" 12104477Ssam#include "lldb/Utility/Stream.h" 13104477Ssam 14104477Ssam#include "llvm/Object/Error.h" 15104477Ssam 16104477Ssam#include "DWARFFormValue.h" 17104477Ssam 18104477Ssamusing namespace lldb_private; 19104477Ssam 20104477SsamDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() 21104477Ssam : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0), 22104477Ssam m_attributes() {} 23104477Ssam 24104477SsamDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, 25104477Ssam uint8_t has_children) 26104477Ssam : m_code(InvalidCode), m_tag(tag), m_has_children(has_children), 27104477Ssam m_attributes() {} 28104477Ssam 29104477Ssamllvm::Expected<DWARFEnumState> 30104477SsamDWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, 31104477Ssam lldb::offset_t *offset_ptr) { 32104477Ssam m_code = data.GetULEB128(offset_ptr); 33104477Ssam if (m_code == 0) 34104477Ssam return DWARFEnumState::Complete; 35104477Ssam 36104477Ssam m_attributes.clear(); 37104477Ssam m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr)); 38104477Ssam if (m_tag == DW_TAG_null) 39104477Ssam return llvm::make_error<llvm::object::GenericBinaryError>( 40104477Ssam "abbrev decl requires non-null tag."); 41104477Ssam 42104477Ssam m_has_children = data.GetU8(offset_ptr); 43104477Ssam 44104477Ssam while (data.ValidOffset(*offset_ptr)) { 45104477Ssam dw_attr_t attr = data.GetULEB128(offset_ptr); 46104477Ssam dw_form_t form = data.GetULEB128(offset_ptr); 47104477Ssam 48104477Ssam // This is the last attribute for this abbrev decl, but there may still be 49104477Ssam // more abbrev decls, so return MoreItems to indicate to the caller that 50104477Ssam // they should call this function again. 51104477Ssam if (!attr && !form) 52104477Ssam return DWARFEnumState::MoreItems; 53104477Ssam 54104477Ssam if (!attr || !form) 55104477Ssam return llvm::make_error<llvm::object::GenericBinaryError>( 56104477Ssam "malformed abbreviation declaration attribute"); 57104477Ssam 58104477Ssam DWARFFormValue::ValueType val; 59104477Ssam 60104477Ssam if (form == DW_FORM_implicit_const) 61104477Ssam val.value.sval = data.GetULEB128(offset_ptr); 62104477Ssam 63104477Ssam m_attributes.push_back(DWARFAttribute(attr, form, val)); 64104477Ssam } 65104477Ssam 66104477Ssam return llvm::make_error<llvm::object::GenericBinaryError>( 67104477Ssam "abbreviation declaration attribute list not terminated with a null " 68104477Ssam "entry"); 69104477Ssam} 70104477Ssam 71104477Ssambool DWARFAbbreviationDeclaration::IsValid() { 72104477Ssam return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null; 73104477Ssam} 74104477Ssam 75104477Ssamuint32_t 76104477SsamDWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const { 77104477Ssam uint32_t i; 78104477Ssam const uint32_t kNumAttributes = m_attributes.size(); 79104477Ssam for (i = 0; i < kNumAttributes; ++i) { 80104477Ssam if (m_attributes[i].get_attr() == attr) 81104477Ssam return i; 82104477Ssam } 83104477Ssam return DW_INVALID_INDEX; 84104477Ssam} 85104477Ssam 86104477Ssambool DWARFAbbreviationDeclaration:: 87104477Ssamoperator==(const DWARFAbbreviationDeclaration &rhs) const { 88104477Ssam return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() && 89104477Ssam m_attributes == rhs.m_attributes; 90104477Ssam} 91104477Ssam