summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp171
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 {
OpenPOWER on IntegriCloud