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() {}
protected:
const FrameKind Kind;
+ const bool IsDWARF64;
+
/// Offset of this entry in the section.
const uint64_t Offset;
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),
/// 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),
}
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) {
}
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);
}
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 {
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 =
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
# 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
DWARFAcceleratorTableTest.cpp
DWARFDataExtractorTest.cpp
DWARFDebugArangeSetTest.cpp
+ DWARFDebugFrameTest.cpp
DWARFDebugInfoTest.cpp
DWARFDebugLineTest.cpp
DWARFDieTest.cpp
--- /dev/null
+//===- 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