[DebugInfo] Do not truncate 64-bit values when dumping CIEs and FDEs.

This fixes printing long values that might reside in CIE and FDE,
including offsets, lengths, and addresses.

Differential Revision: https://reviews.llvm.org/D73887
This commit is contained in:
Igor Kudrin 2020-01-28 14:11:54 +07:00
parent 1a837569db
commit cada5b881b
6 changed files with 153 additions and 24 deletions

View 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),

View 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 =

View 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

View 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

View File

@ -14,6 +14,7 @@ add_llvm_unittest(DebugInfoDWARFTests
DWARFAcceleratorTableTest.cpp
DWARFDataExtractorTest.cpp
DWARFDebugArangeSetTest.cpp
DWARFDebugFrameTest.cpp
DWARFDebugInfoTest.cpp
DWARFDebugLineTest.cpp
DWARFDieTest.cpp

View File

@ -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