[llvm] b4c5b8f - DWARFDebugLoclists: Make it possible to read relocated addresses

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 5 01:27:31 PST 2019


Author: Pavel Labath
Date: 2019-11-05T10:21:39+01:00
New Revision: b4c5b8f3f51206bac2282a8b483e76ad59a5aed5

URL: https://github.com/llvm/llvm-project/commit/b4c5b8f3f51206bac2282a8b483e76ad59a5aed5
DIFF: https://github.com/llvm/llvm-project/commit/b4c5b8f3f51206bac2282a8b483e76ad59a5aed5.diff

LOG: DWARFDebugLoclists: Make it possible to read relocated addresses

Summary:
Handling relocations was not needed when the loclists section was a
DWO-only thing. But since DWARF5, it is possible to use it in regular
objects too, and the standard permits embedding addresses into the
section directly. These addresses need to be relocated in unlinked
files.

Reviewers: JDevlieghere, dblaikie, probinson

Subscribers: aprantl, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDie.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index c79d98e34f6e..d5956a7613a8 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -105,16 +105,17 @@ class DWARFDebugLoclists {
   bool IsLittleEndian;
 
 public:
-  void parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version);
+  void parse(const DWARFDataExtractor &data, uint64_t Offset,
+             uint64_t EndOffset, uint16_t Version);
   void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo,
             DIDumpOptions DumpOpts, Optional<uint64_t> Offset) const;
 
   /// Return the location list at the given offset or nullptr.
   LocationList const *getLocationListAtOffset(uint64_t Offset) const;
 
-  static Expected<LocationList> parseOneLocationList(const DataExtractor &Data,
-                                                     uint64_t *Offset,
-                                                     unsigned Version);
+  static Expected<LocationList>
+  parseOneLocationList(const DWARFDataExtractor &Data, uint64_t *Offset,
+                       unsigned Version);
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index c06d85d50609..c5766b4440d1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -299,12 +299,11 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
     }
 
     Header.dump(OS, DumpOpts);
-    DataExtractor LocData(Data.getData(),
-                          Data.isLittleEndian(), Header.getAddrSize());
 
     DWARFDebugLoclists Loclists;
     uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
-    Loclists.parse(LocData, Offset, EndOffset, Header.getVersion());
+    Data.setAddressSize(Header.getAddrSize());
+    Loclists.parse(Data, Offset, EndOffset, Header.getVersion());
     Loclists.dump(OS, 0, MRI, DumpOpts, DumpOffset);
     Offset = EndOffset;
   }
@@ -733,7 +732,8 @@ const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
   // Assume all compile units have the same address byte size.
   // FIXME: We don't need AddressSize for split DWARF since relocatable
   // addresses cannot appear there. At the moment DWARFExpression requires it.
-  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
+  DWARFDataExtractor LocData(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
+                             4);
   // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
   // that means we are parsing the new style .debug_loc (pre-standatized version
   // of the .debug_loclists).

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 4f7b01130a47..032feb9088c1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -140,7 +140,7 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
 }
 
 Expected<DWARFDebugLoclists::LocationList>
-DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data,
+DWARFDebugLoclists::parseOneLocationList(const DWARFDataExtractor &Data,
                                          uint64_t *Offset, unsigned Version) {
   LocationList LL;
   LL.Offset = *Offset;
@@ -165,7 +165,7 @@ DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data,
         E.Value1 = Data.getULEB128(C);
       break;
     case dwarf::DW_LLE_start_length:
-      E.Value0 = Data.getAddress(C);
+      E.Value0 = Data.getRelocatedAddress(C);
       E.Value1 = Data.getULEB128(C);
       break;
     case dwarf::DW_LLE_offset_pair:
@@ -173,7 +173,7 @@ DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data,
       E.Value1 = Data.getULEB128(C);
       break;
     case dwarf::DW_LLE_base_address:
-      E.Value0 = Data.getAddress(C);
+      E.Value0 = Data.getRelocatedAddress(C);
       break;
     default:
       cantFail(C.takeError());
@@ -200,7 +200,8 @@ DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data,
   return LL;
 }
 
-void DWARFDebugLoclists::parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version) {
+void DWARFDebugLoclists::parse(const DWARFDataExtractor &data, uint64_t Offset,
+                               uint64_t EndOffset, uint16_t Version) {
   IsLittleEndian = data.isLittleEndian();
   AddressSize = data.getAddressSize();
 

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index cec194e8b6b3..f278a7a205e2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -119,13 +119,14 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
     }
 
     bool UseLocLists = !U->isDWOUnit();
-    StringRef LoclistsSectionData =
-        UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData();
-
-    if (!LoclistsSectionData.empty()) {
-      DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
-                         Obj.getAddressSize());
-
+    auto Data =
+        UseLocLists
+            ? DWARFDataExtractor(Obj, Obj.getLoclistsSection(),
+                                 Ctx.isLittleEndian(), Obj.getAddressSize())
+            : DWARFDataExtractor(U->getLocSectionData(), Ctx.isLittleEndian(),
+                                 Obj.getAddressSize());
+
+    if (!Data.getData().empty()) {
       // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
       // Modern locations list (.debug_loclists) are used starting from v5.
       // Ideally we should take the version from the .debug_loclists section

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s
new file mode 100644
index 000000000000..a44080eb9946
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s
@@ -0,0 +1,120 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+
+
+# CHECK:          DW_AT_location        (0x0000000c
+# CHECK-NEXT:        Addr idx 0 (w/ length 1): DW_OP_reg0 RAX
+# CHECK-NEXT:        [0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX
+# CHECK-NEXT:        [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
+# CHECK-NEXT:        [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
+# CHECK-NEXT:        Addr idx 57005 (w/ length 1): DW_OP_reg4 RSI)
+
+
+        .text
+f:                                      # @f
+.Lf0:
+        nop
+.Lf1:
+        nop
+.Lf2:
+        nop
+.Lf3:
+        nop
+.Lf4:
+.Lfend:
+                                        # -- End function
+        .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   3                       # DW_LLE_startx_length
+        .uleb128 0                      #   start idx
+        .uleb128 .Lf1-.Lf0              #   length
+        .byte   1                       # Loc expr size
+        .byte   80                      # super-register DW_OP_reg0
+        .byte   4                       # DW_LLE_offset_pair
+        .uleb128 .Lf1-.Lf0              #   starting offset
+        .uleb128 .Lf2-.Lf0              #   ending offset
+        .byte   1                       # Loc expr size
+        .byte   81                      # super-register DW_OP_reg1
+        .byte   8                       # DW_LLE_start_length
+        .quad   .Lf2                    #   starting offset
+        .uleb128 .Lf3-.Lf2              #   length
+        .byte   1                       # Loc expr size
+        .byte   82                      # super-register DW_OP_reg2
+        .byte   6                       # DW_LLE_base_address
+        .quad   .Lf3                    #   base address
+        .byte   4                       # DW_LLE_offset_pair
+        .uleb128 .Lf3-.Lf3              #   starting offset
+        .uleb128 .Lf4-.Lf3              #   ending offset
+        .byte   1                       # Loc expr size
+        .byte   83                      # super-register DW_OP_reg3
+        .byte   3                       # DW_LLE_startx_length
+        .uleb128 0xdead                 #   start idx
+        .uleb128 .Lf1-.Lf0              #   length
+        .byte   1                       # Loc expr size
+        .byte   84                      # super-register DW_OP_reg4
+        .byte   0                       # DW_LLE_end_of_list
+.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   115                     # DW_AT_addr_base
+        .byte   23                      # DW_FORM_sec_offset
+        .ascii  "\214\001"              # DW_AT_loclists_base
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   46                      # DW_TAG_subprogram
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   17                      # DW_AT_low_pc
+        .byte   27                      # DW_FORM_addrx
+        .byte   18                      # DW_AT_high_pc
+        .byte   6                       # DW_FORM_data4
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   5                       # DW_TAG_formal_parameter
+        .byte   0                       # DW_CHILDREN_no
+        .byte   2                       # DW_AT_location
+        .byte   23                      # DW_FORM_sec_offset
+        .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] 0xc:0x3c DW_TAG_compile_unit
+        .long   .Laddr_table_base0      # DW_AT_addr_base
+        .long   .Lloclists_table_base0  # DW_AT_loclists_base
+        .byte   2                       # Abbrev [2] 0x27:0x1c DW_TAG_subprogram
+        .byte   0                       # DW_AT_low_pc
+        .long   .Lfend-.Lf0             # DW_AT_high_pc
+        .byte   3                       # Abbrev [3] 0x36:0xc DW_TAG_formal_parameter
+        .long   .Ldebug_loc0            # DW_AT_location
+        .byte   0                       # End Of Children Mark
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
+
+        .section        .debug_addr,"", at progbits
+        .long   .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+        .short  5                       # DWARF version number
+        .byte   8                       # Address size
+        .byte   0                       # Segment selector size
+.Laddr_table_base0:
+        .quad   .Lf0
+.Ldebug_addr_end0:


        


More information about the llvm-commits mailing list