[DebugInfo] Do not truncate 64-bit values when dumping CIEs and FDEs.
authorIgor Kudrin <ikudrin@accesssoftek.com>
Tue, 28 Jan 2020 07:11:54 +0000 (14:11 +0700)
committerIgor Kudrin <ikudrin@accesssoftek.com>
Thu, 5 Mar 2020 10:37:28 +0000 (17:37 +0700)
This fixes printing long values that might reside in CIE and FDE,
including offsets, lengths, and addresses.

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

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test
llvm/test/tools/llvm-objdump/eh_frame-arm64.test
llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp [new file with mode: 0644]

index eb20db0..1eb22b2 100644 (file)
@@ -132,9 +132,9 @@ class FrameEntry {
 public:
   enum FrameKind { FK_CIE, FK_FDE };
 
-  FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
-             int64_t DataAlign, Triple::ArchType Arch)
-      : Kind(K), Offset(Offset), Length(Length),
+  FrameEntry(FrameKind K, bool IsDWARF64, uint64_t Offset, uint64_t Length,
+             uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
+      : Kind(K), IsDWARF64(IsDWARF64), Offset(Offset), Length(Length),
         CFIs(CodeAlign, DataAlign, Arch) {}
 
   virtual ~FrameEntry() {}
@@ -152,6 +152,8 @@ public:
 protected:
   const FrameKind Kind;
 
+  const bool IsDWARF64;
+
   /// Offset of this entry in the section.
   const uint64_t Offset;
 
@@ -166,14 +168,14 @@ class CIE : public FrameEntry {
 public:
   // CIEs (and FDEs) are simply container classes, so the only sensible way to
   // create them is by providing the full parsed contents in the constructor.
-  CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
+  CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint8_t Version,
       SmallString<8> Augmentation, uint8_t AddressSize,
       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
       SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
       uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
       Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
-      : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
+      : FrameEntry(FK_CIE, IsDWARF64, Offset, Length, CodeAlignmentFactor,
                    DataAlignmentFactor, Arch),
         Version(Version), Augmentation(std::move(Augmentation)),
         AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
@@ -223,10 +225,10 @@ private:
 /// DWARF Frame Description Entry (FDE)
 class FDE : public FrameEntry {
 public:
-  FDE(uint64_t Offset, uint64_t Length, uint64_t CIEPointer,
+  FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer,
       uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
       Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
-      : FrameEntry(FK_FDE, Offset, Length,
+      : FrameEntry(FK_FDE, IsDWARF64, Offset, Length,
                    Cie ? Cie->getCodeAlignmentFactor() : 0,
                    Cie ? Cie->getDataAlignmentFactor() : 0,
                    Arch),
index fec1bc1..7c1280d 100644 (file)
@@ -298,9 +298,11 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
 }
 
 void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
-  OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length,
-               IsEH ? 0 : DW_CIE_ID)
-     << "\n";
+  OS << format("%08" PRIx64, Offset)
+     << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
+     << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
+               getCIEId(IsDWARF64, IsEH))
+     << " CIE\n";
   OS << format("  Version:               %d\n", Version);
   OS << "  Augmentation:          \"" << Augmentation << "\"\n";
   if (Version >= 4) {
@@ -325,15 +327,16 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
 }
 
 void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
-  OS << format("%08x %08x %08x", (uint32_t)Offset, (uint32_t)Length,
-               (uint32_t)CIEPointer)
+  OS << format("%08" PRIx64, Offset)
+     << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
+     << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
      << " FDE cie=";
   if (LinkedCIE)
-    OS << format("%08x", (uint32_t)(LinkedCIE->getOffset()));
+    OS << format("%08" PRIx64, LinkedCIE->getOffset());
   else
     OS << "<invalid offset>";
-  OS << format(" pc=%08x...%08x\n", (uint32_t)InitialLocation,
-               (uint32_t)InitialLocation + (uint32_t)AddressRange);
+  OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
+               InitialLocation + AddressRange);
   if (LSDAAddress)
     OS << format("  LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
   CFIs.dump(OS, MRI, IsEH);
@@ -469,10 +472,11 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
       }
 
       auto Cie = std::make_unique<CIE>(
-          StartOffset, Length, Version, AugmentationString, AddressSize,
-          SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
-          ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
-          LSDAPointerEncoding, Personality, PersonalityEncoding, Arch);
+          IsDWARF64, StartOffset, Length, Version, AugmentationString,
+          AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
+          DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
+          FDEPointerEncoding, LSDAPointerEncoding, Personality,
+          PersonalityEncoding, Arch);
       CIEs[StartOffset] = Cie.get();
       Entries.emplace_back(std::move(Cie));
     } else {
@@ -522,9 +526,9 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
         AddressRange = Data.getRelocatedAddress(&Offset);
       }
 
-      Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
-                                   InitialLocation, AddressRange,
-                                   Cie, LSDAAddress, Arch));
+      Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
+                                   InitialLocation, AddressRange, Cie,
+                                   LSDAAddress, Arch));
     }
 
     if (Error E =
index 5db8816..269ef47 100644 (file)
@@ -8,7 +8,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=fffffd00...fffffd24
+EH-NEXT: 00000018 00000024 0000001c FDE cie=00000000 pc=fffffffffffffd00...fffffffffffffd24
 EH-NEXT:   DW_CFA_advance_loc: 1
 EH-NOT: pc
 EH-NOT: CIE
index 169b908..c04de08 100644 (file)
@@ -12,7 +12,7 @@
 
 # CHECK:   DW_CFA_def_cfa: reg31 +0
 
-# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=ffffffe4...00000004
+# CHECK: 00000014 00000020 00000018 FDE cie=00000000 pc=ffffffffffffffe4...00000004
 # CHECK:   DW_CFA_advance_loc: 8
 # CHECK:   DW_CFA_def_cfa_offset: +16
 # CHECK:   DW_CFA_offset: reg30 -8
index bb03231..d7e7ed2 100644 (file)
@@ -14,6 +14,7 @@ add_llvm_unittest(DebugInfoDWARFTests
   DWARFAcceleratorTableTest.cpp
   DWARFDataExtractorTest.cpp
   DWARFDebugArangeSetTest.cpp
+  DWARFDebugFrameTest.cpp
   DWARFDebugInfoTest.cpp
   DWARFDebugLineTest.cpp
   DWARFDieTest.cpp
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp
new file mode 100644 (file)
index 0000000..a7465a8
--- /dev/null
@@ -0,0 +1,122 @@
+//===- llvm/unittest/DebugInfo/DWARFDebugFrameTest.cpp --------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+dwarf::CIE createCIE(bool IsDWARF64, uint64_t Offset, uint64_t Length) {
+  return dwarf::CIE(IsDWARF64, Offset, Length,
+                    /*Version=*/3,
+                    /*Augmentation=*/StringRef(),
+                    /*AddressSize=*/8,
+                    /*SegmentDescriptorSize=*/0,
+                    /*CodeAlignmentFactor=*/1,
+                    /*DataAlignmentFactor=*/-8,
+                    /*ReturnAddressRegister=*/16,
+                    /*AugmentationData=*/StringRef(),
+                    /*FDEPointerEncoding=*/dwarf::DW_EH_PE_absptr,
+                    /*LSDAPointerEncoding=*/dwarf::DW_EH_PE_omit,
+                    /*Personality=*/None,
+                    /*PersonalityEnc=*/None,
+                    /*Arch=*/Triple::x86_64);
+}
+
+void expectDumpResult(const dwarf::CIE &TestCIE, bool IsEH,
+                      StringRef ExpectedFirstLine) {
+  std::string Output;
+  raw_string_ostream OS(Output);
+  TestCIE.dump(OS, /*MRI=*/nullptr, IsEH);
+  OS.flush();
+  StringRef FirstLine = StringRef(Output).split('\n').first;
+  EXPECT_EQ(FirstLine, ExpectedFirstLine);
+}
+
+void expectDumpResult(const dwarf::FDE &TestFDE, bool IsEH,
+                      StringRef ExpectedFirstLine) {
+  std::string Output;
+  raw_string_ostream OS(Output);
+  TestFDE.dump(OS, /*MRI=*/nullptr, IsEH);
+  OS.flush();
+  StringRef FirstLine = StringRef(Output).split('\n').first;
+  EXPECT_EQ(FirstLine, ExpectedFirstLine);
+}
+
+TEST(DWARFDebugFrame, DumpDWARF32CIE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
+                                 /*Offset=*/0x1111abcd,
+                                 /*Length=*/0x2222abcd);
+  expectDumpResult(TestCIE, /*IsEH=*/false, "1111abcd 2222abcd ffffffff CIE");
+}
+
+TEST(DWARFDebugFrame, DumpDWARF64CIE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
+                                 /*Offset=*/0x1111abcdabcd,
+                                 /*Length=*/0x2222abcdabcd);
+  expectDumpResult(TestCIE, /*IsEH=*/false,
+                   "1111abcdabcd 00002222abcdabcd ffffffffffffffff CIE");
+}
+
+TEST(DWARFDebugFrame, DumpEHCIE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
+                                 /*Offset=*/0x1000,
+                                 /*Length=*/0x20);
+  expectDumpResult(TestCIE, /*IsEH=*/true, "00001000 00000020 00000000 CIE");
+}
+
+TEST(DWARFDebugFrame, DumpEH64CIE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
+                                 /*Offset=*/0x1000,
+                                 /*Length=*/0x20);
+  expectDumpResult(TestCIE, /*IsEH=*/true,
+                   "00001000 0000000000000020 00000000 CIE");
+}
+
+TEST(DWARFDebugFrame, DumpDWARF64FDE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
+                                 /*Offset=*/0x1111abcdabcd,
+                                 /*Length=*/0x2222abcdabcd);
+  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
+                     /*Offset=*/0x3333abcdabcd,
+                     /*Length=*/0x4444abcdabcd,
+                     /*CIEPointer=*/0x1111abcdabcd,
+                     /*InitialLocation=*/0x5555abcdabcd,
+                     /*AddressRange=*/0x111111111111,
+                     /*Cie=*/&TestCIE,
+                     /*LSDAAddress=*/None,
+                     /*Arch=*/Triple::x86_64);
+  expectDumpResult(TestFDE, /*IsEH=*/false,
+                   "3333abcdabcd 00004444abcdabcd 00001111abcdabcd FDE "
+                   "cie=1111abcdabcd pc=5555abcdabcd...6666bcdebcde");
+}
+
+TEST(DWARFDebugFrame, DumpEH64FDE) {
+  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
+                                 /*Offset=*/0x1111ab9a000c,
+                                 /*Length=*/0x20);
+  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
+                     /*Offset=*/0x1111abcdabcd,
+                     /*Length=*/0x2222abcdabcd,
+                     /*CIEPointer=*/0x33abcd,
+                     /*InitialLocation=*/0x4444abcdabcd,
+                     /*AddressRange=*/0x111111111111,
+                     /*Cie=*/&TestCIE,
+                     /*LSDAAddress=*/None,
+                     /*Arch=*/Triple::x86_64);
+  expectDumpResult(TestFDE, /*IsEH=*/true,
+                   "1111abcdabcd 00002222abcdabcd 0033abcd FDE "
+                   "cie=1111ab9a000c pc=4444abcdabcd...5555bcdebcde");
+}
+
+} // end anonymous namespace