diff options
author | Zachary Turner <zturner@google.com> | 2019-03-15 17:32:05 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2019-03-15 17:32:05 +0000 |
commit | 1cbbab9277af09f2da3f7eba7391452e8da8fe79 (patch) | |
tree | 753645a33149b88d042ecec163235a96685c8fb9 /lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp | |
parent | 04fddc9b27f1c86f24f2dbf9a4de0964ace4380b (diff) | |
download | bcm5719-llvm-1cbbab9277af09f2da3f7eba7391452e8da8fe79.tar.gz bcm5719-llvm-1cbbab9277af09f2da3f7eba7391452e8da8fe79.zip |
Return Error and Expected from more DWARF interfaces.
This continues the work of introducing Error and Expected into
the DWARF parsing interfaces, this time for the DWARFCompileUnit
and DWARFDebugAranges classes.
Differential Revision: https://reviews.llvm.org/D59381
llvm-svn: 356278
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp | 171 |
1 files changed, 81 insertions, 90 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp index ad3709541d7..49de59c33ee 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp @@ -10,6 +10,7 @@ #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" +#include "llvm/Object/Error.h" #include <assert.h> using namespace lldb_private; @@ -130,98 +131,88 @@ void DWARFDebugArangeSet::AddDescriptor( } } -bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr) { - if (data.ValidOffset(*offset_ptr)) { - m_arange_descriptors.clear(); - m_offset = *offset_ptr; - - // 7.20 Address Range Table - // - // Each set of entries in the table of address ranges contained in the - // .debug_aranges section begins with a header consisting of: a 4-byte - // length containing the length of the set of entries for this compilation - // unit, not including the length field itself; a 2-byte version identifier - // containing the value 2 for DWARF Version 2; a 4-byte offset into - // the.debug_infosection; a 1-byte unsigned integer containing the size in - // bytes of an address (or the offset portion of an address for segmented - // addressing) on the target system; and a 1-byte unsigned integer - // containing the size in bytes of a segment descriptor on the target - // system. This header is followed by a series of tuples. Each tuple - // consists of an address and a length, each in the size appropriate for an - // address on the target architecture. - m_header.length = data.GetDWARFInitialLength(offset_ptr); - m_header.version = data.GetU16(offset_ptr); - m_header.cu_offset = data.GetDWARFOffset(offset_ptr); - m_header.addr_size = data.GetU8(offset_ptr); - m_header.seg_size = data.GetU8(offset_ptr); - - // Try to avoid reading invalid arange sets by making sure: - // 1 - the version looks good - // 2 - the address byte size looks plausible - // 3 - the length seems to make sense - // size looks plausible - if ((m_header.version >= 2 && m_header.version <= 5) && - (m_header.addr_size == 4 || m_header.addr_size == 8) && - (m_header.length > 0)) { - if (data.ValidOffset(m_offset + sizeof(m_header.length) + - m_header.length - 1)) { - // The first tuple following the header in each set begins at an offset - // that is a multiple of the size of a single tuple (that is, twice the - // size of an address). The header is padded, if necessary, to the - // appropriate boundary. - const uint32_t header_size = *offset_ptr - m_offset; - const uint32_t tuple_size = m_header.addr_size << 1; - uint32_t first_tuple_offset = 0; - while (first_tuple_offset < header_size) - first_tuple_offset += tuple_size; - - *offset_ptr = m_offset + first_tuple_offset; - - Descriptor arangeDescriptor; - - static_assert( - sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length), - "DWARFDebugArangeSet::Descriptor.address and " - "DWARFDebugArangeSet::Descriptor.length must have same size"); - - while (data.ValidOffset(*offset_ptr)) { - arangeDescriptor.address = - data.GetMaxU64(offset_ptr, m_header.addr_size); - arangeDescriptor.length = - data.GetMaxU64(offset_ptr, m_header.addr_size); - - // Each set of tuples is terminated by a 0 for the address and 0 for - // the length. - if (arangeDescriptor.address || arangeDescriptor.length) - m_arange_descriptors.push_back(arangeDescriptor); - else - break; // We are done if we get a zero address and length - } - } -#if defined(LLDB_CONFIGURATION_DEBUG) - else { - printf("warning: .debug_arange set length is too large arange data at " - "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " - "addr_size=%u, seg_size=%u\n", - m_offset, m_header.length, m_header.version, m_header.cu_offset, - m_header.addr_size, m_header.seg_size); - } -#endif - } -#if defined(LLDB_CONFIGURATION_DEBUG) - else { - printf("warning: .debug_arange set has bad header at 0x%8.8x: " - "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, " - "addr_size=%u, seg_size=%u\n", - m_offset, m_header.length, m_header.version, m_header.cu_offset, - m_header.addr_size, m_header.seg_size); - } -#endif +llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data, + lldb::offset_t *offset_ptr) { + assert(data.ValidOffset(*offset_ptr)); + + m_arange_descriptors.clear(); + m_offset = *offset_ptr; + + // 7.20 Address Range Table + // + // Each set of entries in the table of address ranges contained in the + // .debug_aranges section begins with a header consisting of: a 4-byte + // length containing the length of the set of entries for this compilation + // unit, not including the length field itself; a 2-byte version identifier + // containing the value 2 for DWARF Version 2; a 4-byte offset into + // the.debug_infosection; a 1-byte unsigned integer containing the size in + // bytes of an address (or the offset portion of an address for segmented + // addressing) on the target system; and a 1-byte unsigned integer + // containing the size in bytes of a segment descriptor on the target + // system. This header is followed by a series of tuples. Each tuple + // consists of an address and a length, each in the size appropriate for an + // address on the target architecture. + m_header.length = data.GetDWARFInitialLength(offset_ptr); + m_header.version = data.GetU16(offset_ptr); + m_header.cu_offset = data.GetDWARFOffset(offset_ptr); + m_header.addr_size = data.GetU8(offset_ptr); + m_header.seg_size = data.GetU8(offset_ptr); + + // Try to avoid reading invalid arange sets by making sure: + // 1 - the version looks good + // 2 - the address byte size looks plausible + // 3 - the length seems to make sense + // size looks plausible + if (m_header.version < 2 || m_header.version > 5) + return llvm::make_error<llvm::object::GenericBinaryError>( + "Invalid arange header version"); + + if (m_header.addr_size != 4 && m_header.addr_size != 8) + return llvm::make_error<llvm::object::GenericBinaryError>( + "Invalid arange header address size"); - return !m_arange_descriptors.empty(); + if (m_header.length == 0) + return llvm::make_error<llvm::object::GenericBinaryError>( + "Invalid arange header length"); + + if (!data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length - + 1)) + return llvm::make_error<llvm::object::GenericBinaryError>( + "Invalid arange header length"); + + // The first tuple following the header in each set begins at an offset + // that is a multiple of the size of a single tuple (that is, twice the + // size of an address). The header is padded, if necessary, to the + // appropriate boundary. + const uint32_t header_size = *offset_ptr - m_offset; + const uint32_t tuple_size = m_header.addr_size << 1; + uint32_t first_tuple_offset = 0; + while (first_tuple_offset < header_size) + first_tuple_offset += tuple_size; + + *offset_ptr = m_offset + first_tuple_offset; + + Descriptor arangeDescriptor; + + static_assert(sizeof(arangeDescriptor.address) == + sizeof(arangeDescriptor.length), + "DWARFDebugArangeSet::Descriptor.address and " + "DWARFDebugArangeSet::Descriptor.length must have same size"); + + while (data.ValidOffset(*offset_ptr)) { + arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size); + arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size); + + // Each set of tuples is terminated by a 0 for the address and 0 for + // the length. + if (!arangeDescriptor.address && !arangeDescriptor.length) + return llvm::ErrorSuccess(); + + m_arange_descriptors.push_back(arangeDescriptor); } - return false; + + return llvm::make_error<llvm::object::GenericBinaryError>( + "arange descriptors not terminated by null entry"); } dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const { |