Skip to content

Commit f5f8d86

Browse files
jh7370tstellar
authored andcommitted
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 cb3a598, 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
1 parent 280e47e commit f5f8d86

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,20 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
132132

133133
uint64_t end_offset = Offset + full_length;
134134
while (*offset_ptr < end_offset) {
135+
uint64_t EntryOffset = *offset_ptr;
135136
arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
136137
arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
137138

138-
if (arangeDescriptor.Length == 0) {
139-
// Each set of tuples is terminated by a 0 for the address and 0
140-
// for the length.
141-
if (arangeDescriptor.Address == 0 && *offset_ptr == end_offset)
139+
// Each set of tuples is terminated by a 0 for the address and 0
140+
// for the length.
141+
if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
142+
if (*offset_ptr == end_offset)
142143
return ErrorSuccess();
143144
return createStringError(
144145
errc::invalid_argument,
145146
"address range table at offset 0x%" PRIx64
146-
" has an invalid tuple (length = 0) at offset 0x%" PRIx64,
147-
Offset, *offset_ptr - tuple_size);
147+
" has a premature terminator entry at offset 0x%" PRIx64,
148+
Offset, EntryOffset);
148149
}
149150

150151
ArangeDescriptors.push_back(arangeDescriptor);

llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
10+
#include "llvm/Testing/Support/Error.h"
1011
#include "gtest/gtest.h"
1112

1213
using namespace llvm;
@@ -166,24 +167,78 @@ TEST(DWARFDebugArangeSet, UnevenLength) {
166167
"of the tuple size");
167168
}
168169

169-
TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
170+
TEST(DWARFDebugArangeSet, ZeroAddressEntry) {
170171
static const char DebugArangesSecRaw[] =
171-
"\x24\x00\x00\x00" // Length
172+
"\x1c\x00\x00\x00" // Length
172173
"\x02\x00" // Version
173174
"\x00\x00\x00\x00" // Debug Info Offset
174175
"\x04" // Address Size
175176
"\x00" // Segment Selector Size
176177
"\x00\x00\x00\x00" // Padding
177178
"\x00\x00\x00\x00" // Entry1: Address
178179
"\x01\x00\x00\x00" // Length
180+
"\x00\x00\x00\x00" // Termination tuple
181+
"\x00\x00\x00\x00";
182+
DWARFDataExtractor Extractor(
183+
StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
184+
/*IsLittleEndian=*/true,
185+
/*AddressSize=*/4);
186+
DWARFDebugArangeSet Set;
187+
uint64_t Offset = 0;
188+
ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset),
189+
Succeeded());
190+
auto Range = Set.descriptors();
191+
auto Iter = Range.begin();
192+
ASSERT_EQ(std::distance(Iter, Range.end()), 1u);
193+
EXPECT_EQ(Iter->Address, 0u);
194+
EXPECT_EQ(Iter->Length, 1u);
195+
}
196+
197+
TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
198+
static const char DebugArangesSecRaw[] =
199+
"\x1c\x00\x00\x00" // Length
200+
"\x02\x00" // Version
201+
"\x00\x00\x00\x00" // Debug Info Offset
202+
"\x04" // Address Size
203+
"\x00" // Segment Selector Size
204+
"\x00\x00\x00\x00" // Padding
205+
"\x01\x00\x00\x00" // Entry1: Address
206+
"\x00\x00\x00\x00" // Length
207+
"\x00\x00\x00\x00" // Termination tuple
208+
"\x00\x00\x00\x00";
209+
DWARFDataExtractor Extractor(
210+
StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
211+
/*IsLittleEndian=*/true,
212+
/*AddressSize=*/4);
213+
DWARFDebugArangeSet Set;
214+
uint64_t Offset = 0;
215+
ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset),
216+
Succeeded());
217+
auto Range = Set.descriptors();
218+
auto Iter = Range.begin();
219+
ASSERT_EQ(std::distance(Iter, Range.end()), 1u);
220+
EXPECT_EQ(Iter->Address, 1u);
221+
EXPECT_EQ(Iter->Length, 0u);
222+
}
223+
224+
TEST(DWARFDebugArangesSet, PrematureTerminator) {
225+
static const char DebugArangesSecRaw[] =
226+
"\x24\x00\x00\x00" // Length
227+
"\x02\x00" // Version
228+
"\x00\x00\x00\x00" // Debug Info Offset
229+
"\x04" // Address Size
230+
"\x00" // Segment Selector Size
231+
"\x00\x00\x00\x00" // Padding
232+
"\x00\x00\x00\x00" // Entry1: Premature
233+
"\x00\x00\x00\x00" // terminator
179234
"\x01\x00\x00\x00" // Entry2: Address
180-
"\x00\x00\x00\x00" // Length (invalid)
235+
"\x01\x00\x00\x00" // Length
181236
"\x00\x00\x00\x00" // Termination tuple
182237
"\x00\x00\x00\x00";
183238
ExpectExtractError(
184239
DebugArangesSecRaw,
185-
"address range table at offset 0x0 has an invalid tuple (length = 0) "
186-
"at offset 0x18");
240+
"address range table at offset 0x0 has a premature "
241+
"terminator entry at offset 0x10");
187242
}
188243

189244
} // end anonymous namespace

0 commit comments

Comments
 (0)