summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henderson <james.henderson@sony.com>2020-08-10 13:36:44 +0100
committerTom Stellard <tstellar@redhat.com>2020-12-16 22:47:02 -0500
commitf5f8d86dc4c91ef492b919edf98335d4d09188a8 (patch)
tree8fc353ae493e80be23e49195a99e30d2277957c6
parent280e47ea0e837b809be03f2048ac8abc14dbc387 (diff)
downloadllvm-f5f8d86dc4c91ef492b919edf98335d4d09188a8.tar.gz
Don't error for zero-length arange entries
Although the DWARF specification states that .debug_aranges entries can't have length zero, these can occur in the wild. There's no particular reason to enforce this part of the spec, since functionally they have no impact. The patch removes the error and introduces a new warning for premature terminator entries which does not stop parsing. This is a relanding of cb3a598c87db, adding the missing obj2yaml part that was needed. Fixes https://bugs.llvm.org/show_bug.cgi?id=46805. See also https://reviews.llvm.org/D71932 which originally introduced the error. Reviewed by: ikudrin, dblaikie, Higuoxing Differential Revision: https://reviews.llvm.org/D85313
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp13
-rw-r--r--llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp65
2 files changed, 67 insertions, 11 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 608fc0388af0..c3b039b05f30 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -132,19 +132,20 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
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(
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);
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp
index 4ec9c5d1c0be..7f16aa9ce4b7 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -166,9 +167,9 @@ TEST(DWARFDebugArangeSet, UnevenLength) {
"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
@@ -176,14 +177,68 @@ TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
"\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),
+ 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),
+ 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");
+ "address range table at offset 0x0 has a premature "
+ "terminator entry at offset 0x10");
}
} // end anonymous namespace