Differential D59370 Diff 190654 lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
Changeset View
Changeset View
Standalone View
Standalone View
lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===// | //===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===// | ||||
// | // | ||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "DWARFAbbreviationDeclaration.h" | #include "DWARFAbbreviationDeclaration.h" | ||||
#include "lldb/Core/dwarf.h" | #include "lldb/Core/dwarf.h" | ||||
#include "lldb/Utility/Stream.h" | #include "lldb/Utility/Stream.h" | ||||
#include "llvm/Object/Error.h" | |||||
#include "DWARFFormValue.h" | #include "DWARFFormValue.h" | ||||
using namespace lldb_private; | using namespace lldb_private; | ||||
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() | DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() | ||||
: m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {} | : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {} | ||||
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, | DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, | ||||
uint8_t has_children) | uint8_t has_children) | ||||
: m_code(InvalidCode), m_tag(tag), m_has_children(has_children), | : m_code(InvalidCode), m_tag(tag), m_has_children(has_children), | ||||
m_attributes() {} | m_attributes() {} | ||||
bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, | llvm::Expected<DWARFEnumState> | ||||
DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, | |||||
lldb::offset_t *offset_ptr) { | lldb::offset_t *offset_ptr) { | ||||
return Extract(data, offset_ptr, data.GetULEB128(offset_ptr)); | m_code = data.GetULEB128(offset_ptr); | ||||
} | if (m_code == 0) | ||||
return DWARFEnumState::Complete; | |||||
bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, | |||||
lldb::offset_t *offset_ptr, | |||||
dw_uleb128_t code) { | |||||
m_code = code; | |||||
m_attributes.clear(); | m_attributes.clear(); | ||||
if (m_code) { | |||||
m_tag = data.GetULEB128(offset_ptr); | m_tag = data.GetULEB128(offset_ptr); | ||||
if (m_tag == DW_TAG_null) { | |||||
// FIXME: According to the DWARF spec this may actually be malformed. | |||||
// Should this return an error instead? | |||||
return DWARFEnumState::Complete; | |||||
} | |||||
clayborg: Seems like this would be malformed and should be an error. Something about NULL tag when valid… | |||||
m_has_children = data.GetU8(offset_ptr); | m_has_children = data.GetU8(offset_ptr); | ||||
while (data.ValidOffset(*offset_ptr)) { | while (data.ValidOffset(*offset_ptr)) { | ||||
dw_attr_t attr = data.GetULEB128(offset_ptr); | dw_attr_t attr = data.GetULEB128(offset_ptr); | ||||
dw_form_t form = 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; | DWARFFormValue::ValueType val; | ||||
if (form == DW_FORM_implicit_const) | if (form == DW_FORM_implicit_const) | ||||
val.value.sval = data.GetULEB128(offset_ptr); | val.value.sval = data.GetULEB128(offset_ptr); | ||||
if (attr && form) | |||||
m_attributes.push_back(DWARFAttribute(attr, form, val)); | m_attributes.push_back(DWARFAttribute(attr, form, val)); | ||||
else | |||||
break; | |||||
} | |||||
return m_tag != 0; | |||||
} else { | |||||
m_tag = 0; | |||||
m_has_children = 0; | |||||
} | } | ||||
return false; | return llvm::make_error<llvm::object::GenericBinaryError>( | ||||
"abbreviation declaration attribute list not terminated with a null " | |||||
"entry"); | |||||
} | } | ||||
void DWARFAbbreviationDeclaration::Dump(Stream *s) const { | void DWARFAbbreviationDeclaration::Dump(Stream *s) const { | ||||
s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, " | s->Printf("Debug Abbreviation Declaration: code = 0x%4.4x, tag = %s, " | ||||
"has_children = %s\n", | "has_children = %s\n", | ||||
m_code, DW_TAG_value_to_name(m_tag), | m_code, DW_TAG_value_to_name(m_tag), | ||||
DW_CHILDREN_value_to_name(m_has_children)); | DW_CHILDREN_value_to_name(m_has_children)); | ||||
Show All 30 Lines |
Seems like this would be malformed and should be an error. Something about NULL tag when valid tag was expected