.debug_names: Correctly align the AugmentationStringSize field
authorPavel Labath <labath@google.com>
Thu, 29 Mar 2018 15:12:45 +0000 (15:12 +0000)
committerPavel Labath <labath@google.com>
Thu, 29 Mar 2018 15:12:45 +0000 (15:12 +0000)
We should align the value of the field, not the overall section offset.

This distinction matters if one of the debug_names contributions is not
of size which is a multiple of four. The dwarf producers may choose to
emit rounded contributions, but they are not required to do so. In the
latter case, without this patch we would corrupt the parsing state, as
we would adjust the offset even if subsequent contributions contained
correctly rounded augmentation strings.

llvm-svn: 328796

llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug-names-misaligned.s [new file with mode: 0644]

index 4017411..fccff27 100644 (file)
@@ -385,7 +385,7 @@ llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
   BucketCount = AS.getU32(Offset);
   NameCount = AS.getU32(Offset);
   AbbrevTableSize = AS.getU32(Offset);
-  AugmentationStringSize = AS.getU32(Offset);
+  AugmentationStringSize = alignTo(AS.getU32(Offset), 4);
 
   if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize))
     return make_error<StringError>(
@@ -394,7 +394,6 @@ llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
   AugmentationString.resize(AugmentationStringSize);
   AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()),
            AugmentationStringSize);
-  *Offset = alignTo(*Offset, 4);
   return Error::success();
 }
 
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-misaligned.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-misaligned.s
new file mode 100644 (file)
index 0000000..0acc745
--- /dev/null
@@ -0,0 +1,101 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj -o - | llvm-dwarfdump -debug-names - | FileCheck %s
+       .section        .debug_str,"MS",@progbits,1
+.Linfo_string0:
+       .asciz  "foo"
+.Linfo_string1:
+       .asciz  "bar"
+
+# Fake .debug_info. We just need it for the offsets to two "compile units" and
+# two "DIEs"
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .byte   0
+.Ldie0:
+       .byte   0
+.Lcu_begin1:
+       .byte   0
+.Ldie1:
+       .byte   0
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   1                       # Header: name count
+       .long   .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+       .long   .Linfo_string0          # String 1: foo
+       .long   .Lnames0-.Lnames_entries0 # Offset 1
+.Lnames_abbrev_start0:
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+       .byte   3                       # DW_IDX_die_offset
+       .byte   19                      # DW_FORM_ref4
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames0:
+       .byte   46                      # Abbrev code
+       .long   .Ldie0-.Lcu_begin0      # DW_IDX_die_offset
+       .long   0                       # End of list: foo
+       .p2align        2
+        .byte   42                      # Deliberately misalign the next contribution
+.Lnames_end0:
+
+       .long   .Lnames_end1-.Lnames_start1 # Header: contribution length
+.Lnames_start1:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   1                       # Header: name count
+       .long   .Lnames_abbrev_end1-.Lnames_abbrev_start1 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin1             # Compilation unit 0
+       .long   .Linfo_string1          # String 1: bar
+       .long   .Lnames1-.Lnames_entries1 # Offset 1
+.Lnames_abbrev_start1:
+       .byte   52                      # Abbrev code
+       .byte   52                      # DW_TAG_variable
+       .byte   3                       # DW_IDX_die_offset
+       .byte   19                      # DW_FORM_ref4
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end1:
+.Lnames_entries1:
+.Lnames1:
+       .byte   52                      # Abbrev code
+       .long   .Ldie1-.Lcu_begin1      # DW_IDX_die_offset
+       .long   0                       # End of list: bar
+       .p2align        2
+.Lnames_end1:
+# CHECK:     Name Index @ 0x0
+# CHECK:       Name 1 {
+# CHECK-NEXT:    String: 0x00000000 "foo"
+# CHECK-NEXT:    Entry @ 0x37 {
+# CHECK-NEXT:      Abbrev: 0x2E
+# CHECK-NEXT:      Tag: DW_TAG_subprogram
+# CHECK-NEXT:      DW_IDX_die_offset: 0x00000001
+# CHECK-NEXT:    }
+# CHECK-NEXT:  }
+
+# CHECK:     Name Index @ 0x41
+# CHECK:       Name 1 {
+# CHECK-NEXT:    String: 0x00000004 "bar"
+# CHECK-NEXT:    Entry @ 0x78 {
+# CHECK-NEXT:      Abbrev: 0x34
+# CHECK-NEXT:      Tag: DW_TAG_variable
+# CHECK-NEXT:      DW_IDX_die_offset: 0x00000001
+# CHECK-NEXT:    }
+# CHECK-NEXT:  }