Currently dw_tag_t is a typedef for uint16_t. This patch changes makes dw_tag_t a typedef for llvm::dwarf::Tag. This enables us to use the full power of the DWARF utilities in LLVM without having to do the cast every time. With this approach, we only have to do the cast when reading the ULEB value. Differential revision: https://reviews.llvm.org/D68005 llvm-svn: 372891
91 lines
3.0 KiB
C++
91 lines
3.0 KiB
C++
//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DWARFAbbreviationDeclaration.h"
|
|
|
|
#include "lldb/Core/dwarf.h"
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
#include "llvm/Object/Error.h"
|
|
|
|
#include "DWARFFormValue.h"
|
|
|
|
using namespace lldb_private;
|
|
|
|
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
|
|
: m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
|
|
m_attributes() {}
|
|
|
|
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
|
|
uint8_t has_children)
|
|
: m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
|
|
m_attributes() {}
|
|
|
|
llvm::Expected<DWARFEnumState>
|
|
DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
|
|
lldb::offset_t *offset_ptr) {
|
|
m_code = data.GetULEB128(offset_ptr);
|
|
if (m_code == 0)
|
|
return DWARFEnumState::Complete;
|
|
|
|
m_attributes.clear();
|
|
m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr));
|
|
if (m_tag == DW_TAG_null)
|
|
return llvm::make_error<llvm::object::GenericBinaryError>(
|
|
"abbrev decl requires non-null tag.");
|
|
|
|
m_has_children = data.GetU8(offset_ptr);
|
|
|
|
while (data.ValidOffset(*offset_ptr)) {
|
|
dw_attr_t attr = data.GetULEB128(offset_ptr);
|
|
dw_form_t form = data.GetULEB128(offset_ptr);
|
|
|
|
// This is the last attribute for this abbrev decl, but there may still be
|
|
// more abbrev decls, so return MoreItems to indicate to the caller that
|
|
// they should call this function again.
|
|
if (!attr && !form)
|
|
return DWARFEnumState::MoreItems;
|
|
|
|
if (!attr || !form)
|
|
return llvm::make_error<llvm::object::GenericBinaryError>(
|
|
"malformed abbreviation declaration attribute");
|
|
|
|
DWARFFormValue::ValueType val;
|
|
|
|
if (form == DW_FORM_implicit_const)
|
|
val.value.sval = data.GetULEB128(offset_ptr);
|
|
|
|
m_attributes.push_back(DWARFAttribute(attr, form, val));
|
|
}
|
|
|
|
return llvm::make_error<llvm::object::GenericBinaryError>(
|
|
"abbreviation declaration attribute list not terminated with a null "
|
|
"entry");
|
|
}
|
|
|
|
bool DWARFAbbreviationDeclaration::IsValid() {
|
|
return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null;
|
|
}
|
|
|
|
uint32_t
|
|
DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
|
|
uint32_t i;
|
|
const uint32_t kNumAttributes = m_attributes.size();
|
|
for (i = 0; i < kNumAttributes; ++i) {
|
|
if (m_attributes[i].get_attr() == attr)
|
|
return i;
|
|
}
|
|
return DW_INVALID_INDEX;
|
|
}
|
|
|
|
bool DWARFAbbreviationDeclaration::
|
|
operator==(const DWARFAbbreviationDeclaration &rhs) const {
|
|
return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
|
|
m_attributes == rhs.m_attributes;
|
|
}
|