Skip to content

Commit

Permalink
[DWARFDebugLine] Use new DWARFDataExtractor::getInitialLength
Browse files Browse the repository at this point in the history
Summary:
The error messages change somewhat, but I believe the overall
informational value remains unchanged.

Reviewers: jhenderson, dblaikie, ikudrin

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75116
  • Loading branch information
labath committed Mar 2, 2020
1 parent b52355f commit d978656
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 38 deletions.
26 changes: 11 additions & 15 deletions llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
Expand Up @@ -340,18 +340,15 @@ Error DWARFDebugLine::Prologue::parse(
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
Expand All @@ -360,7 +357,7 @@ Error DWARFDebugLine::Prologue::parse(
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) {
Expand Down Expand Up @@ -1218,8 +1215,7 @@ DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
}

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(
Expand Down
@@ -0,0 +1,37 @@
## 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
6 changes: 3 additions & 3 deletions llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
Expand Up @@ -46,7 +46,7 @@
## For fatal issues, the following table(s) should not be dumped:
# FATAL: debug_line[0x00000048]
# RESERVED-NOT: prologue
# RESERVED: warning: parsing line table prologue at offset 0x00000048 unsupported reserved unit length found of value 0xfffffffe
# RESERVED: warning: parsing line table prologue at offset 0x00000048: unsupported reserved unit length of value 0xfffffffe
# RESERVED-NOT: prologue
# FATAL-NOT: debug_line

Expand Down Expand Up @@ -197,8 +197,8 @@
# LAST: 0x00000000cafebabe {{.*}} end_sequence

# ALL-NOT: warning:
# ALL: warning: parsing line table prologue at offset 0x00000048 found unsupported version 0
# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e found unsupported version 1
# ALL: warning: parsing line table prologue at offset 0x00000048: unsupported version 0
# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e: unsupported version 1
# ALL-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073
# ALL-NEXT: warning: failed to parse entry content descriptions because no path was found
# ALL-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba
Expand Down
45 changes: 25 additions & 20 deletions llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
Expand Up @@ -209,6 +209,11 @@ TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {

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(
Expand Down Expand Up @@ -316,8 +321,8 @@ TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {
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>,
Expand All @@ -339,8 +344,8 @@ TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) {

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)));
}

Expand Down Expand Up @@ -807,7 +812,7 @@ TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) {
EXPECT_TRUE(Parser.done());
}

TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) {
if (!setupGenerator())
return;

Expand All @@ -819,18 +824,18 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
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;

Expand All @@ -842,15 +847,15 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
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) {
Expand All @@ -873,10 +878,10 @@ 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) {
Expand Down Expand Up @@ -932,10 +937,10 @@ TEST_F(DebugLineBasicFixture,

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) {
Expand Down

0 comments on commit d978656

Please sign in to comment.