[LLVMdev] [llvm] r174463 - Initial support for DWARF CFI parsing and dumping in LLVM
Reed Kotler
rkotler at mips.com
Tue Feb 5 21:04:04 PST 2013
llvm[2]: Compiling DWARFDebugArangeSet.cpp for Debug+Asserts build
llvm[2]: Compiling DWARFDebugAranges.cpp for Debug+Asserts build
llvm[2]: Compiling DWARFDebugFrame.cpp for Debug+Asserts build
/home/rkotler/llvm_trunk/lib/DebugInfo/DWARFDebugFrame.cpp:118:8: error:
private field 'LinkedCIE' is not used
[-Werror,-Wunused-private-field]
CIE *LinkedCIE;
^
1 error generated.
make[2]: *** [/home/rkotler/
On 02/05/2013 08:24 PM, Matt Beaumont-Gay wrote:
> On Tue, Feb 5, 2013 at 3:30 PM, Eli Bendersky <eliben-hpIqsD4AKlfQT0dZR+AlfA at public.gmane.org> wrote:
>> Author: eliben
>> Date: Tue Feb 5 17:30:58 2013
>> New Revision: 174463
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=174463&view=rev
>> Log:
>> Initial support for DWARF CFI parsing and dumping in LLVM
>>
>> Added:
>> llvm/trunk/lib/DebugInfo/DWARFDebugFrame.cpp
>> llvm/trunk/lib/DebugInfo/DWARFDebugFrame.h
>> Modified:
>> llvm/trunk/include/llvm/DebugInfo/DIContext.h
>> llvm/trunk/include/llvm/Support/Dwarf.h
>> llvm/trunk/lib/DebugInfo/DWARFContext.cpp
>> llvm/trunk/lib/DebugInfo/DWARFContext.h
>> llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=174463&r1=174462&r2=174463&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Tue Feb 5 17:30:58 2013
>> @@ -101,6 +101,7 @@ enum DIDumpType {
>> DIDT_Abbrev,
>> DIDT_AbbrevDwo,
>> DIDT_Aranges,
>> + DIDT_Frames,
>> DIDT_Info,
>> DIDT_InfoDwo,
>> DIDT_Line,
>>
>> Modified: llvm/trunk/include/llvm/Support/Dwarf.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Dwarf.h?rev=174463&r1=174462&r2=174463&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Support/Dwarf.h (original)
>> +++ llvm/trunk/include/llvm/Support/Dwarf.h Tue Feb 5 17:30:58 2013
>> @@ -16,6 +16,9 @@
>> #ifndef LLVM_SUPPORT_DWARF_H
>> #define LLVM_SUPPORT_DWARF_H
>>
>> +#include "llvm/Support/DataTypes.h"
>> +
>> +
>> namespace llvm {
>>
>> //===----------------------------------------------------------------------===//
>> @@ -53,10 +56,16 @@ enum llvm_dwarf_constants {
>>
>> DW_TAG_user_base = 0x1000, // Recommended base for user tags.
>>
>> - DW_CIE_VERSION = 1, // Common frame information version.
>> - DW_CIE_ID = 0xffffffff // Common frame information mark.
>> + DW_CIE_VERSION = 1 // Common frame information version.
>> };
>>
>> +
>> +// 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 {
>> DWARF_VERSION = 2,
>>
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=174463&r1=174462&r2=174463&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Tue Feb 5 17:30:58 2013
>> @@ -31,6 +31,11 @@ void DWARFContext::dump(raw_ostream &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;
>> if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
>> OS << "\n.debug_aranges contents:\n";
>> @@ -152,6 +157,26 @@ const DWARFDebugAranges *DWARFContext::g
>> 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 *
>> DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
>> if (!Line)
>> @@ -440,7 +465,8 @@ DIInliningInfo DWARFContext::getInlining
>> }
>>
>> DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
>> - IsLittleEndian(Obj->isLittleEndian()) {
>> + IsLittleEndian(Obj->isLittleEndian()),
>> + AddressSize(Obj->getBytesInAddress()) {
>> error_code ec;
>> for (object::section_iterator i = Obj->begin_sections(),
>> e = Obj->end_sections();
>> @@ -459,6 +485,8 @@ DWARFContextInMemory::DWARFContextInMemo
>> LineSection = data;
>> else if (name == "debug_aranges")
>> ARangeSection = data;
>> + else if (name == "debug_frame")
>> + DebugFrameSection = data;
>> else if (name == "debug_str")
>> StringSection = data;
>> else if (name == "debug_ranges") {
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARFContext.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.h?rev=174463&r1=174462&r2=174463&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFContext.h (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARFContext.h Tue Feb 5 17:30:58 2013
>> @@ -12,6 +12,7 @@
>>
>> #include "DWARFCompileUnit.h"
>> #include "DWARFDebugAranges.h"
>> +#include "DWARFDebugFrame.h"
>> #include "DWARFDebugLine.h"
>> #include "DWARFDebugRangeList.h"
>> #include "llvm/ADT/OwningPtr.h"
>> @@ -29,6 +30,7 @@ class DWARFContext : public DIContext {
>> OwningPtr<DWARFDebugAbbrev> Abbrev;
>> OwningPtr<DWARFDebugAranges> Aranges;
>> OwningPtr<DWARFDebugLine> Line;
>> + OwningPtr<DWARFDebugFrame> DebugFrame;
>>
>> SmallVector<DWARFCompileUnit, 1> DWOCUs;
>> OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
>> @@ -84,6 +86,9 @@ public:
>> /// Get a pointer to the parsed DebugAranges object.
>> 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.
>> const DWARFDebugLine::LineTable *
>> getLineTableForCompileUnit(DWARFCompileUnit *cu);
>> @@ -96,11 +101,13 @@ public:
>> DILineInfoSpecifier Specifier = DILineInfoSpecifier());
>>
>> virtual bool isLittleEndian() const = 0;
>> + virtual uint8_t getAddressSize() const = 0;
>> virtual const RelocAddrMap &infoRelocMap() const = 0;
>> virtual const RelocAddrMap &lineRelocMap() const = 0;
>> virtual StringRef getInfoSection() = 0;
>> virtual StringRef getAbbrevSection() = 0;
>> virtual StringRef getARangeSection() = 0;
>> + virtual StringRef getDebugFrameSection() = 0;
>> virtual StringRef getLineSection() = 0;
>> virtual StringRef getStringSection() = 0;
>> virtual StringRef getRangeSection() = 0;
>> @@ -132,11 +139,13 @@ private:
>> class DWARFContextInMemory : public DWARFContext {
>> virtual void anchor();
>> bool IsLittleEndian;
>> + uint8_t AddressSize;
>> RelocAddrMap InfoRelocMap;
>> RelocAddrMap LineRelocMap;
>> StringRef InfoSection;
>> StringRef AbbrevSection;
>> StringRef ARangeSection;
>> + StringRef DebugFrameSection;
>> StringRef LineSection;
>> StringRef StringSection;
>> StringRef RangeSection;
>> @@ -153,11 +162,13 @@ class DWARFContextInMemory : public DWAR
>> public:
>> DWARFContextInMemory(object::ObjectFile *);
>> virtual bool isLittleEndian() const { return IsLittleEndian; }
>> + virtual uint8_t getAddressSize() const { return AddressSize; }
>> virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
>> virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
>> virtual StringRef getInfoSection() { return InfoSection; }
>> virtual StringRef getAbbrevSection() { return AbbrevSection; }
>> virtual StringRef getARangeSection() { return ARangeSection; }
>> + virtual StringRef getDebugFrameSection() { return DebugFrameSection; }
>> virtual StringRef getLineSection() { return LineSection; }
>> virtual StringRef getStringSection() { return StringSection; }
>> virtual StringRef getRangeSection() { return RangeSection; }
>>
>> Added: llvm/trunk/lib/DebugInfo/DWARFDebugFrame.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugFrame.cpp?rev=174463&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFDebugFrame.cpp (added)
>> +++ llvm/trunk/lib/DebugInfo/DWARFDebugFrame.cpp Tue Feb 5 17:30:58 2013
>> @@ -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 {
>
> What's a CIE? That is to say, it would probably be better if the name
> were spelled out. (Likewise FDE below.)
>
>> +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);
>> + }
>> +}
>> +
>>
>> Added: llvm/trunk/lib/DebugInfo/DWARFDebugFrame.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugFrame.h?rev=174463&view=auto
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/DWARFDebugFrame.h (added)
>> +++ llvm/trunk/lib/DebugInfo/DWARFDebugFrame.h Tue Feb 5 17:30:58 2013
>> @@ -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
>> +
>>
>> Modified: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp?rev=174463&r1=174462&r2=174463&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp (original)
>> +++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp Tue Feb 5 17:30:58 2013
>> @@ -63,6 +63,7 @@ DumpType("debug-dump", cl::init(DIDT_All
>> clEnumValN(DIDT_Info, "info", ".debug_info"),
>> clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
>> clEnumValN(DIDT_Line, "line", ".debug_line"),
>> + clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
>> clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
>> clEnumValN(DIDT_Str, "str", ".debug_str"),
>> clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits-Tmj1lob9twqVc3sceRu5cw at public.gmane.org
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-dev
mailing list