[llvm] r370868 - DWARF: Fix a regression in location list dumping

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 03:09:12 PDT 2019


Author: labath
Date: Wed Sep  4 03:09:12 2019
New Revision: 370868

URL: http://llvm.org/viewvc/llvm-project?rev=370868&view=rev
Log:
DWARF: Fix a regression in location list dumping

Summary:
While fixing the handling of some error cases, r370363 introduced new
problems -- assertion failures due to unchecked errors (my excuse is that a very
early version of that patch used Optional<T> instead of Expected).

This patch adds proper handling of parsing errors encountered when
dumping location lists from inside DWARF DIEs, and adds a bunch of
additional tests.

I reorder the arguments of the location list dumping functions to make
them consistent, and also be able to dump the two kinds of location
lists generically.

Reviewers: JDevlieghere, dblaikie, probinson

Subscribers: aprantl, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67102

Added:
    llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loc-error-cases2.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h?rev=370868&r1=370867&r2=370868&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h Wed Sep  4 03:09:12 2019
@@ -40,8 +40,8 @@ public:
     /// All the locations in which the variable is stored.
     SmallVector<Entry, 2> Entries;
     /// Dump this list on OS.
-    void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize,
-              const MCRegisterInfo *MRI, DWARFUnit *U, uint64_t BaseAddress,
+    void dump(raw_ostream &OS, uint64_t BaseAddress, bool IsLittleEndian,
+              unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U,
               unsigned Indent) const;
   };
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp?rev=370868&r1=370867&r2=370868&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp Wed Sep  4 03:09:12 2019
@@ -35,11 +35,10 @@ static void dumpExpression(raw_ostream &
   DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U);
 }
 
-void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
+void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, uint64_t BaseAddress,
+                                       bool IsLittleEndian,
                                        unsigned AddressSize,
-                                       const MCRegisterInfo *MRI,
-                                       DWARFUnit *U,
-                                       uint64_t BaseAddress,
+                                       const MCRegisterInfo *MRI, DWARFUnit *U,
                                        unsigned Indent) const {
   for (const Entry &E : Entries) {
     OS << '\n';
@@ -67,7 +66,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS
                          Optional<uint64_t> Offset) const {
   auto DumpLocationList = [&](const LocationList &L) {
     OS << format("0x%8.8" PRIx64 ": ", L.Offset);
-    L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12);
+    L.dump(OS, 0, IsLittleEndian, AddressSize, MRI, nullptr, 12);
     OS << "\n\n";
   };
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=370868&r1=370867&r2=370868&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Wed Sep  4 03:09:12 2019
@@ -21,6 +21,7 @@
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/WithColor.h"
@@ -91,21 +92,27 @@ static void dumpLocation(raw_ostream &OS
   }
 
   FormValue.dump(OS, DumpOpts);
+  const auto &DumpLL = [&](auto ExpectedLL) {
+    if (ExpectedLL) {
+      uint64_t BaseAddr = 0;
+      if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
+        BaseAddr = BA->Address;
+      ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(),
+                       MRI, U, Indent);
+    } else {
+      OS << '\n';
+      OS.indent(Indent);
+      OS << formatv("error extracting location list: {0}",
+                    fmt_consume(ExpectedLL.takeError()));
+    }
+  };
   if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
     uint64_t Offset = *FormValue.getAsSectionOffset();
     if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
       DWARFDebugLoc DebugLoc;
       DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
                               Obj.getAddressSize());
-      auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
-      if (LL) {
-        uint64_t BaseAddr = 0;
-        if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
-          BaseAddr = BA->Address;
-        LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
-                 BaseAddr, Indent);
-      } else
-        OS << "error extracting location list.";
+      DumpLL(DebugLoc.parseOneLocationList(Data, &Offset));
       return;
     }
 
@@ -121,18 +128,8 @@ static void dumpLocation(raw_ostream &OS
       // Modern locations list (.debug_loclists) are used starting from v5.
       // Ideally we should take the version from the .debug_loclists section
       // header, but using CU's version for simplicity.
-      auto LL = DWARFDebugLoclists::parseOneLocationList(
-          Data, &Offset, UseLocLists ? U->getVersion() : 4);
-
-      uint64_t BaseAddr = 0;
-      if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
-        BaseAddr = BA->Address;
-
-      if (LL)
-        LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
-                 U, Indent);
-      else
-        OS << "error extracting location list.";
+      DumpLL(DWARFDebugLoclists::parseOneLocationList(
+          Data, &Offset, UseLocLists ? U->getVersion() : 4));
     }
   }
 }

Added: llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loc-error-cases2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loc-error-cases2.s?rev=370868&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loc-error-cases2.s (added)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loc-error-cases2.s Wed Sep  4 03:09:12 2019
@@ -0,0 +1,121 @@
+# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+
+# CHECK:      DW_AT_name        ("x0")
+# CHECK-NEXT: DW_AT_location    (0x00000000
+# CHECK-NEXT:    [0x0000000000000000,  0x0000000000000002): DW_OP_reg5 RDI
+# CHECK-NEXT:    [0x0000000000000002,  0x0000000000000003): DW_OP_reg0 RAX)
+
+# CHECK:      DW_AT_name        ("x1")
+# CHECK-NEXT: DW_AT_location    (0xdeadbeef
+# CHECK-NEXT:    error extracting location list: unexpected end of data)
+
+# CHECK:      DW_AT_name        ("x2")
+# CHECK-NEXT: DW_AT_location    (0x00000036
+# CHECK-NEXT:    error extracting location list: unexpected end of data)
+
+
+        .type   f, at function
+f:                                      # @f
+.Lfunc_begin0:
+        movl    %edi, %eax
+.Ltmp0:
+        retq
+.Ltmp1:
+.Lfunc_end0:
+        .size   f, .Lfunc_end0-f
+
+        .section        .debug_str,"MS", at progbits,1
+.Linfo_string0:
+        .asciz  "Hand-written DWARF"
+.Linfo_string3:
+        .asciz  "f"
+.Linfo_string4:
+        .asciz  "int"
+.Lx0:
+        .asciz  "x0"
+.Lx1:
+        .asciz  "x1"
+.Lx2:
+        .asciz  "x2"
+
+        .section        .debug_loc,"", at progbits
+.Ldebug_loc0:
+        .quad   .Lfunc_begin0-.Lfunc_begin0
+        .quad   .Ltmp0-.Lfunc_begin0
+        .short  1                       # Loc expr size
+        .byte   85                      # super-register DW_OP_reg5
+        .quad   .Ltmp0-.Lfunc_begin0
+        .quad   .Lfunc_end0-.Lfunc_begin0
+        .short  1                       # Loc expr size
+        .byte   80                      # super-register DW_OP_reg0
+        .quad   0
+        .quad   0
+.Ldebug_loc2:
+        .quad   .Lfunc_begin0-.Lfunc_begin0
+        .quad   .Lfunc_end0-.Lfunc_begin0
+        .short  0xdead                  # Loc expr size
+
+        .section        .debug_abbrev,"", at progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   14                      # DW_FORM_strp
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   46                      # DW_TAG_subprogram
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   5                       # DW_TAG_formal_parameter
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   2                       # DW_AT_location
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   4                       # Abbreviation Code
+        .byte   36                      # DW_TAG_base_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   62                      # DW_AT_encoding
+        .byte   11                      # DW_FORM_data1
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+        .section        .debug_info,"", at progbits
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   1                       # Abbrev [1] 0xb:0x50 DW_TAG_compile_unit
+        .long   .Linfo_string0          # DW_AT_producer
+        .short  12                      # DW_AT_language
+        .byte   2                       # Abbrev [2] 0x2a:0x29 DW_TAG_subprogram
+        .long   .Linfo_string3          # DW_AT_name
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx0                    # DW_AT_name
+        .long   .Ldebug_loc0            # DW_AT_location
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx1                    # DW_AT_name
+        .long   0xdeadbeef              # DW_AT_location
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx2                    # DW_AT_name
+        .long   .Ldebug_loc2            # DW_AT_location
+        .byte   0                       # End Of Children Mark
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:

Added: llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s?rev=370868&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s (added)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s Wed Sep  4 03:09:12 2019
@@ -0,0 +1,132 @@
+# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+
+# CHECK:      DW_AT_name        ("x0")
+# CHECK-NEXT: DW_AT_location    (0x0000000c
+# CHECK-NEXT:    [0x0000000000000000,  0x0000000000000002): DW_OP_reg5 RDI
+# CHECK-NEXT:    [0x0000000000000002,  0x0000000000000003): DW_OP_reg0 RAX)
+
+# CHECK:      DW_AT_name        ("x1")
+# CHECK-NEXT: DW_AT_location    (0xdeadbeef
+# CHECK-NEXT:    error extracting location list: unexpected end of data)
+
+# CHECK:      DW_AT_name        ("x2")
+# CHECK-NEXT: DW_AT_location    (0x00000025
+# CHECK-NEXT:    error extracting location list: unexpected end of data)
+
+
+        .type   f, at function
+f:                                      # @f
+.Lfunc_begin0:
+        movl    %edi, %eax
+.Ltmp0:
+        retq
+.Ltmp1:
+.Lfunc_end0:
+        .size   f, .Lfunc_end0-f
+
+        .section        .debug_str,"MS", at progbits,1
+.Linfo_string0:
+        .asciz  "Hand-written DWARF"
+.Linfo_string3:
+        .asciz  "f"
+.Linfo_string4:
+        .asciz  "int"
+.Lx0:
+        .asciz  "x0"
+.Lx1:
+        .asciz  "x1"
+.Lx2:
+        .asciz  "x2"
+
+        .section        .debug_loclists,"", at progbits
+        .long   .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0 # Length
+.Ldebug_loclist_table_start0:
+        .short  5                       # Version
+        .byte   8                       # Address size
+        .byte   0                       # Segment selector size
+        .long   0                       # Offset entry count
+.Lloclists_table_base0:
+.Ldebug_loc0:
+        .byte   8                       # DW_LLE_start_length
+        .quad   .Lfunc_begin0-.Lfunc_begin0 #   starting offset
+        .uleb128 .Ltmp0-.Lfunc_begin0   #   size
+        .byte   1                       # Loc expr size
+        .byte   85                      # super-register DW_OP_reg5
+        .byte   8                       # DW_LLE_start_length
+        .quad   .Ltmp0-.Lfunc_begin0    #   starting offset
+        .uleb128 .Lfunc_end0-.Ltmp0     #   size
+        .byte   1                       # Loc expr size
+        .byte   80                      # super-register DW_OP_reg0
+        .byte   0                       # DW_LLE_end_of_list
+.Ldebug_loc2:
+        .byte   8                       # DW_LLE_start_length
+        .quad   .Lfunc_begin0-.Lfunc_begin0 #   starting offset
+        .uleb128 .Ltmp0-.Lfunc_begin0   #   size
+        .uleb128  0xdeadbeef              # Loc expr size
+.Ldebug_loclist_table_end0:
+
+        .section        .debug_abbrev,"", at progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   14                      # DW_FORM_strp
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   46                      # DW_TAG_subprogram
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   5                       # DW_TAG_formal_parameter
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   2                       # DW_AT_location
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   4                       # Abbreviation Code
+        .byte   36                      # DW_TAG_base_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   62                      # DW_AT_encoding
+        .byte   11                      # DW_FORM_data1
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+        .section        .debug_info,"", at progbits
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  5                       # DWARF version number
+        .byte   1                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   1                       # Abbrev [1] 0xb:0x50 DW_TAG_compile_unit
+        .long   .Linfo_string0          # DW_AT_producer
+        .short  12                      # DW_AT_language
+        .byte   2                       # Abbrev [2] 0x2a:0x29 DW_TAG_subprogram
+        .long   .Linfo_string3          # DW_AT_name
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx0                    # DW_AT_name
+        .long   .Ldebug_loc0            # DW_AT_location
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx1                    # DW_AT_name
+        .long   0xdeadbeef              # DW_AT_location
+        .byte   3                       # Abbrev [3] DW_TAG_formal_parameter
+        .long   .Lx2                    # DW_AT_name
+        .long   .Ldebug_loc2            # DW_AT_location
+        .byte   0                       # End Of Children Mark
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:




More information about the llvm-commits mailing list