mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-05 14:34:55 +00:00
Initial support for DWARF CFI parsing and dumping in LLVM
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174463 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5e215f9bfd
commit
60bdc5b16e
@ -101,6 +101,7 @@ enum DIDumpType {
|
|||||||
DIDT_Abbrev,
|
DIDT_Abbrev,
|
||||||
DIDT_AbbrevDwo,
|
DIDT_AbbrevDwo,
|
||||||
DIDT_Aranges,
|
DIDT_Aranges,
|
||||||
|
DIDT_Frames,
|
||||||
DIDT_Info,
|
DIDT_Info,
|
||||||
DIDT_InfoDwo,
|
DIDT_InfoDwo,
|
||||||
DIDT_Line,
|
DIDT_Line,
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
#ifndef LLVM_SUPPORT_DWARF_H
|
#ifndef LLVM_SUPPORT_DWARF_H
|
||||||
#define LLVM_SUPPORT_DWARF_H
|
#define LLVM_SUPPORT_DWARF_H
|
||||||
|
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -53,10 +56,16 @@ enum llvm_dwarf_constants {
|
|||||||
|
|
||||||
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
|
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
|
||||||
|
|
||||||
DW_CIE_VERSION = 1, // Common frame information version.
|
DW_CIE_VERSION = 1 // Common frame information version.
|
||||||
DW_CIE_ID = 0xffffffff // Common frame information mark.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
|
||||||
|
// Not inside an enum because a 64-bit value is needed.
|
||||||
|
const uint32_t DW_CIE_ID = UINT32_MAX;
|
||||||
|
const uint64_t DW64_CIE_ID = UINT64_MAX;
|
||||||
|
|
||||||
|
|
||||||
enum dwarf_constants {
|
enum dwarf_constants {
|
||||||
DWARF_VERSION = 2,
|
DWARF_VERSION = 2,
|
||||||
|
|
||||||
|
@ -31,6 +31,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
|||||||
getCompileUnitAtIndex(i)->dump(OS);
|
getCompileUnitAtIndex(i)->dump(OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
|
||||||
|
OS << "\n.debug_frame contents:\n";
|
||||||
|
getDebugFrame()->dump(OS);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
|
if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
|
||||||
OS << "\n.debug_aranges contents:\n";
|
OS << "\n.debug_aranges contents:\n";
|
||||||
@ -152,6 +157,26 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() {
|
|||||||
return Aranges.get();
|
return Aranges.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DWARFDebugFrame *DWARFContext::getDebugFrame() {
|
||||||
|
if (DebugFrame)
|
||||||
|
return DebugFrame.get();
|
||||||
|
|
||||||
|
// 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",
|
||||||
|
// which isn't specified in DWARF in general. It's only specified for CUs, but
|
||||||
|
// .eh_frame can appear without a .debug_info section. Follow the example of
|
||||||
|
// other tools (libdwarf) and extract this from the container (ObjectFile
|
||||||
|
// 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
|
||||||
|
DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
|
||||||
|
getAddressSize());
|
||||||
|
DebugFrame.reset(new DWARFDebugFrame());
|
||||||
|
DebugFrame->parse(debugFrameData);
|
||||||
|
return DebugFrame.get();
|
||||||
|
}
|
||||||
|
|
||||||
const DWARFLineTable *
|
const DWARFLineTable *
|
||||||
DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
|
DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
|
||||||
if (!Line)
|
if (!Line)
|
||||||
@ -440,7 +465,8 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
||||||
IsLittleEndian(Obj->isLittleEndian()) {
|
IsLittleEndian(Obj->isLittleEndian()),
|
||||||
|
AddressSize(Obj->getBytesInAddress()) {
|
||||||
error_code ec;
|
error_code ec;
|
||||||
for (object::section_iterator i = Obj->begin_sections(),
|
for (object::section_iterator i = Obj->begin_sections(),
|
||||||
e = Obj->end_sections();
|
e = Obj->end_sections();
|
||||||
@ -459,6 +485,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
|||||||
LineSection = data;
|
LineSection = data;
|
||||||
else if (name == "debug_aranges")
|
else if (name == "debug_aranges")
|
||||||
ARangeSection = data;
|
ARangeSection = data;
|
||||||
|
else if (name == "debug_frame")
|
||||||
|
DebugFrameSection = data;
|
||||||
else if (name == "debug_str")
|
else if (name == "debug_str")
|
||||||
StringSection = data;
|
StringSection = data;
|
||||||
else if (name == "debug_ranges") {
|
else if (name == "debug_ranges") {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "DWARFCompileUnit.h"
|
#include "DWARFCompileUnit.h"
|
||||||
#include "DWARFDebugAranges.h"
|
#include "DWARFDebugAranges.h"
|
||||||
|
#include "DWARFDebugFrame.h"
|
||||||
#include "DWARFDebugLine.h"
|
#include "DWARFDebugLine.h"
|
||||||
#include "DWARFDebugRangeList.h"
|
#include "DWARFDebugRangeList.h"
|
||||||
#include "llvm/ADT/OwningPtr.h"
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
@ -29,6 +30,7 @@ class DWARFContext : public DIContext {
|
|||||||
OwningPtr<DWARFDebugAbbrev> Abbrev;
|
OwningPtr<DWARFDebugAbbrev> Abbrev;
|
||||||
OwningPtr<DWARFDebugAranges> Aranges;
|
OwningPtr<DWARFDebugAranges> Aranges;
|
||||||
OwningPtr<DWARFDebugLine> Line;
|
OwningPtr<DWARFDebugLine> Line;
|
||||||
|
OwningPtr<DWARFDebugFrame> DebugFrame;
|
||||||
|
|
||||||
SmallVector<DWARFCompileUnit, 1> DWOCUs;
|
SmallVector<DWARFCompileUnit, 1> DWOCUs;
|
||||||
OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
|
OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
|
||||||
@ -84,6 +86,9 @@ public:
|
|||||||
/// Get a pointer to the parsed DebugAranges object.
|
/// Get a pointer to the parsed DebugAranges object.
|
||||||
const DWARFDebugAranges *getDebugAranges();
|
const DWARFDebugAranges *getDebugAranges();
|
||||||
|
|
||||||
|
/// Get a pointer to the parsed frame information object.
|
||||||
|
const DWARFDebugFrame *getDebugFrame();
|
||||||
|
|
||||||
/// Get a pointer to a parsed line table corresponding to a compile unit.
|
/// Get a pointer to a parsed line table corresponding to a compile unit.
|
||||||
const DWARFDebugLine::LineTable *
|
const DWARFDebugLine::LineTable *
|
||||||
getLineTableForCompileUnit(DWARFCompileUnit *cu);
|
getLineTableForCompileUnit(DWARFCompileUnit *cu);
|
||||||
@ -96,11 +101,13 @@ public:
|
|||||||
DILineInfoSpecifier Specifier = DILineInfoSpecifier());
|
DILineInfoSpecifier Specifier = DILineInfoSpecifier());
|
||||||
|
|
||||||
virtual bool isLittleEndian() const = 0;
|
virtual bool isLittleEndian() const = 0;
|
||||||
|
virtual uint8_t getAddressSize() const = 0;
|
||||||
virtual const RelocAddrMap &infoRelocMap() const = 0;
|
virtual const RelocAddrMap &infoRelocMap() const = 0;
|
||||||
virtual const RelocAddrMap &lineRelocMap() const = 0;
|
virtual const RelocAddrMap &lineRelocMap() const = 0;
|
||||||
virtual StringRef getInfoSection() = 0;
|
virtual StringRef getInfoSection() = 0;
|
||||||
virtual StringRef getAbbrevSection() = 0;
|
virtual StringRef getAbbrevSection() = 0;
|
||||||
virtual StringRef getARangeSection() = 0;
|
virtual StringRef getARangeSection() = 0;
|
||||||
|
virtual StringRef getDebugFrameSection() = 0;
|
||||||
virtual StringRef getLineSection() = 0;
|
virtual StringRef getLineSection() = 0;
|
||||||
virtual StringRef getStringSection() = 0;
|
virtual StringRef getStringSection() = 0;
|
||||||
virtual StringRef getRangeSection() = 0;
|
virtual StringRef getRangeSection() = 0;
|
||||||
@ -132,11 +139,13 @@ private:
|
|||||||
class DWARFContextInMemory : public DWARFContext {
|
class DWARFContextInMemory : public DWARFContext {
|
||||||
virtual void anchor();
|
virtual void anchor();
|
||||||
bool IsLittleEndian;
|
bool IsLittleEndian;
|
||||||
|
uint8_t AddressSize;
|
||||||
RelocAddrMap InfoRelocMap;
|
RelocAddrMap InfoRelocMap;
|
||||||
RelocAddrMap LineRelocMap;
|
RelocAddrMap LineRelocMap;
|
||||||
StringRef InfoSection;
|
StringRef InfoSection;
|
||||||
StringRef AbbrevSection;
|
StringRef AbbrevSection;
|
||||||
StringRef ARangeSection;
|
StringRef ARangeSection;
|
||||||
|
StringRef DebugFrameSection;
|
||||||
StringRef LineSection;
|
StringRef LineSection;
|
||||||
StringRef StringSection;
|
StringRef StringSection;
|
||||||
StringRef RangeSection;
|
StringRef RangeSection;
|
||||||
@ -153,11 +162,13 @@ class DWARFContextInMemory : public DWARFContext {
|
|||||||
public:
|
public:
|
||||||
DWARFContextInMemory(object::ObjectFile *);
|
DWARFContextInMemory(object::ObjectFile *);
|
||||||
virtual bool isLittleEndian() const { return IsLittleEndian; }
|
virtual bool isLittleEndian() const { return IsLittleEndian; }
|
||||||
|
virtual uint8_t getAddressSize() const { return AddressSize; }
|
||||||
virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
|
virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
|
||||||
virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
|
virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
|
||||||
virtual StringRef getInfoSection() { return InfoSection; }
|
virtual StringRef getInfoSection() { return InfoSection; }
|
||||||
virtual StringRef getAbbrevSection() { return AbbrevSection; }
|
virtual StringRef getAbbrevSection() { return AbbrevSection; }
|
||||||
virtual StringRef getARangeSection() { return ARangeSection; }
|
virtual StringRef getARangeSection() { return ARangeSection; }
|
||||||
|
virtual StringRef getDebugFrameSection() { return DebugFrameSection; }
|
||||||
virtual StringRef getLineSection() { return LineSection; }
|
virtual StringRef getLineSection() { return LineSection; }
|
||||||
virtual StringRef getStringSection() { return StringSection; }
|
virtual StringRef getStringSection() { return StringSection; }
|
||||||
virtual StringRef getRangeSection() { return RangeSection; }
|
virtual StringRef getRangeSection() { return RangeSection; }
|
||||||
|
195
lib/DebugInfo/DWARFDebugFrame.cpp
Normal file
195
lib/DebugInfo/DWARFDebugFrame.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "DWARFDebugFrame.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include "llvm/Support/Dwarf.h"
|
||||||
|
#include "llvm/Support/Format.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace dwarf;
|
||||||
|
|
||||||
|
|
||||||
|
class llvm::FrameEntry {
|
||||||
|
public:
|
||||||
|
enum FrameKind {FK_CIE, FK_FDE};
|
||||||
|
FrameEntry(FrameKind K, DataExtractor D, uint64_t Offset, uint64_t Length)
|
||||||
|
: Kind(K), Data(D), Offset(Offset), Length(Length)
|
||||||
|
{}
|
||||||
|
|
||||||
|
FrameKind getKind() const { return Kind; }
|
||||||
|
|
||||||
|
virtual void dumpHeader(raw_ostream &OS) const = 0;
|
||||||
|
protected:
|
||||||
|
const FrameKind Kind;
|
||||||
|
DataExtractor Data;
|
||||||
|
uint64_t Offset;
|
||||||
|
uint64_t Length;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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(DataExtractor D, uint64_t Offset, uint64_t Length, uint8_t Version,
|
||||||
|
SmallString<8> Augmentation, uint64_t CodeAlignmentFactor,
|
||||||
|
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
|
||||||
|
: FrameEntry(FK_CIE, D, Offset, Length), Version(Version),
|
||||||
|
Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
|
||||||
|
DataAlignmentFactor(DataAlignmentFactor),
|
||||||
|
ReturnAddressRegister(ReturnAddressRegister)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void dumpHeader(raw_ostream &OS) const {
|
||||||
|
OS << format("%08x %08x %08x CIE", Offset, Length, DW_CIE_ID) << "\n";
|
||||||
|
OS << format(" Version: %d\n", Version);
|
||||||
|
OS << " Augmentation: \"" << Augmentation << "\"\n";
|
||||||
|
OS << format(" Code alignment factor: %u\n", CodeAlignmentFactor);
|
||||||
|
OS << format(" Data alignment factor: %d\n", DataAlignmentFactor);
|
||||||
|
OS << format(" Return address column: %d\n", ReturnAddressRegister);
|
||||||
|
OS << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const FrameEntry *FE) {
|
||||||
|
return FE->getKind() == FK_CIE;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint8_t Version;
|
||||||
|
SmallString<8> Augmentation;
|
||||||
|
uint64_t CodeAlignmentFactor;
|
||||||
|
int64_t DataAlignmentFactor;
|
||||||
|
uint64_t ReturnAddressRegister;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FDE : public FrameEntry {
|
||||||
|
public:
|
||||||
|
// 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(DataExtractor D, uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
|
||||||
|
uint64_t InitialLocation, uint64_t AddressRange)
|
||||||
|
: FrameEntry(FK_FDE, D, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
|
||||||
|
InitialLocation(InitialLocation), AddressRange(AddressRange),
|
||||||
|
LinkedCIE(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void dumpHeader(raw_ostream &OS) const {
|
||||||
|
OS << format("%08x %08x %08x FDE ", Offset, Length, LinkedCIEOffset);
|
||||||
|
OS << format("cie=%08x pc=%08x...%08x\n",
|
||||||
|
LinkedCIEOffset, InitialLocation,
|
||||||
|
InitialLocation + AddressRange);
|
||||||
|
OS << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool classof(const FrameEntry *FE) {
|
||||||
|
return FE->getKind() == FK_FDE;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint64_t LinkedCIEOffset;
|
||||||
|
uint64_t InitialLocation;
|
||||||
|
uint64_t AddressRange;
|
||||||
|
CIE *LinkedCIE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DWARFDebugFrame::DWARFDebugFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWARFDebugFrame::~DWARFDebugFrame()
|
||||||
|
{
|
||||||
|
for (EntryVector::iterator I = Entries.begin(), E = Entries.end();
|
||||||
|
I != E; ++I) {
|
||||||
|
delete *I;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
|
||||||
|
uint32_t Offset, int Length) {
|
||||||
|
errs() << "DUMP: ";
|
||||||
|
for (int i = 0; i < Length; ++i) {
|
||||||
|
uint8_t c = Data.getU8(&Offset);
|
||||||
|
errs().write_hex(c); errs() << " ";
|
||||||
|
}
|
||||||
|
errs() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DWARFDebugFrame::parse(DataExtractor Data) {
|
||||||
|
uint32_t Offset = 0;
|
||||||
|
|
||||||
|
while (Data.isValidOffset(Offset)) {
|
||||||
|
uint32_t StartOffset = Offset;
|
||||||
|
|
||||||
|
bool IsDWARF64 = false;
|
||||||
|
uint64_t Length = Data.getU32(&Offset);
|
||||||
|
uint64_t Id;
|
||||||
|
|
||||||
|
if (Length == UINT32_MAX) {
|
||||||
|
// DWARF-64 is distinguished by the first 32 bits of the initial length
|
||||||
|
// field being 0xffffffff. Then, the next 64 bits are the actual entry
|
||||||
|
// length.
|
||||||
|
IsDWARF64 = true;
|
||||||
|
Length = Data.getU64(&Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, Offset points to the next field after Length.
|
||||||
|
// Length is the structure size excluding itself. Compute an offset one
|
||||||
|
// past the end of the structure (needed to know how many instructions to
|
||||||
|
// read).
|
||||||
|
// TODO: For honest DWARF64 support, DataExtractor will have to treat
|
||||||
|
// offset_ptr as uint64_t*
|
||||||
|
uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
|
||||||
|
|
||||||
|
// The Id field's size depends on the DWARF format
|
||||||
|
Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
|
||||||
|
bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
|
||||||
|
|
||||||
|
if (IsCIE) {
|
||||||
|
// Note: this is specifically DWARFv3 CIE header structure. It was
|
||||||
|
// changed in DWARFv4.
|
||||||
|
uint8_t Version = Data.getU8(&Offset);
|
||||||
|
const char *Augmentation = Data.getCStr(&Offset);
|
||||||
|
uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
|
||||||
|
int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
|
||||||
|
uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
|
||||||
|
|
||||||
|
CIE *NewCIE = new CIE(Data, StartOffset, Length, Version,
|
||||||
|
StringRef(Augmentation), CodeAlignmentFactor,
|
||||||
|
DataAlignmentFactor, ReturnAddressRegister);
|
||||||
|
Entries.push_back(NewCIE);
|
||||||
|
} else {
|
||||||
|
// FDE
|
||||||
|
uint64_t CIEPointer = Id;
|
||||||
|
uint64_t InitialLocation = Data.getAddress(&Offset);
|
||||||
|
uint64_t AddressRange = Data.getAddress(&Offset);
|
||||||
|
|
||||||
|
FDE *NewFDE = new FDE(Data, StartOffset, Length, CIEPointer,
|
||||||
|
InitialLocation, AddressRange);
|
||||||
|
Entries.push_back(NewFDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = EndStructureOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DWARFDebugFrame::dump(raw_ostream &OS) const {
|
||||||
|
OS << "\n";
|
||||||
|
for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end();
|
||||||
|
I != E; ++I) {
|
||||||
|
(*I)->dumpHeader(OS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
lib/DebugInfo/DWARFDebugFrame.h
Normal file
46
lib/DebugInfo/DWARFDebugFrame.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_DEBUGINFO_DWARFDEBUGFRAME_H
|
||||||
|
#define LLVM_DEBUGINFO_DWARFDEBUGFRAME_H
|
||||||
|
|
||||||
|
#include "llvm/Support/DataExtractor.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class FrameEntry;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief A parsed .debug_frame section
|
||||||
|
///
|
||||||
|
class DWARFDebugFrame {
|
||||||
|
public:
|
||||||
|
DWARFDebugFrame();
|
||||||
|
~DWARFDebugFrame();
|
||||||
|
|
||||||
|
/// \brief Dump the section data into the given stream.
|
||||||
|
void dump(raw_ostream &OS) const;
|
||||||
|
|
||||||
|
/// \brief Parse the section from raw data.
|
||||||
|
/// data is assumed to be pointing to the beginning of the section.
|
||||||
|
void parse(DataExtractor Data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::vector<FrameEntry *> EntryVector;
|
||||||
|
EntryVector Entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -63,6 +63,7 @@ DumpType("debug-dump", cl::init(DIDT_All),
|
|||||||
clEnumValN(DIDT_Info, "info", ".debug_info"),
|
clEnumValN(DIDT_Info, "info", ".debug_info"),
|
||||||
clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
|
clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
|
||||||
clEnumValN(DIDT_Line, "line", ".debug_line"),
|
clEnumValN(DIDT_Line, "line", ".debug_line"),
|
||||||
|
clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
|
||||||
clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
|
clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
|
||||||
clEnumValN(DIDT_Str, "str", ".debug_str"),
|
clEnumValN(DIDT_Str, "str", ".debug_str"),
|
||||||
clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
|
clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user