Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -132,9 +132,9 @@ 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 @@ protected: const FrameKind Kind; + const bool IsDWARF64; + /// Offset of this entry in the section. const uint64_t Offset; @@ -166,16 +168,16 @@ 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, - SmallString<8> Augmentation, uint8_t AddressSize, + CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEId, + 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 Personality, Optional 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)), + CIEId(CIEId), Version(Version), Augmentation(std::move(Augmentation)), AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize), CodeAlignmentFactor(CodeAlignmentFactor), DataAlignmentFactor(DataAlignmentFactor), @@ -204,6 +206,7 @@ private: /// The following fields are defined in section 6.4.1 of the DWARF standard v4 + const uint64_t CIEId; const uint8_t Version; const SmallString<8> Augmentation; const uint8_t AddressSize; @@ -226,10 +229,10 @@ // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with // an offset to the CIE (provided by parsing the FDE header). The CIE itself // is obtained lazily once it's actually required. - FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, + FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie, Optional 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: llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -286,9 +286,10 @@ } 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, CIEId) + << " CIE\n"; OS << format(" Version: %d\n", Version); OS << " Augmentation: \"" << Augmentation << "\"\n"; if (Version >= 4) { @@ -313,11 +314,14 @@ } void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { - OS << format("%08x %08x %08x FDE ", (uint32_t)Offset, (uint32_t)Length, - (int32_t)LinkedCIEOffset); - OS << format("cie=%08x pc=%08x...%08x\n", (int32_t)LinkedCIEOffset, - (uint32_t)InitialLocation, - (uint32_t)InitialLocation + (uint32_t)AddressRange); + OS << format("%08" PRIx64, Offset) + << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) + << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, LinkedCIEOffset) + << format(" FDE cie=%0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, + LinkedCIEOffset) + << format(" pc=%08" PRIx64 "...%08" PRIx64, InitialLocation, + InitialLocation + AddressRange) + << "\n"; if (LSDAAddress) OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); CFIs.dump(OS, MRI, IsEH); @@ -462,10 +466,11 @@ } auto Cie = std::make_unique( - StartOffset, Length, Version, AugmentationString, AddressSize, - SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor, - ReturnAddressRegister, AugmentationData, FDEPointerEncoding, - LSDAPointerEncoding, Personality, PersonalityEncoding, Arch); + IsDWARF64, StartOffset, Length, Id, Version, AugmentationString, + AddressSize, SegmentDescriptorSize, CodeAlignmentFactor, + DataAlignmentFactor, ReturnAddressRegister, AugmentationData, + FDEPointerEncoding, LSDAPointerEncoding, Personality, + PersonalityEncoding, Arch); CIEs[StartOffset] = Cie.get(); Entries.emplace_back(std::move(Cie)); } else { @@ -515,9 +520,9 @@ 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: llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test +++ llvm/test/tools/llvm-dwarfdump/X86/debug_frame_offset.test @@ -8,7 +8,7 @@ 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=0000001c pc=fffffd00...fffffd24 +EH-NEXT: 00000018 00000024 0000001c FDE cie=0000001c pc=fffffffffffffd00...fffffffffffffd24 EH-NEXT: DW_CFA_advance_loc: 1 EH-NOT: pc EH-NOT: CIE Index: llvm/test/tools/llvm-objdump/eh_frame-arm64.test =================================================================== --- llvm/test/tools/llvm-objdump/eh_frame-arm64.test +++ llvm/test/tools/llvm-objdump/eh_frame-arm64.test @@ -12,7 +12,7 @@ # CHECK: DW_CFA_def_cfa: reg31 +0 -# CHECK: 00000014 00000020 00000018 FDE cie=00000018 pc=ffffffe4...00000004 +# CHECK: 00000014 00000020 00000018 FDE cie=00000018 pc=ffffffffffffffe4...00000004 # CHECK: DW_CFA_advance_loc: 8 # CHECK: DW_CFA_def_cfa_offset: +16 # CHECK: DW_CFA_offset: reg30 -8 Index: llvm/unittests/DebugInfo/DWARF/CMakeLists.txt =================================================================== --- llvm/unittests/DebugInfo/DWARF/CMakeLists.txt +++ llvm/unittests/DebugInfo/DWARF/CMakeLists.txt @@ -13,6 +13,7 @@ DwarfUtils.cpp DWARFAcceleratorTableTest.cpp DWARFDebugArangeSetTest.cpp + DWARFDebugFrameTest.cpp DWARFDebugInfoTest.cpp DWARFDebugLineTest.cpp DWARFDieTest.cpp Index: llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp =================================================================== --- /dev/null +++ llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp @@ -0,0 +1,146 @@ +//===- 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 { + +TEST(DWARFDebugFrame, CIEDumpDWARF64) { + dwarf::CIE TestCIE( + /* IsDWARF64 = */ true, + /* Offset = */ 0x1111abcdabcdULL, + /* Length = */ 0x2222abcdabcdULL, + /* CIEId = */ 0xffffffffffffffffULL, + /* 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); + std::string Output; + raw_string_ostream OS(Output); + TestCIE.dump(OS, /* MRI = */ nullptr, /* IsEH = */ false); + OS.flush(); + SmallVector OutputLines; + StringRef(Output).split(OutputLines, '\n'); + ASSERT_EQ(OutputLines.size(), 9U); + EXPECT_EQ(OutputLines[0], + "1111abcdabcd 00002222abcdabcd ffffffffffffffff CIE"); +} + +TEST(DWARFDebugFrame, CIEDumpEH) { + dwarf::CIE TestCIE( + /* IsDWARF64 = */ false, + /* Offset = */ 0x1000, + /* Length = */ 0x20, + /* CIEId = */ 0, + /* 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); + std::string Output; + raw_string_ostream OS(Output); + TestCIE.dump(OS, /* MRI = */ nullptr, /* IsEH = */ true); + OS.flush(); + StringRef FirstLine = StringRef(Output).split('\n').first; + EXPECT_EQ(FirstLine, "00001000 00000020 00000000 CIE"); +} + +TEST(DWARFDebugFrame, CIEDumpEHDWARF64) { + dwarf::CIE TestCIE( + /* IsDWARF64 = */ true, + /* Offset = */ 0x1000ULL, + /* Length = */ 0x20ULL, + /* CIEId = */ 0, + /* 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); + std::string Output; + raw_string_ostream OS(Output); + TestCIE.dump(OS, /* MRI = */ nullptr, /* IsEH = */ true); + OS.flush(); + SmallVector OutputLines; + StringRef(Output).split(OutputLines, '\n'); + ASSERT_EQ(OutputLines.size(), 9U); + EXPECT_EQ(OutputLines[0], + "00001000 0000000000000020 00000000 CIE"); +} + +TEST(DWARFDebugFrame, FDEDumpDWARF64) { + dwarf::FDE TestFDE(/* IsDWARF64 = */ true, + /* Offset = */ 0x1111abcdabcdULL, + /* Length = */ 0x2222abcdabcdULL, + /* LinkedCIEOffset = */ 0x3333abcdabcdULL, + /* InitialLocation = */ 0x4444abcdabcdULL, + /* AddressRange = */ 0x111111111111ULL, + /* Cie = */ nullptr, + /* LSDAAddress = */ None, + /* Arch = */ Triple::x86_64); + std::string Output; + raw_string_ostream OS(Output); + TestFDE.dump(OS, /* MRI = */ nullptr, /* IsEH = */ false); + OS.flush(); + EXPECT_STREQ( + Output.c_str(), + "1111abcdabcd 00002222abcdabcd 00003333abcdabcd FDE " + "cie=00003333abcdabcd pc=4444abcdabcd...5555bcdebcde\n\n"); +} + +TEST(DWARFDebugFrame, FDEDumpEHDWARF64) { + dwarf::FDE TestFDE(/* IsDWARF64 = */ true, + /* Offset = */ 0x1111abcdabcdULL, + /* Length = */ 0x2222abcdabcdULL, + /* LinkedCIEOffset = */ 0x33abcdULL, + /* InitialLocation = */ 0x4444abcdabcdULL, + /* AddressRange = */ 0x111111111111ULL, + /* Cie = */ nullptr, + /* LSDAAddress = */ None, + /* Arch = */ Triple::x86_64); + std::string Output; + raw_string_ostream OS(Output); + TestFDE.dump(OS, /* MRI = */ nullptr, /* IsEH = */ true); + OS.flush(); + EXPECT_STREQ( + Output.c_str(), + "1111abcdabcd 00002222abcdabcd 0033abcd FDE " + "cie=0033abcd pc=4444abcdabcd...5555bcdebcde\n\n"); +} + +} // end anonymous namespace