Skip to content

Commit

Permalink
[DebugInfo] Correct out-of-bounds error message for DW_FORM_line_strp
Browse files Browse the repository at this point in the history
DW_FORM_line_strp reads from the .debug_line_str section, but
previously the out-of-bounds error reported the .debug_line section.

This incorrect error message showed up when debugging an issue with
some invalid DWARF5 data.

The verify_string.s test has now been extended to check this (which
required a small change to the DWARF verifier to also look at
DW_FORM_line_strp).

Differential Revision: https://reviews.llvm.org/D146539
  • Loading branch information
MacDue committed Mar 30, 2023
1 parent cc8237d commit 277b898
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
12 changes: 7 additions & 5 deletions llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,16 +615,18 @@ Expected<const char *> DWARFFormValue::getAsCString() const {
}
// Prefer the Unit's string extractor, because for .dwo it will point to
// .debug_str.dwo, while the Context's extractor always uses .debug_str.
DataExtractor StrData = Form == DW_FORM_line_strp
? C->getLineStringExtractor()
: U ? U->getStringExtractor()
: C->getStringExtractor();
bool IsDebugLineString = Form == DW_FORM_line_strp;
DataExtractor StrData =
IsDebugLineString ? C->getLineStringExtractor()
: U ? U->getStringExtractor() : C->getStringExtractor();
if (const char *Str = StrData.getCStr(&Offset))
return Str;
std::string Msg = FormEncodingString(Form).str();
if (Index)
Msg += (" uses index " + Twine(*Index) + ", but the referenced string").str();
Msg += (" offset " + Twine(Offset) + " is beyond .debug_str bounds").str();
Msg += (" offset " + Twine(Offset) + " is beyond " +
(IsDebugLineString ? ".debug_line_str" : ".debug_str") + " bounds")
.str();
return make_error<StringError>(Msg,
inconvertibleErrorCode());
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,8 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
case DW_FORM_strx1:
case DW_FORM_strx2:
case DW_FORM_strx3:
case DW_FORM_strx4: {
case DW_FORM_strx4:
case DW_FORM_line_strp: {
if (Error E = AttrValue.Value.getAsCString().takeError()) {
++NumErrors;
error() << toString(std::move(E)) << ":\n";
Expand Down
37 changes: 32 additions & 5 deletions llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
# RUN: not llvm-dwarfdump -verify %t.o | FileCheck --check-prefix=VERIFY %s

# Check that the verifier correctly diagnoses various error conditions with
# the usage of string indices and string offsets tables.
# the usage of string indices/offsets and string offsets tables.

.section .debug_line_str,"MS",@progbits,1
str_comp_dir:
.asciz "llvm/test/tools/llvm-dwarfdump/X86"

.section .debug_str,"MS",@progbits,1
str_producer:
Expand All @@ -25,6 +29,8 @@ str_producer:
.byte 0x00 # DW_CHILDREN_no
.byte 0x25 # DW_AT_producer
.byte 0x1a # DW_FORM_strx
.byte 0x1b # DW_AT_comp_dir
.byte 0x1f # DW_FORM_line_strp
.byte 0x72 # DW_AT_str_offsets_base
.byte 0x17 # DW_FORM_sec_offset
.byte 0x00 # EOM(1)
Expand All @@ -45,6 +51,7 @@ CU1_5_version:
# The compile-unit DIE, which has DW_AT_producer and DW_AT_str_offsets.
.byte 1 # Abbreviation code
.byte 0 # Index of string for DW_AT_producer.
.long str_comp_dir # Offset of debug line string for DW_AT_comp_dir
.long 1000 # Bad value for DW_AT_str_offsets_base
.byte 0 # NULL
CU1_5_end:
Expand All @@ -61,12 +68,13 @@ CU2_5_version:
# The compile-unit DIE, which has DW_AT_producer and DW_AT_str_offsets.
.byte 1 # Abbreviation code
.byte 100 # Invalid string index
.long str_comp_dir # Offset of debug line string for DW_AT_comp_dir
.long .debug_str_offsets_base0
.byte 0 # NULL
CU2_5_end:

# The third unit's CU DIE uses a valid string index but the entry in the
# string offsets table is invalid.
# The third unit's CU DIE uses a valid string index but the entry in the
# string offsets table is invalid.

# DWARF v5 CU header
.long CU3_5_end-CU3_5_version # Length of Unit
Expand All @@ -78,11 +86,30 @@ CU3_5_version:
# The compile-unit DIE, which has DW_AT_producer and DW_AT_str_offsets.
.byte 1 # Abbreviation code
.byte 1 # Index of string for DW_AT_producer.
.long str_comp_dir # Offset of debug line string for DW_AT_comp_dir
.long .debug_str_offsets_base0
.byte 0 # NULL
CU3_5_end:


# The fourth unit's CU DIE has an invalid offset for the debug line string.

# DWARF v5 CU header
.long CU4_5_end-CU4_5_version # Length of Unit
CU4_5_version:
.short 5 # DWARF version number
.byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
# The compile-unit DIE, which has DW_AT_producer and DW_AT_str_offsets.
.byte 1 # Abbreviation code
.byte 0 # Index of string for DW_AT_producer.
.long 99999 # Invalid offset of debug line string for DW_AT_comp_dir
.long .debug_str_offsets_base0
.byte 0 # NULL
CU4_5_end:

# VERIFY-DAG: error: DW_FORM_strx used without a valid string offsets table:
# VERIFY-DAG: error: DW_FORM_strx uses index 100, which is too large:
# VERIFY-DAG: error: DW_FORM_strx uses index 1, but the referenced string offset
# VERIFY-DAG: error: DW_FORM_strx uses index 1, but the referenced string offset
# VERIFY-DAG-SAME: is beyond .debug_str bounds:
# VERIFY-DAG: error: DW_FORM_line_strp offset 99999 is beyond .debug_line_str bounds

0 comments on commit 277b898

Please sign in to comment.