mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[DWARF v5] Verifier: Add checks for DW_FORM_strx* forms.
Adding functionality to the DWARF verifier for DWARF v5 strx* forms which index into the string offsets table. Differential Revision: https://reviews.llvm.org/D54049 llvm-svn: 346061
This commit is contained in:
parent
d203f88115
commit
612e4a2932
@ -611,6 +611,45 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DW_FORM_strx:
|
||||
case DW_FORM_strx1:
|
||||
case DW_FORM_strx2:
|
||||
case DW_FORM_strx3:
|
||||
case DW_FORM_strx4: {
|
||||
auto Index = AttrValue.Value.getRawUValue();
|
||||
auto DieCU = Die.getDwarfUnit();
|
||||
// Check that we have a valid DWARF v5 string offsets table.
|
||||
if (!DieCU->getStringOffsetsTableContribution()) {
|
||||
++NumErrors;
|
||||
error() << FormEncodingString(Form)
|
||||
<< " used without a valid string offsets table:\n";
|
||||
dump(Die) << '\n';
|
||||
break;
|
||||
}
|
||||
// Check that the index is within the bounds of the section.
|
||||
unsigned ItemSize = DieCU->getDwarfStringOffsetsByteSize();
|
||||
// Use a 64-bit type to calculate the offset to guard against overflow.
|
||||
uint64_t Offset =
|
||||
(uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
|
||||
if (DObj.getStringOffsetSection().Data.size() < Offset + ItemSize) {
|
||||
++NumErrors;
|
||||
error() << FormEncodingString(Form) << " uses index "
|
||||
<< format("%" PRIu64, Index) << ", which is too large:\n";
|
||||
dump(Die) << '\n';
|
||||
break;
|
||||
}
|
||||
// Check that the string offset is valid.
|
||||
uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
|
||||
if (StringOffset >= DObj.getStringSection().size()) {
|
||||
++NumErrors;
|
||||
error() << FormEncodingString(Form) << " uses index "
|
||||
<< format("%" PRIu64, Index)
|
||||
<< ", but the referenced string"
|
||||
" offset is beyond .debug_str bounds:\n";
|
||||
dump(Die) << '\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
||||
# RUN: llvm-dwarfdump -v %t.o 2> %t.err | FileCheck --check-prefix=COMMON --check-prefix=SPLIT %s
|
||||
# RUN: llvm-dwarfdump -verify %t.o | FileCheck --check-prefix=VERIFY %s
|
||||
#
|
||||
# Check that we don't report an error on a non-existent range list table.
|
||||
# RUN: FileCheck -allow-empty --check-prefix ERR %s < %t.err
|
||||
@ -136,6 +137,8 @@ dwo_str_TU_5_type:
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x26 # DW_FORM_strx2
|
||||
.byte 0x49 # DW_AT_type
|
||||
.byte 0x13 # DW_FORM_ref4
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x06 # Abbrev code
|
||||
@ -143,6 +146,8 @@ dwo_str_TU_5_type:
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x27 # DW_FORM_strx3
|
||||
.byte 0x49 # DW_AT_type
|
||||
.byte 0x13 # DW_FORM_ref4
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x07 # Abbrev code
|
||||
@ -150,6 +155,15 @@ dwo_str_TU_5_type:
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x28 # DW_FORM_strx4
|
||||
.byte 0x49 # DW_AT_type
|
||||
.byte 0x13 # DW_FORM_ref4
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x08 # Abbrev code
|
||||
.byte 0x24 # DW_TAG_base_type
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x3e # DW_AT_encoding
|
||||
.byte 0x0b # DW_FORM_data1
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
@ -202,17 +216,24 @@ CU1_5_version:
|
||||
# A subprogram DIE with DW_AT_name, using DW_FORM_strx1.
|
||||
.byte 4 # Abbreviation code
|
||||
.byte 3 # Subprogram name string (DW_FORM_strx1)
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx2.
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx2, and DW_AT_type.
|
||||
.byte 5 # Abbreviation code
|
||||
.short 0x0004 # Subprogram name string (DW_FORM_strx2)
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx3.
|
||||
.long TypeDie-.debug_info
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx3, and DW_AT_type.
|
||||
.byte 6 # Abbreviation code
|
||||
.byte 5 # Subprogram name string (DW_FORM_strx3)
|
||||
.short 0 # Subprogram name string (DW_FORM_strx3)
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx4.
|
||||
.long TypeDie-.debug_info
|
||||
# A variable DIE with DW_AT_name, using DW_FORM_strx4, and DW_AT_type.
|
||||
.byte 7 # Abbreviation code
|
||||
.quad 0x00000006 # Subprogram name string (DW_FORM_strx4)
|
||||
.long 6 # Subprogram name string (DW_FORM_strx4)
|
||||
.long TypeDie-.debug_info
|
||||
.byte 0 # NULL
|
||||
# A base type DIE with DW_AT_encoding.
|
||||
TypeDie:
|
||||
.byte 8 # Abbreviation code
|
||||
.byte 5 # DW_ATE_signed
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
CU1_5_end:
|
||||
@ -386,4 +407,6 @@ TU_split_5_end:
|
||||
# SPLIT-NEXT: 0x00000014: 00000047 "V5_split_type_unit"
|
||||
# SPLIT-NEXT: 0x00000018: 0000005a "V5_split_Mystruct"
|
||||
|
||||
# VERIFY: No errors.
|
||||
|
||||
# ERR-NOT: parsing a range list table:
|
||||
|
@ -7,7 +7,7 @@
|
||||
# CHECK-NEXT: DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = "clang version 5.0.0 (trunk 308185) (llvm/trunk 308186)")
|
||||
# CHECK-NEXT: DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
|
||||
# CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000037] = "basic.c")
|
||||
# CHECK-NEXT: DW_AT_stmt_list [DW_FORM_strx4] ( indexed (00000000) string = )
|
||||
# CHECK-NEXT: DW_AT_stmt_list [DW_FORM_block4]
|
||||
# CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000003f] = "/Users/sgravani/Development/tests")
|
||||
# CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||
# CHECK-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000016){{[[:space:]]}}
|
||||
@ -82,7 +82,7 @@ Lsection_abbrev:
|
||||
.byte 3 ## DW_AT_name
|
||||
.byte 14 ## DW_FORM_strp
|
||||
.byte 16 ## DW_AT_stmt_list
|
||||
.byte 40 ## DW_FORM_sec_offset -- error: DIE has invalid DW_AT_stmt_list encoding:
|
||||
.byte 4 ## DW_FORM_sec_offset -- error: DIE has invalid DW_AT_stmt_list encoding:
|
||||
.byte 27 ## DW_AT_comp_dir
|
||||
.byte 14 ## DW_FORM_strp
|
||||
.byte 17 ## DW_AT_low_pc
|
||||
|
88
test/tools/llvm-dwarfdump/X86/verify_strings.s
Normal file
88
test/tools/llvm-dwarfdump/X86/verify_strings.s
Normal file
@ -0,0 +1,88 @@
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
||||
# 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.
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# The string offsets table
|
||||
.long .debug_str_offsets_segment0_end-.debug_str_offsets_base0+4
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base0:
|
||||
.long str_producer
|
||||
.long 1000 # Invalid string address.
|
||||
.debug_str_offsets_segment0_end:
|
||||
|
||||
# A simple abbrev section with a basic compile unit DIE.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x01 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# The first unit's CU DIE has an invalid DW_AT_str_offsets_base which
|
||||
# renders any string index unresolvable.
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_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 1000 # Bad value for DW_AT_str_offsets_base
|
||||
.byte 0 # NULL
|
||||
CU1_5_end:
|
||||
|
||||
# The second unit's CU DIE uses an invalid string index.
|
||||
|
||||
# DWARF v5 CU header
|
||||
.long CU2_5_end-CU2_5_version # Length of Unit
|
||||
CU2_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 100 # Invalid string index
|
||||
.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.
|
||||
|
||||
# DWARF v5 CU header
|
||||
.long CU3_5_end-CU3_5_version # Length of Unit
|
||||
CU3_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 1 # Index of string for DW_AT_producer.
|
||||
.long .debug_str_offsets_base0
|
||||
.byte 0 # NULL
|
||||
CU3_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-SAME: is beyond .debug_str bounds:
|
Loading…
Reference in New Issue
Block a user