[llvm] r346061 - [DWARF v5] Verifier: Add checks for DW_FORM_strx* forms.

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 2 17:27:35 PDT 2018


Author: wolfgangp
Date: Fri Nov  2 17:27:35 2018
New Revision: 346061

URL: http://llvm.org/viewvc/llvm-project?rev=346061&view=rev
Log:
[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

Added:
    llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_strings.s
Modified:
    llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s
    llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=346061&r1=346060&r2=346061&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Fri Nov  2 17:27:35 2018
@@ -611,6 +611,45 @@ unsigned DWARFVerifier::verifyDebugInfoF
     }
     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;
   }

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s?rev=346061&r1=346060&r2=346061&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s Fri Nov  2 17:27:35 2018
@@ -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:

Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s?rev=346061&r1=346060&r2=346061&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_debug_info.s Fri Nov  2 17:27:35 2018
@@ -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

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_strings.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_strings.s?rev=346061&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_strings.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_strings.s Fri Nov  2 17:27:35 2018
@@ -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", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+
+        .section .debug_str_offsets,"", at 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,"", at 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,"", at 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:




More information about the llvm-commits mailing list