[lld] 49cbf4c - Fix bug in .eh_frame/.debug_frame PC offset calculation for DW_EH_PE_pcrel

Alex Orlov via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 15 04:06:34 PDT 2021


Author: Alex Orlov
Date: 2021-04-15T15:06:20+04:00
New Revision: 49cbf4cd85a9ae6b53947fb8cf39ccfb56becc57

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

LOG: Fix bug in .eh_frame/.debug_frame PC offset calculation for DW_EH_PE_pcrel

This fixes the following bugs:
https://bugs.llvm.org/show_bug.cgi?id=27249
https://bugs.llvm.org/show_bug.cgi?id=46414

Reviewed By: MaskRay

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

Added: 
    

Modified: 
    lld/test/ELF/eh-frame-hdr-augmentation.s
    llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
    llvm/test/tools/llvm-objdump/MachO/eh_frame-arm64.test

Removed: 
    


################################################################################
diff  --git a/lld/test/ELF/eh-frame-hdr-augmentation.s b/lld/test/ELF/eh-frame-hdr-augmentation.s
index 9c9b862ae80d5..4fe6a5fd45e71 100644
--- a/lld/test/ELF/eh-frame-hdr-augmentation.s
+++ b/lld/test/ELF/eh-frame-hdr-augmentation.s
@@ -12,7 +12,7 @@
 // CHECK-NEXT:   Code alignment factor: 1
 // CHECK-NEXT:   Data alignment factor: -8
 // CHECK-NEXT:   Return address column: 16
-// CHECK-NEXT:   Personality Address: 0000000000001029
+// CHECK-NEXT:   Personality Address: 000000000000127c
 // CHECK-NEXT:   Augmentation data:
 
 // CHECK:      DW_CFA_def_cfa:  reg7 +8
@@ -21,9 +21,9 @@
 // CHECK-NEXT: DW_CFA_nop:
 
 /// FIXME Handle relocation correctly
-// CHECK:      00000020 00000014 00000024 FDE cie=00000000 pc=0000103c...0000103c
+// CHECK:      00000020 00000014 00000024 FDE cie=00000000 pc=0000127c...0000127c
 // CHECK-NEXT:   Format:       DWARF32
-// CHECK-NEXT:   LSDA Address: 000000000000100b
+// CHECK-NEXT:   LSDA Address: 000000000000127c
 // CHECK-NEXT:   DW_CFA_nop:
 // CHECK-NEXT:   DW_CFA_nop:
 // CHECK-NEXT:   DW_CFA_nop:

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
index 054524d368ed5..e03dc21fb6f00 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h
@@ -15,6 +15,7 @@ namespace llvm {
 
 struct DWARFSection {
   StringRef Data;
+  uint64_t Address = 0;
 };
 
 struct SectionName {

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index b655bee9c1d22..806d8b210b3fa 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -823,6 +823,8 @@ Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
   if (DebugFrame)
     return DebugFrame.get();
 
+  const DWARFSection &DS = DObj->getFrameSection();
+
   // There's a "bug" in the DWARFv3 standard with respect to the target address
   // size within debug frame sections. While DWARF is supposed to be independent
   // of its container, FDEs have fields with size being "target address size",
@@ -832,10 +834,11 @@ Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
   // provides this information). This problem is fixed in DWARFv4
   // See this dwarf-discuss discussion for more details:
   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
-  DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
-                                    isLittleEndian(), DObj->getAddressSize());
-  auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false);
-  if (Error E = DF->parse(debugFrameData))
+  DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
+                                    DObj->getAddressSize());
+  auto DF =
+      std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false, DS.Address);
+  if (Error E = DF->parse(DebugFrameData))
     return std::move(E);
 
   DebugFrame.swap(DF);
@@ -846,11 +849,13 @@ Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
   if (EHFrame)
     return EHFrame.get();
 
-  DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
-                                    isLittleEndian(), DObj->getAddressSize());
+  const DWARFSection &DS = DObj->getEHFrameSection();
+  DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
+                                    DObj->getAddressSize());
 
-  auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true);
-  if (Error E = DF->parse(debugFrameData))
+  auto DF =
+      std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true, DS.Address);
+  if (Error E = DF->parse(DebugFrameData))
     return std::move(E);
   DebugFrame.swap(DF);
   return DebugFrame.get();
@@ -1707,6 +1712,9 @@ class DWARFObjInMemory final : public DWARFObject {
         if (Name == "debug_ranges") {
           // FIXME: Use the other dwo range section when we emit it.
           RangesDWOSection.Data = Data;
+        } else if (Name == "debug_frame" || Name == "eh_frame") {
+          if (DWARFSection *S = mapNameToDWARFSection(Name))
+            S->Address = Section.getAddress();
         }
       } else if (InfoSectionMap *Sections =
                      StringSwitch<InfoSectionMap *>(Name)

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
index 27e5dfa622b31..55981dda69ad7 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
@@ -9,7 +9,7 @@ CHECK-NOT: pc
 RUN: llvm-dwarfdump %p/../../dsymutil/Inputs/basic1.macho.x86_64.o \
 RUN:   -eh-frame=0x00000018 | FileCheck %s --check-prefix=EH
 EH: .eh_frame contents:
-EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=fffffffffffffd20...fffffffffffffd44
+EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=00000000...00000024
 EH-NEXT:   Format:       DWARF32
 EH-NEXT:   DW_CFA_advance_loc: 1
 EH-NOT: pc

diff  --git a/llvm/test/tools/llvm-objdump/MachO/eh_frame-arm64.test b/llvm/test/tools/llvm-objdump/MachO/eh_frame-arm64.test
index 31f87a5035e7e..f732495b8672e 100644
--- a/llvm/test/tools/llvm-objdump/MachO/eh_frame-arm64.test
+++ b/llvm/test/tools/llvm-objdump/MachO/eh_frame-arm64.test
@@ -12,7 +12,7 @@
 
 # CHECK:   DW_CFA_def_cfa: reg31 +0
 
-# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=00000000...00000020
+# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=00000050...00000070
 # CHECK:   DW_CFA_advance_loc: 8
 # CHECK:   DW_CFA_def_cfa_offset: +16
 # CHECK:   DW_CFA_offset: reg30 -8


        


More information about the llvm-commits mailing list