const uint64_t PrologueOffset = *OffsetPtr;
clear();
- TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr);
- if (TotalLength == dwarf::DW_LENGTH_DWARF64) {
- FormParams.Format = dwarf::DWARF64;
- TotalLength = DebugLineData.getU64(OffsetPtr);
- } else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) {
- // Treat this error as unrecoverable - we have no way of knowing where the
- // table ends.
- return createStringError(errc::invalid_argument,
- "parsing line table prologue at offset 0x%8.8" PRIx64
- " unsupported reserved unit length found of value 0x%8.8" PRIx64,
- PrologueOffset, TotalLength);
- }
+ Error Err = Error::success();
+ std::tie(TotalLength, FormParams.Format) =
+ DebugLineData.getInitialLength(OffsetPtr, &Err);
+ if (Err)
+ return createStringError(
+ errc::invalid_argument,
+ "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
+ PrologueOffset, toString(std::move(Err)).c_str());
+
FormParams.Version = DebugLineData.getU16(OffsetPtr);
if (!versionIsSupported(getVersion()))
// Treat this error as unrecoverable - we cannot be sure what any of
return createStringError(
errc::not_supported,
"parsing line table prologue at offset 0x%8.8" PRIx64
- " found unsupported version %" PRIu16,
+ ": unsupported version %" PRIu16,
PrologueOffset, getVersion());
if (getVersion() >= 5) {
}
bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
- return TotalLength == dwarf::DW_LENGTH_DWARF64 ||
- TotalLength < dwarf::DW_LENGTH_lo_reserved;
+ return TotalLength != 0u;
}
DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
--- /dev/null
+## Test that we can dump the (intact) prologue of a large table which was
+## truncated. Also, make sure we don't get confused by a DWARF64 length which
+## matches one of the reserved initial length values.
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s >%t
+# RUN: llvm-dwarfdump %t -debug-line 2>&1 | FileCheck %s
+
+# CHECK: debug_line[0x00000000]
+# CHECK-NEXT: warning: line table program with offset 0x00000000 has length 0xfffffffc but only 0x0000003a bytes are available
+# CHECK-NEXT: Line table prologue:
+# CHECK-NEXT: total_length: 0xfffffff0
+# CHECK-NEXT: version: 4
+# CHECK-NEXT: prologue_length: 0x00000016
+
+# CHECK: 0x000000000badbeef 1 0 1 0 0 is_stmt end_sequence
+
+.section .debug_line,"",@progbits
+.long 0xffffffff # Length of Unit (DWARF-64 format)
+.quad 0xfffffff0
+.short 4 # DWARF version number
+.quad .Lprologue1_end-.Lprologue1_start # Length of Prologue
+.Lprologue1_start:
+.byte 1 # Minimum Instruction Length
+.byte 1 # Maximum Operations per Instruction
+.byte 1 # Default is_stmt
+.byte -5 # Line Base
+.byte 14 # Line Range
+.byte 1 # Opcode Base
+.asciz "dir1" # Include table
+.byte 0
+.asciz "file1" # File table
+.byte 0, 0, 0
+.byte 0
+.Lprologue1_end:
+.byte 0, 9, 2 # DW_LNE_set_address
+.quad 0x0badbeef
+.byte 0, 1, 1 # DW_LNE_end_sequence
generate();
EXPECT_THAT_EXPECTED(
+ getOrParseLineTableFatalErrors(0),
+ FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+ "unexpected end of data at offset 0x0"));
+
+ EXPECT_THAT_EXPECTED(
getOrParseLineTableFatalErrors(1),
FailedWithMessage(
"offset 0x00000001 is not a valid debug line section offset"));
EXPECT_THAT_EXPECTED(
getOrParseLineTableFatalErrors(),
FailedWithMessage(
- "parsing line table prologue at offset 0x00000000 unsupported "
- "reserved unit length found of value 0xfffffff0"));
+ "parsing line table prologue at offset 0x00000000: unsupported "
+ "reserved unit length of value 0xfffffff0"));
}
struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>,
EXPECT_THAT_EXPECTED(
getOrParseLineTableFatalErrors(),
- FailedWithMessage("parsing line table prologue at offset 0x00000000 "
- "found unsupported version " +
+ FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+ "unsupported version " +
std::to_string(Version)));
}
EXPECT_TRUE(Parser.done());
}
-TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
+TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) {
if (!setupGenerator())
return;
DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
- EXPECT_EQ(Parser.getOffset(), 4u);
+ EXPECT_EQ(Parser.getOffset(), 0u);
EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable);
EXPECT_THAT_ERROR(
std::move(Unrecoverable),
FailedWithMessage(
- "parsing line table prologue at offset 0x00000000 unsupported "
- "reserved unit length found of value 0xfffffff0"));
+ "parsing line table prologue at offset 0x00000000: unsupported "
+ "reserved unit length of value 0xfffffff0"));
}
-TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
+TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenSkipping) {
if (!setupGenerator())
return;
DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
Parser.skip(RecordRecoverable, RecordUnrecoverable);
- EXPECT_EQ(Parser.getOffset(), 4u);
+ EXPECT_EQ(Parser.getOffset(), 0u);
EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable);
EXPECT_THAT_ERROR(
std::move(Unrecoverable),
FailedWithMessage(
- "parsing line table prologue at offset 0x00000000 unsupported "
- "reserved unit length found of value 0xfffffff0"));
+ "parsing line table prologue at offset 0x00000000: unsupported "
+ "reserved unit length of value 0xfffffff0"));
}
TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
EXPECT_THAT_ERROR(
std::move(Unrecoverable),
- FailedWithMessage("parsing line table prologue at offset 0x00000000 "
- "found unsupported version 0",
- "parsing line table prologue at offset 0x00000006 "
- "found unsupported version 1"));
+ FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+ "unsupported version 0",
+ "parsing line table prologue at offset 0x00000006: "
+ "unsupported version 1"));
}
TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
EXPECT_THAT_ERROR(
std::move(Unrecoverable),
- FailedWithMessage("parsing line table prologue at offset 0x00000000 "
- "found unsupported version 0",
- "parsing line table prologue at offset 0x00000006 "
- "found unsupported version 1"));
+ FailedWithMessage("parsing line table prologue at offset 0x00000000: "
+ "unsupported version 0",
+ "parsing line table prologue at offset 0x00000006: "
+ "unsupported version 1"));
}
TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {