zturner updated this revision to Diff 190654.
zturner added a comment.
Fix half-written comment and add comments to other extraction function
declarations.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59370/new/
https://reviews.llvm.org/D59370
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -660,14 +660,23 @@
}
DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
- if (m_abbr == NULL) {
- const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
- if (debug_abbrev_data.GetByteSize() > 0) {
- m_abbr.reset(new DWARFDebugAbbrev());
- if (m_abbr)
- m_abbr->Parse(debug_abbrev_data);
- }
+ if (m_abbr)
+ return m_abbr.get();
+
+ const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
+ if (debug_abbrev_data.GetByteSize() == 0)
+ return nullptr;
+
+ auto abbr = llvm::make_unique<DWARFDebugAbbrev>();
+ llvm::Error error = abbr->parse(debug_abbrev_data);
+ if (error) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "Unable to read .debug_abbrev section: {0}");
+ return nullptr;
}
+
+ m_abbr = std::move(abbr);
return m_abbr.get();
}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -14,6 +14,8 @@
namespace lldb_private {
+enum class DWARFEnumState { MoreItems, Complete };
+
typedef uint32_t DRC_class; // Holds DRC_* class bitfields
enum DW_TAG_Category {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -35,8 +35,11 @@
void Clear();
dw_offset_t GetOffset() const { return m_offset; }
void Dump(lldb_private::Stream *s) const;
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
+
+ /// Extract all abbrev decls in a set. Returns llvm::ErrorSuccess() on
+ /// success, and an appropriate llvm::Error object otherwise.
+ llvm::Error extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
// void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
dw_uleb128_t
AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
@@ -64,7 +67,11 @@
const DWARFAbbreviationDeclarationSet *
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
void Dump(lldb_private::Stream *s) const;
- void Parse(const lldb_private::DWARFDataExtractor &data);
+
+ /// Extract all abbreviations for a particular compile unit. Returns
+ /// llvm::ErrorSuccess() on success, and an appropriate llvm::Error object
+ /// otherwise.
+ llvm::Error parse(const lldb_private::DWARFDataExtractor &data);
void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
protected:
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -25,14 +25,22 @@
//----------------------------------------------------------------------
// DWARFAbbreviationDeclarationSet::Extract()
//----------------------------------------------------------------------
-bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
+llvm::Error
+DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
const lldb::offset_t begin_offset = *offset_ptr;
m_offset = begin_offset;
Clear();
DWARFAbbreviationDeclaration abbrevDeclaration;
dw_uleb128_t prev_abbr_code = 0;
- while (abbrevDeclaration.Extract(data, offset_ptr)) {
+ DWARFEnumState state = DWARFEnumState::MoreItems;
+ while (state == DWARFEnumState::MoreItems) {
+ llvm::Expected<DWARFEnumState> es =
+ abbrevDeclaration.extract(data, offset_ptr);
+ if (!es)
+ return es.takeError();
+
+ state = *es;
m_decls.push_back(abbrevDeclaration);
if (m_idx_offset == 0)
m_idx_offset = abbrevDeclaration.Code();
@@ -43,7 +51,7 @@
}
prev_abbr_code = abbrevDeclaration.Code();
}
- return begin_offset != *offset_ptr;
+ return llvm::ErrorSuccess();
}
//----------------------------------------------------------------------
@@ -138,19 +146,21 @@
//----------------------------------------------------------------------
// DWARFDebugAbbrev::Parse()
//----------------------------------------------------------------------
-void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) {
+llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) {
lldb::offset_t offset = 0;
while (data.ValidOffset(offset)) {
uint32_t initial_cu_offset = offset;
DWARFAbbreviationDeclarationSet abbrevDeclSet;
- if (abbrevDeclSet.Extract(data, &offset))
- m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
- else
- break;
+ llvm::Error error = abbrevDeclSet.extract(data, &offset);
+ if (error)
+ return error;
+
+ m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
}
m_prev_abbr_offset_pos = m_abbrevCollMap.end();
+ return llvm::ErrorSuccess();
}
//----------------------------------------------------------------------
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -10,7 +10,9 @@
#define liblldb_DWARFAbbreviationDeclaration_h_
#include "DWARFAttribute.h"
+#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"
+#include "llvm/Support/Error.h"
class DWARFAbbreviationDeclaration {
public:
@@ -44,10 +46,18 @@
return m_attributes[idx].get_form();
}
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr);
- bool Extract(const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr, dw_uleb128_t code);
+
+ /// Extract one abbreviation declaration and all of its associated attributes.
+ /// Possible return values:
+ /// DWARFEnumState::Complete - the extraction completed successfully. This
+ /// was the last abbrev decl in a sequence, and the user should not call
+ /// this function again.
+ /// DWARFEnumState::MoreItems - the extraction completed successfully. The
+ /// user should call this function again to retrieve the next decl.
+ /// llvm::Error - A parsing error occurred. The debug info is malformed.
+ llvm::Expected<lldb_private::DWARFEnumState>
+ extract(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
bool IsValid();
void Dump(lldb_private::Stream *s) const;
bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -11,6 +11,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/Stream.h"
+#include "llvm/Object/Error.h"
+
#include "DWARFFormValue.h"
using namespace lldb_private;
@@ -23,41 +25,48 @@
: m_code(InvalidCode), m_tag(tag), m_has_children(has_children),
m_attributes() {}
-bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr) {
- return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
-}
+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;
-bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- dw_uleb128_t code) {
- m_code = code;
m_attributes.clear();
- if (m_code) {
- m_tag = data.GetULEB128(offset_ptr);
- 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);
- DWARFFormValue::ValueType val;
-
- if (form == DW_FORM_implicit_const)
- val.value.sval = data.GetULEB128(offset_ptr);
-
- if (attr && form)
- m_attributes.push_back(DWARFAttribute(attr, form, val));
- else
- break;
- }
-
- return m_tag != 0;
- } else {
- m_tag = 0;
- m_has_children = 0;
+ 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;
+ }
+
+ 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 false;
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "abbreviation declaration attribute list not terminated with a null "
+ "entry");
}
void DWARFAbbreviationDeclaration::Dump(Stream *s) const {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits