}
Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
- uint64_t *offset_ptr) {
+ uint64_t *offset_ptr,
+ function_ref<void(Error)> WarningHandler) {
assert(data.isValidOffset(*offset_ptr));
ArangeDescriptors.clear();
Offset = *offset_ptr;
uint64_t end_offset = Offset + full_length;
while (*offset_ptr < end_offset) {
+ uint64_t EntryOffset = *offset_ptr;
arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
- if (arangeDescriptor.Length == 0) {
- // Each set of tuples is terminated by a 0 for the address and 0
- // for the length.
- if (arangeDescriptor.Address == 0 && *offset_ptr == end_offset)
+ // Each set of tuples is terminated by a 0 for the address and 0
+ // for the length.
+ if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
+ if (*offset_ptr == end_offset)
return ErrorSuccess();
- return createStringError(
+ WarningHandler(createStringError(
errc::invalid_argument,
"address range table at offset 0x%" PRIx64
- " has an invalid tuple (length = 0) at offset 0x%" PRIx64,
- Offset, *offset_ptr - tuple_size);
+ " has a premature terminator entry at offset 0x%" PRIx64,
+ Offset, EntryOffset));
}
ArangeDescriptors.push_back(arangeDescriptor);
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
+struct WarningHandler {
+ ~WarningHandler() { EXPECT_THAT_ERROR(std::move(Err), Succeeded()); }
+
+ void operator()(Error E) { Err = joinErrors(std::move(Err), std::move(E)); }
+
+ Error getWarning() { return std::move(Err); }
+
+ Error Err = Error::success();
+};
+
template <size_t SecSize>
void ExpectExtractError(const char (&SecDataRaw)[SecSize],
const char *ErrorMessage) {
/* AddressSize = */ 4);
DWARFDebugArangeSet Set;
uint64_t Offset = 0;
- Error E = Set.extract(Extractor, &Offset);
+ WarningHandler Warnings;
+ Error E = Set.extract(Extractor, &Offset, Warnings);
ASSERT_TRUE(E.operator bool());
EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
}
"of the tuple size");
}
-TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
+TEST(DWARFDebugArangeSet, ZeroAddressEntry) {
static const char DebugArangesSecRaw[] =
- "\x24\x00\x00\x00" // Length
+ "\x1c\x00\x00\x00" // Length
"\x02\x00" // Version
"\x00\x00\x00\x00" // Debug Info Offset
"\x04" // Address Size
"\x00\x00\x00\x00" // Padding
"\x00\x00\x00\x00" // Entry1: Address
"\x01\x00\x00\x00" // Length
+ "\x00\x00\x00\x00" // Termination tuple
+ "\x00\x00\x00\x00";
+ DWARFDataExtractor Extractor(
+ StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
+ /*IsLittleEndian=*/true,
+ /*AddressSize=*/4);
+ DWARFDebugArangeSet Set;
+ uint64_t Offset = 0;
+ ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
+ Succeeded());
+ auto Range = Set.descriptors();
+ auto Iter = Range.begin();
+ ASSERT_EQ(std::distance(Iter, Range.end()), 1u);
+ EXPECT_EQ(Iter->Address, 0u);
+ EXPECT_EQ(Iter->Length, 1u);
+}
+
+TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
+ static const char DebugArangesSecRaw[] =
+ "\x1c\x00\x00\x00" // Length
+ "\x02\x00" // Version
+ "\x00\x00\x00\x00" // Debug Info Offset
+ "\x04" // Address Size
+ "\x00" // Segment Selector Size
+ "\x00\x00\x00\x00" // Padding
+ "\x01\x00\x00\x00" // Entry1: Address
+ "\x00\x00\x00\x00" // Length
+ "\x00\x00\x00\x00" // Termination tuple
+ "\x00\x00\x00\x00";
+ DWARFDataExtractor Extractor(
+ StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
+ /*IsLittleEndian=*/true,
+ /*AddressSize=*/4);
+ DWARFDebugArangeSet Set;
+ uint64_t Offset = 0;
+ ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
+ Succeeded());
+ auto Range = Set.descriptors();
+ auto Iter = Range.begin();
+ ASSERT_EQ(std::distance(Iter, Range.end()), 1u);
+ EXPECT_EQ(Iter->Address, 1u);
+ EXPECT_EQ(Iter->Length, 0u);
+}
+
+TEST(DWARFDebugArangesSet, PrematureTerminator) {
+ static const char DebugArangesSecRaw[] =
+ "\x24\x00\x00\x00" // Length
+ "\x02\x00" // Version
+ "\x00\x00\x00\x00" // Debug Info Offset
+ "\x04" // Address Size
+ "\x00" // Segment Selector Size
+ "\x00\x00\x00\x00" // Padding
+ "\x00\x00\x00\x00" // Entry1: Premature
+ "\x00\x00\x00\x00" // terminator
"\x01\x00\x00\x00" // Entry2: Address
- "\x00\x00\x00\x00" // Length (invalid)
+ "\x01\x00\x00\x00" // Length
"\x00\x00\x00\x00" // Termination tuple
"\x00\x00\x00\x00";
- ExpectExtractError(
- DebugArangesSecRaw,
- "address range table at offset 0x0 has an invalid tuple (length = 0) "
- "at offset 0x18");
+ DWARFDataExtractor Extractor(
+ StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
+ /*IsLittleEndian=*/true,
+ /*AddressSize=*/4);
+ DWARFDebugArangeSet Set;
+ uint64_t Offset = 0;
+ WarningHandler Warnings;
+ ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, Warnings), Succeeded());
+ auto Range = Set.descriptors();
+ auto Iter = Range.begin();
+ ASSERT_EQ(std::distance(Iter, Range.end()), 2u);
+ EXPECT_EQ(Iter->Address, 0u);
+ EXPECT_EQ(Iter->Length, 0u);
+ ++Iter;
+ EXPECT_EQ(Iter->Address, 1u);
+ EXPECT_EQ(Iter->Length, 1u);
+ EXPECT_THAT_ERROR(
+ Warnings.getWarning(),
+ FailedWithMessage("address range table at offset 0x0 has a premature "
+ "terminator entry at offset 0x10"));
}
} // end anonymous namespace