[llvm] r326953 - Revert r326932: [DebugInfo] Support DWARF expressions in eh_frame
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 7 14:29:49 PST 2018
Author: ruiu
Date: Wed Mar 7 14:29:48 2018
New Revision: 326953
URL: http://llvm.org/viewvc/llvm-project?rev=326953&view=rev
Log:
Revert r326932: [DebugInfo] Support DWARF expressions in eh_frame
This reverts commit rr326932 because it broke lld/test/ELF/eh-frame-hdr-augmentation.s.
Removed:
llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml
llvm/trunk/test/tools/llvm-readobj/unwind.test
llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h
Modified:
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h
llvm/trunk/include/llvm/Support/ScopedPrinter.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
llvm/trunk/tools/llvm-readobj/CMakeLists.txt
llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h Wed Mar 7 14:29:48 2018
@@ -44,13 +44,6 @@ public:
uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const {
return getRelocatedValue(getAddressSize(), Off, SecIx);
}
-
- /// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding.
- /// There is a DWARF encoding that uses a PC-relative adjustment.
- /// For these values, \p AbsPosOffset is used to fix them, which should
- /// reflect the absolute address of this pointer.
- Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
- uint64_t AbsPosOffset = 0) const;
};
} // end namespace llvm
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h Wed Mar 7 14:29:48 2018
@@ -10,290 +10,40 @@
#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/DataExtractor.h"
#include <memory>
#include <vector>
namespace llvm {
+class FrameEntry;
class raw_ostream;
-namespace dwarf {
-
-/// Represent a sequence of Call Frame Information instructions that, when read
-/// in order, construct a table mapping PC to frame state. This can also be
-/// referred to as "CFI rules" in DWARF literature to avoid confusion with
-/// computer programs in the broader sense, and in this context each instruction
-/// would be a rule to establish the mapping. Refer to pg. 172 in the DWARF5
-/// manual, "6.4.1 Structure of Call Frame Information".
-class CFIProgram {
-public:
- typedef SmallVector<uint64_t, 2> Operands;
-
- /// An instruction consists of a DWARF CFI opcode and an optional sequence of
- /// operands. If it refers to an expression, then this expression has its own
- /// sequence of operations and operands handled separately by DWARFExpression.
- struct Instruction {
- Instruction(uint8_t Opcode) : Opcode(Opcode) {}
-
- uint8_t Opcode;
- Operands Ops;
- // Associated DWARF expression in case this instruction refers to one
- Optional<DWARFExpression> Expression;
- };
-
- using InstrList = std::vector<Instruction>;
- using iterator = InstrList::iterator;
- using const_iterator = InstrList::const_iterator;
-
- iterator begin() { return Instructions.begin(); }
- const_iterator begin() const { return Instructions.begin(); }
- iterator end() { return Instructions.end(); }
- const_iterator end() const { return Instructions.end(); }
-
- unsigned size() const { return (unsigned)Instructions.size(); }
- bool empty() const { return Instructions.empty(); }
-
- CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)
- : CodeAlignmentFactor(CodeAlignmentFactor),
- DataAlignmentFactor(DataAlignmentFactor) {}
-
- /// Parse and store a sequence of CFI instructions from Data,
- /// starting at *Offset and ending at EndOffset. *Offset is updated
- /// to EndOffset upon successful parsing, or indicates the offset
- /// where a problem occurred in case an error is returned.
- Error parse(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
-
- void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
- unsigned IndentLevel = 1) const;
-
-private:
- std::vector<Instruction> Instructions;
- const uint64_t CodeAlignmentFactor;
- const int64_t DataAlignmentFactor;
-
- /// Convenience method to add a new instruction with the given opcode.
- void addInstruction(uint8_t Opcode) {
- Instructions.push_back(Instruction(Opcode));
- }
-
- /// Add a new single-operand instruction.
- void addInstruction(uint8_t Opcode, uint64_t Operand1) {
- Instructions.push_back(Instruction(Opcode));
- Instructions.back().Ops.push_back(Operand1);
- }
-
- /// Add a new instruction that has two operands.
- void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
- Instructions.push_back(Instruction(Opcode));
- Instructions.back().Ops.push_back(Operand1);
- Instructions.back().Ops.push_back(Operand2);
- }
-
- /// Types of operands to CFI instructions
- /// In DWARF, this type is implicitly tied to a CFI instruction opcode and
- /// thus this type doesn't need to be explictly written to the file (this is
- /// not a DWARF encoding). The relationship of instrs to operand types can
- /// be obtained from getOperandTypes() and is only used to simplify
- /// instruction printing.
- enum OperandType {
- OT_Unset,
- OT_None,
- OT_Address,
- OT_Offset,
- OT_FactoredCodeOffset,
- OT_SignedFactDataOffset,
- OT_UnsignedFactDataOffset,
- OT_Register,
- OT_Expression
- };
-
- /// Retrieve the array describing the types of operands according to the enum
- /// above. This is indexed by opcode.
- static ArrayRef<OperandType[2]> getOperandTypes();
-
- /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
- void printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
- const Instruction &Instr, unsigned OperandIdx,
- uint64_t Operand) const;
-};
-
-/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an
-/// FDE.
-class FrameEntry {
-public:
- enum FrameKind { FK_CIE, FK_FDE };
-
- FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
- int64_t DataAlign)
- : Kind(K), Offset(Offset), Length(Length), CFIs(CodeAlign, DataAlign) {}
-
- virtual ~FrameEntry() {}
-
- FrameKind getKind() const { return Kind; }
- uint64_t getOffset() const { return Offset; }
- uint64_t getLength() const { return Length; }
- const CFIProgram &cfis() const { return CFIs; }
- CFIProgram &cfis() { return CFIs; }
-
- /// Dump the instructions in this CFI fragment
- virtual void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- bool IsEH) const = 0;
-
-protected:
- const FrameKind Kind;
-
- /// Offset of this entry in the section.
- const uint64_t Offset;
-
- /// Entry length as specified in DWARF.
- const uint64_t Length;
-
- CFIProgram CFIs;
-};
-
-/// DWARF Common Information Entry (CIE)
-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,
- 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)
- : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
- DataAlignmentFactor),
- Version(Version), Augmentation(std::move(Augmentation)),
- AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
- CodeAlignmentFactor(CodeAlignmentFactor),
- DataAlignmentFactor(DataAlignmentFactor),
- ReturnAddressRegister(ReturnAddressRegister),
- AugmentationData(std::move(AugmentationData)),
- FDEPointerEncoding(FDEPointerEncoding),
- LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),
- PersonalityEnc(PersonalityEnc) {}
-
- static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }
-
- StringRef getAugmentationString() const { return Augmentation; }
- uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
- int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
- uint8_t getVersion() const { return Version; }
- uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }
- Optional<uint64_t> getPersonalityAddress() const { return Personality; }
- Optional<uint32_t> getPersonalityEncoding() const { return PersonalityEnc; }
-
- uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }
-
- uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
-
- void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- bool IsEH) const override;
-
-private:
- /// The following fields are defined in section 6.4.1 of the DWARF standard v4
- const uint8_t Version;
- const SmallString<8> Augmentation;
- const uint8_t AddressSize;
- const uint8_t SegmentDescriptorSize;
- const uint64_t CodeAlignmentFactor;
- const int64_t DataAlignmentFactor;
- const uint64_t ReturnAddressRegister;
-
- // The following are used when the CIE represents an EH frame entry.
- const SmallString<8> AugmentationData;
- const uint32_t FDEPointerEncoding;
- const uint32_t LSDAPointerEncoding;
- const Optional<uint64_t> Personality;
- const Optional<uint32_t> PersonalityEnc;
-};
-
-/// DWARF Frame Description Entry (FDE)
-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(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
- uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
- Optional<uint64_t> LSDAAddress)
- : FrameEntry(FK_FDE, Offset, Length,
- Cie ? Cie->getCodeAlignmentFactor() : 0,
- Cie ? Cie->getDataAlignmentFactor() : 0),
- LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
- AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
-
- ~FDE() override = default;
-
- const CIE *getLinkedCIE() const { return LinkedCIE; }
- uint64_t getInitialLocation() const { return InitialLocation; }
- uint64_t getAddressRange() const { return AddressRange; }
- Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
-
- void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- bool IsEH) const override;
-
- static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
-
-private:
- /// The following fields are defined in section 6.4.1 of the DWARF standard v3
- const uint64_t LinkedCIEOffset;
- const uint64_t InitialLocation;
- const uint64_t AddressRange;
- const CIE *LinkedCIE;
- const Optional<uint64_t> LSDAAddress;
-};
-
-} // end namespace dwarf
-
-/// A parsed .debug_frame or .eh_frame section
+/// \brief A parsed .debug_frame or .eh_frame section
+///
class DWARFDebugFrame {
// True if this is parsing an eh_frame section.
- const bool IsEH;
- // Not zero for sane pointer values coming out of eh_frame
- const uint64_t EHFrameAddress;
-
- std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;
- using iterator = pointee_iterator<decltype(Entries)::const_iterator>;
-
- /// Return the entry at the given offset or nullptr.
- dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;
+ bool IsEH;
public:
- // If IsEH is true, assume it is a .eh_frame section. Otherwise,
- // it is a .debug_frame section. EHFrameAddress should be different
- // than zero for correct parsing of .eh_frame addresses when they
- // use a PC-relative encoding.
- DWARFDebugFrame(bool IsEH = false, uint64_t EHFrameAddress = 0);
+ DWARFDebugFrame(bool IsEH);
~DWARFDebugFrame();
/// Dump the section data into the given stream.
- void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- Optional<uint64_t> Offset) const;
+ void dump(raw_ostream &OS, Optional<uint64_t> Offset) const;
- /// Parse the section from raw data. \p Data is assumed to contain the whole
- /// frame section contents to be parsed.
- void parse(DWARFDataExtractor Data);
+ /// \brief Parse the section from raw data.
+ /// data is assumed to be pointing to the beginning of the section.
+ void parse(DataExtractor Data);
/// Return whether the section has any entries.
bool empty() const { return Entries.empty(); }
- /// DWARF Frame entries accessors
- iterator begin() const { return Entries.begin(); }
- iterator end() const { return Entries.end(); }
- iterator_range<iterator> entries() const {
- return iterator_range<iterator>(Entries.begin(), Entries.end());
- }
+ /// Return the entry at the given offset or nullptr.
+ FrameEntry *getEntryAtOffset(uint64_t Offset) const;
- uint64_t getEHFrameAddress() const { return EHFrameAddress; }
+private:
+ std::vector<std::unique_ptr<FrameEntry>> Entries;
};
} // end namespace llvm
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h Wed Mar 7 14:29:48 2018
@@ -93,13 +93,12 @@ public:
/// An iterator to go through the expression operations.
class iterator
- : public iterator_facade_base<iterator, std::forward_iterator_tag,
- Operation> {
+ : public iterator_facade_base<iterator, std::forward_iterator_tag, Operation> {
friend class DWARFExpression;
- const DWARFExpression *Expr;
+ DWARFExpression *Expr;
uint32_t Offset;
Operation Op;
- iterator(const DWARFExpression *Expr, uint32_t Offset)
+ iterator(DWARFExpression *Expr, uint32_t Offset)
: Expr(Expr), Offset(Offset) {
Op.Error =
Offset >= Expr->Data.getData().size() ||
@@ -128,11 +127,10 @@ public:
assert(AddressSize == 8 || AddressSize == 4);
}
- iterator begin() const { return iterator(this, 0); }
- iterator end() const { return iterator(this, Data.getData().size()); }
+ iterator begin() { return iterator(this, 0); }
+ iterator end() { return iterator(this, Data.getData().size()); }
- void print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
- bool IsEH = false) const;
+ void print(raw_ostream &OS, const MCRegisterInfo *RegInfo);
private:
DataExtractor Data;
Modified: llvm/trunk/include/llvm/Support/ScopedPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ScopedPrinter.h?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ScopedPrinter.h (original)
+++ llvm/trunk/include/llvm/Support/ScopedPrinter.h Wed Mar 7 14:29:48 2018
@@ -80,8 +80,6 @@ public:
void resetIndent() { IndentLevel = 0; }
- int getIndentLevel() { return IndentLevel; }
-
void setPrefix(StringRef P) { Prefix = P; }
void printIndent() {
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Mar 7 14:29:48 2018
@@ -349,11 +349,11 @@ void DWARFContext::dump(
if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
DObj->getDebugFrameSection()))
- getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ getDebugFrame()->dump(OS, DumpOffset);
if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
DObj->getEHFrameSection()))
- getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ getEHFrame()->dump(OS, DumpOffset);
if (DumpType & DIDT_DebugMacro) {
if (Explicit || !getDebugMacro()->empty()) {
@@ -712,8 +712,8 @@ const DWARFDebugFrame *DWARFContext::get
// 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
- DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
- isLittleEndian(), DObj->getAddressSize());
+ DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
+ DObj->getAddressSize());
DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
@@ -723,8 +723,8 @@ const DWARFDebugFrame *DWARFContext::get
if (EHFrame)
return EHFrame.get();
- DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
- DObj->getAddressSize());
+ DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
+ DObj->getAddressSize());
DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp Wed Mar 7 14:29:48 2018
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
using namespace llvm;
@@ -26,71 +25,3 @@ uint64_t DWARFDataExtractor::getRelocate
*SecNdx = Rel->SectionIndex;
return getUnsigned(Off, Size) + Rel->Value;
}
-
-Optional<uint64_t>
-DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
- uint64_t PCRelOffset) const {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return None;
-
- uint64_t Result = 0;
- uint32_t OldOffset = *Offset;
- // First get value
- switch (Encoding & 0x0F) {
- case dwarf::DW_EH_PE_absptr:
- switch (getAddressSize()) {
- case 2:
- case 4:
- case 8:
- Result = getUnsigned(Offset, getAddressSize());
- break;
- default:
- return None;
- }
- break;
- case dwarf::DW_EH_PE_uleb128:
- Result = getULEB128(Offset);
- break;
- case dwarf::DW_EH_PE_sleb128:
- Result = getSLEB128(Offset);
- break;
- case dwarf::DW_EH_PE_udata2:
- Result = getUnsigned(Offset, 2);
- break;
- case dwarf::DW_EH_PE_udata4:
- Result = getUnsigned(Offset, 4);
- break;
- case dwarf::DW_EH_PE_udata8:
- Result = getUnsigned(Offset, 8);
- break;
- case dwarf::DW_EH_PE_sdata2:
- Result = getSigned(Offset, 2);
- break;
- case dwarf::DW_EH_PE_sdata4:
- Result = getSigned(Offset, 4);
- break;
- case dwarf::DW_EH_PE_sdata8:
- Result = getSigned(Offset, 8);
- break;
- default:
- return None;
- }
- // Then add relative offset, if required
- switch (Encoding & 0x70) {
- case dwarf::DW_EH_PE_absptr:
- // do nothing
- break;
- case dwarf::DW_EH_PE_pcrel:
- Result += PCRelOffset;
- break;
- case dwarf::DW_EH_PE_datarel:
- case dwarf::DW_EH_PE_textrel:
- case dwarf::DW_EH_PE_funcrel:
- case dwarf::DW_EH_PE_aligned:
- default:
- *Offset = OldOffset;
- return None;
- }
-
- return Result;
-}
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp Wed Mar 7 14:29:48 2018
@@ -8,8 +8,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -29,13 +31,87 @@
using namespace llvm;
using namespace dwarf;
+/// \brief Abstract frame entry defining the common interface concrete
+/// entries implement.
+class llvm::FrameEntry {
+public:
+ enum FrameKind {FK_CIE, FK_FDE};
+
+ FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
+ : Kind(K), Offset(Offset), Length(Length) {}
+
+ virtual ~FrameEntry() = default;
+
+ FrameKind getKind() const { return Kind; }
+ virtual uint64_t getOffset() const { return Offset; }
+
+ /// Parse and store a sequence of CFI instructions from Data,
+ /// starting at *Offset and ending at EndOffset. If everything
+ /// goes well, *Offset should be equal to EndOffset when this method
+ /// returns. Otherwise, an error occurred.
+ virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
+ uint32_t EndOffset);
+
+ /// Dump the entry header to the given output stream.
+ virtual void dumpHeader(raw_ostream &OS) const = 0;
+
+ /// Dump the entry's instructions to the given output stream.
+ virtual void dumpInstructions(raw_ostream &OS) const;
+
+ /// Dump the entire entry to the given output stream.
+ void dump(raw_ostream &OS) const {
+ dumpHeader(OS);
+ dumpInstructions(OS);
+ OS << "\n";
+ }
+
+protected:
+ const FrameKind Kind;
+
+ /// \brief Offset of this entry in the section.
+ uint64_t Offset;
+
+ /// \brief Entry length as specified in DWARF.
+ uint64_t Length;
+
+ /// An entry may contain CFI instructions. An instruction consists of an
+ /// opcode and an optional sequence of operands.
+ using Operands = std::vector<uint64_t>;
+ struct Instruction {
+ Instruction(uint8_t Opcode)
+ : Opcode(Opcode)
+ {}
+
+ uint8_t Opcode;
+ Operands Ops;
+ };
+
+ std::vector<Instruction> Instructions;
+
+ /// Convenience methods to add a new instruction with the given opcode and
+ /// operands to the Instructions vector.
+ void addInstruction(uint8_t Opcode) {
+ Instructions.push_back(Instruction(Opcode));
+ }
+
+ void addInstruction(uint8_t Opcode, uint64_t Operand1) {
+ Instructions.push_back(Instruction(Opcode));
+ Instructions.back().Ops.push_back(Operand1);
+ }
+
+ void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
+ Instructions.push_back(Instruction(Opcode));
+ Instructions.back().Ops.push_back(Operand1);
+ Instructions.back().Ops.push_back(Operand2);
+ }
+};
// See DWARF standard v3, section 7.23
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
-Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
- uint32_t EndOffset) {
+void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
+ uint32_t EndOffset) {
while (*Offset < EndOffset) {
uint8_t Opcode = Data.getU8(Offset);
// Some instructions have a primary opcode encoded in the top bits.
@@ -46,73 +122,67 @@ Error CFIProgram::parse(DataExtractor Da
// bits of the opcode itself.
uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
switch (Primary) {
- default:
- return make_error<StringError>(
- "Invalid primary CFI opcode",
- std::make_error_code(std::errc::illegal_byte_sequence));
- case DW_CFA_advance_loc:
- case DW_CFA_restore:
- addInstruction(Primary, Op1);
- break;
- case DW_CFA_offset:
- addInstruction(Primary, Op1, Data.getULEB128(Offset));
- break;
+ default: llvm_unreachable("Impossible primary CFI opcode");
+ case DW_CFA_advance_loc:
+ case DW_CFA_restore:
+ addInstruction(Primary, Op1);
+ break;
+ case DW_CFA_offset:
+ addInstruction(Primary, Op1, Data.getULEB128(Offset));
+ break;
}
} else {
// Extended opcode - its value is Opcode itself.
switch (Opcode) {
- default:
- return make_error<StringError>(
- "Invalid extended CFI opcode",
- std::make_error_code(std::errc::illegal_byte_sequence));
- case DW_CFA_nop:
- case DW_CFA_remember_state:
- case DW_CFA_restore_state:
- case DW_CFA_GNU_window_save:
- // No operands
- addInstruction(Opcode);
- break;
- case DW_CFA_set_loc:
- // Operands: Address
- addInstruction(Opcode, Data.getAddress(Offset));
- break;
- case DW_CFA_advance_loc1:
- // Operands: 1-byte delta
- addInstruction(Opcode, Data.getU8(Offset));
- break;
- case DW_CFA_advance_loc2:
- // Operands: 2-byte delta
- addInstruction(Opcode, Data.getU16(Offset));
- break;
- case DW_CFA_advance_loc4:
- // Operands: 4-byte delta
- addInstruction(Opcode, Data.getU32(Offset));
- break;
- case DW_CFA_restore_extended:
- case DW_CFA_undefined:
- case DW_CFA_same_value:
- case DW_CFA_def_cfa_register:
- case DW_CFA_def_cfa_offset:
- case DW_CFA_GNU_args_size:
- // Operands: ULEB128
- addInstruction(Opcode, Data.getULEB128(Offset));
- break;
- case DW_CFA_def_cfa_offset_sf:
- // Operands: SLEB128
- addInstruction(Opcode, Data.getSLEB128(Offset));
- break;
- case DW_CFA_offset_extended:
- case DW_CFA_register:
- case DW_CFA_def_cfa:
- case DW_CFA_val_offset: {
- // Operands: ULEB128, ULEB128
- // Note: We can not embed getULEB128 directly into function
- // argument list. getULEB128 changes Offset and order of evaluation
- // for arguments is unspecified.
- auto op1 = Data.getULEB128(Offset);
- auto op2 = Data.getULEB128(Offset);
- addInstruction(Opcode, op1, op2);
- break;
+ default: llvm_unreachable("Invalid extended CFI opcode");
+ case DW_CFA_nop:
+ case DW_CFA_remember_state:
+ case DW_CFA_restore_state:
+ case DW_CFA_GNU_window_save:
+ // No operands
+ addInstruction(Opcode);
+ break;
+ case DW_CFA_set_loc:
+ // Operands: Address
+ addInstruction(Opcode, Data.getAddress(Offset));
+ break;
+ case DW_CFA_advance_loc1:
+ // Operands: 1-byte delta
+ addInstruction(Opcode, Data.getU8(Offset));
+ break;
+ case DW_CFA_advance_loc2:
+ // Operands: 2-byte delta
+ addInstruction(Opcode, Data.getU16(Offset));
+ break;
+ case DW_CFA_advance_loc4:
+ // Operands: 4-byte delta
+ addInstruction(Opcode, Data.getU32(Offset));
+ break;
+ case DW_CFA_restore_extended:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_GNU_args_size:
+ // Operands: ULEB128
+ addInstruction(Opcode, Data.getULEB128(Offset));
+ break;
+ case DW_CFA_def_cfa_offset_sf:
+ // Operands: SLEB128
+ addInstruction(Opcode, Data.getSLEB128(Offset));
+ break;
+ case DW_CFA_offset_extended:
+ case DW_CFA_register:
+ case DW_CFA_def_cfa:
+ case DW_CFA_val_offset: {
+ // Operands: ULEB128, ULEB128
+ // Note: We can not embed getULEB128 directly into function
+ // argument list. getULEB128 changes Offset and order of evaluation
+ // for arguments is unspecified.
+ auto op1 = Data.getULEB128(Offset);
+ auto op2 = Data.getULEB128(Offset);
+ addInstruction(Opcode, op1, op2);
+ break;
}
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
@@ -124,49 +194,162 @@ Error CFIProgram::parse(DataExtractor Da
addInstruction(Opcode, op1, op2);
break;
}
- case DW_CFA_def_cfa_expression: {
- uint32_t ExprLength = Data.getULEB128(Offset);
- addInstruction(Opcode, 0);
- DataExtractor Extractor(
- Data.getData().slice(*Offset, *Offset + ExprLength),
- Data.isLittleEndian(), Data.getAddressSize());
- Instructions.back().Expression = DWARFExpression(
- Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);
- *Offset += ExprLength;
+ case DW_CFA_def_cfa_expression:
+ // FIXME: Parse the actual instruction.
+ *Offset += Data.getULEB128(Offset);
break;
- }
case DW_CFA_expression:
case DW_CFA_val_expression: {
- auto RegNum = Data.getULEB128(Offset);
- auto BlockLength = Data.getULEB128(Offset);
- addInstruction(Opcode, RegNum, 0);
- DataExtractor Extractor(
- Data.getData().slice(*Offset, *Offset + BlockLength),
- Data.isLittleEndian(), Data.getAddressSize());
- Instructions.back().Expression = DWARFExpression(
- Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);
- *Offset += BlockLength;
+ // FIXME: Parse the actual instruction.
+ Data.getULEB128(Offset);
+ *Offset += Data.getULEB128(Offset);
break;
}
}
}
}
-
- return Error::success();
}
namespace {
+/// \brief DWARF Common Information Entry (CIE)
+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,
+ 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)
+ : FrameEntry(FK_CIE, Offset, Length), Version(Version),
+ Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
+ SegmentDescriptorSize(SegmentDescriptorSize),
+ CodeAlignmentFactor(CodeAlignmentFactor),
+ DataAlignmentFactor(DataAlignmentFactor),
+ ReturnAddressRegister(ReturnAddressRegister),
+ AugmentationData(std::move(AugmentationData)),
+ FDEPointerEncoding(FDEPointerEncoding),
+ LSDAPointerEncoding(LSDAPointerEncoding) {}
+
+ ~CIE() override = default;
+
+ StringRef getAugmentationString() const { return Augmentation; }
+ uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
+ int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
+
+ uint32_t getFDEPointerEncoding() const {
+ return FDEPointerEncoding;
+ }
+
+ uint32_t getLSDAPointerEncoding() const {
+ return LSDAPointerEncoding;
+ }
+
+ void dumpHeader(raw_ostream &OS) const override {
+ OS << format("%08x %08x %08x CIE",
+ (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
+ << "\n";
+ OS << format(" Version: %d\n", Version);
+ OS << " Augmentation: \"" << Augmentation << "\"\n";
+ if (Version >= 4) {
+ OS << format(" Address size: %u\n",
+ (uint32_t)AddressSize);
+ OS << format(" Segment desc size: %u\n",
+ (uint32_t)SegmentDescriptorSize);
+ }
+ OS << format(" Code alignment factor: %u\n",
+ (uint32_t)CodeAlignmentFactor);
+ OS << format(" Data alignment factor: %d\n",
+ (int32_t)DataAlignmentFactor);
+ OS << format(" Return address column: %d\n",
+ (int32_t)ReturnAddressRegister);
+ if (!AugmentationData.empty()) {
+ OS << " Augmentation data: ";
+ for (uint8_t Byte : AugmentationData)
+ OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
+ OS << "\n";
+ }
+ OS << "\n";
+ }
+
+ static bool classof(const FrameEntry *FE) {
+ return FE->getKind() == FK_CIE;
+ }
+
+private:
+ /// The following fields are defined in section 6.4.1 of the DWARF standard v4
+ uint8_t Version;
+ SmallString<8> Augmentation;
+ uint8_t AddressSize;
+ uint8_t SegmentDescriptorSize;
+ uint64_t CodeAlignmentFactor;
+ int64_t DataAlignmentFactor;
+ uint64_t ReturnAddressRegister;
+
+ // The following are used when the CIE represents an EH frame entry.
+ SmallString<8> AugmentationData;
+ uint32_t FDEPointerEncoding;
+ uint32_t LSDAPointerEncoding;
+};
+
+/// \brief DWARF Frame Description Entry (FDE)
+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(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
+ uint64_t InitialLocation, uint64_t AddressRange,
+ CIE *Cie)
+ : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
+ InitialLocation(InitialLocation), AddressRange(AddressRange),
+ LinkedCIE(Cie) {}
+
+ ~FDE() override = default;
+
+ CIE *getLinkedCIE() const { return LinkedCIE; }
+
+ void dumpHeader(raw_ostream &OS) const override {
+ 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);
+ }
+
+ static bool classof(const FrameEntry *FE) {
+ return FE->getKind() == FK_FDE;
+ }
+
+private:
+ /// The following fields are defined in section 6.4.1 of the DWARF standard v3
+ uint64_t LinkedCIEOffset;
+ uint64_t InitialLocation;
+ uint64_t AddressRange;
+ CIE *LinkedCIE;
+};
+
+/// \brief Types of operands to CF instructions.
+enum OperandType {
+ OT_Unset,
+ OT_None,
+ OT_Address,
+ OT_Offset,
+ OT_FactoredCodeOffset,
+ OT_SignedFactDataOffset,
+ OT_UnsignedFactDataOffset,
+ OT_Register,
+ OT_Expression
+};
} // end anonymous namespace
-ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
+/// \brief Initialize the array describing the types of operands.
+static ArrayRef<OperandType[2]> getOperandTypes() {
static OperandType OpTypes[DW_CFA_restore+1][2];
- static bool Initialized = false;
- if (Initialized) {
- return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
- }
- Initialized = true;
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
do { \
@@ -213,13 +396,15 @@ ArrayRef<CFIProgram::OperandType[2]> CFI
return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
}
-/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
-void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
- bool IsEH, const Instruction &Instr,
- unsigned OperandIdx, uint64_t Operand) const {
+static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
+
+/// \brief Print \p Opcode's operand number \p OperandIdx which has
+/// value \p Operand.
+static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
+ uint64_t Operand, uint64_t CodeAlignmentFactor,
+ int64_t DataAlignmentFactor) {
assert(OperandIdx < 2);
- uint8_t Opcode = Instr.Opcode;
- OperandType Type = getOperandTypes()[Opcode][OperandIdx];
+ OperandType Type = OpTypes[Opcode][OperandIdx];
switch (Type) {
case OT_Unset: {
@@ -264,68 +449,36 @@ void CFIProgram::printOperand(raw_ostrea
OS << format(" reg%" PRId64, Operand);
break;
case OT_Expression:
- assert(Instr.Expression && "missing DWARFExpression object");
- OS << " ";
- Instr.Expression->print(OS, MRI, IsEH);
+ OS << " expression";
break;
}
}
-void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
- unsigned IndentLevel) const {
+void FrameEntry::dumpInstructions(raw_ostream &OS) const {
+ uint64_t CodeAlignmentFactor = 0;
+ int64_t DataAlignmentFactor = 0;
+ const CIE *Cie = dyn_cast<CIE>(this);
+
+ if (!Cie)
+ Cie = cast<FDE>(this)->getLinkedCIE();
+ if (Cie) {
+ CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
+ DataAlignmentFactor = Cie->getDataAlignmentFactor();
+ }
+
for (const auto &Instr : Instructions) {
uint8_t Opcode = Instr.Opcode;
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
- OS.indent(2 * IndentLevel);
- OS << CallFrameString(Opcode) << ":";
+ OS << " " << CallFrameString(Opcode) << ":";
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
- printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
+ printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
+ DataAlignmentFactor);
OS << '\n';
}
}
-void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
- OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length,
- DW_CIE_ID)
- << "\n";
- OS << format(" Version: %d\n", Version);
- OS << " Augmentation: \"" << Augmentation << "\"\n";
- if (Version >= 4) {
- OS << format(" Address size: %u\n", (uint32_t)AddressSize);
- OS << format(" Segment desc size: %u\n",
- (uint32_t)SegmentDescriptorSize);
- }
- OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
- OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
- OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister);
- if (Personality)
- OS << format(" Personality Address: %08x\n", *Personality);
- if (!AugmentationData.empty()) {
- OS << " Augmentation data: ";
- for (uint8_t Byte : AugmentationData)
- OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
- OS << "\n";
- }
- OS << "\n";
- CFIs.dump(OS, MRI, IsEH);
- OS << "\n";
-}
-
-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);
- if (LSDAAddress)
- OS << format(" LSDA Address: %08x\n", *LSDAAddress);
- CFIs.dump(OS, MRI, IsEH);
- OS << "\n";
-}
-
-DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)
- : IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
+DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {}
DWARFDebugFrame::~DWARFDebugFrame() = default;
@@ -339,6 +492,40 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDa
errs() << "\n";
}
+static unsigned getSizeForEncoding(const DataExtractor &Data,
+ unsigned symbolEncoding) {
+ unsigned format = symbolEncoding & 0x0f;
+ switch (format) {
+ default: llvm_unreachable("Unknown Encoding");
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_signed:
+ return Data.getAddressSize();
+ case DW_EH_PE_udata2:
+ case DW_EH_PE_sdata2:
+ return 2;
+ case DW_EH_PE_udata4:
+ case DW_EH_PE_sdata4:
+ return 4;
+ case DW_EH_PE_udata8:
+ case DW_EH_PE_sdata8:
+ return 8;
+ }
+}
+
+static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,
+ unsigned Encoding) {
+ switch (getSizeForEncoding(Data, Encoding)) {
+ case 2:
+ return Data.getU16(&Offset);
+ case 4:
+ return Data.getU32(&Offset);
+ case 8:
+ return Data.getU64(&Offset);
+ default:
+ llvm_unreachable("Illegal data size");
+ }
+}
+
// This is a workaround for old compilers which do not allow
// noreturn attribute usage in lambdas. Once the support for those
// compilers are phased out, we can remove this and return back to
@@ -352,7 +539,7 @@ static void LLVM_ATTRIBUTE_NORETURN Repo
report_fatal_error(Str);
}
-void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
+void DWARFDebugFrame::parse(DataExtractor Data) {
uint32_t Offset = 0;
DenseMap<uint32_t, CIE *> CIEs;
@@ -382,8 +569,9 @@ void DWARFDebugFrame::parse(DWARFDataExt
// The Id field's size depends on the DWARF format
Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
- bool IsCIE =
- ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID || (IsEH && !Id));
+ bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
+ Id == DW_CIE_ID ||
+ (IsEH && !Id));
if (IsCIE) {
uint8_t Version = Data.getU8(&Offset);
@@ -401,9 +589,10 @@ void DWARFDebugFrame::parse(DWARFDataExt
StringRef AugmentationData("");
uint32_t FDEPointerEncoding = DW_EH_PE_omit;
uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
- Optional<uint64_t> Personality;
- Optional<uint32_t> PersonalityEncoding;
if (IsEH) {
+ Optional<uint32_t> PersonalityEncoding;
+ Optional<uint64_t> Personality;
+
Optional<uint64_t> AugmentationLength;
uint32_t StartAugmentationOffset;
uint32_t EndAugmentationOffset;
@@ -422,9 +611,7 @@ void DWARFDebugFrame::parse(DWARFDataExt
ReportError(StartOffset,
"Duplicate personality in entry at %lx");
PersonalityEncoding = Data.getU8(&Offset);
- Personality = Data.getEncodedPointer(
- &Offset, *PersonalityEncoding,
- EHFrameAddress ? EHFrameAddress + Offset : 0);
+ Personality = readPointer(Data, Offset, *PersonalityEncoding);
break;
}
case 'R':
@@ -452,11 +639,14 @@ void DWARFDebugFrame::parse(DWARFDataExt
}
}
- auto Cie = llvm::make_unique<CIE>(
- StartOffset, Length, Version, AugmentationString, AddressSize,
- SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
- ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
- LSDAPointerEncoding, Personality, PersonalityEncoding);
+ auto Cie = llvm::make_unique<CIE>(StartOffset, Length, Version,
+ AugmentationString, AddressSize,
+ SegmentDescriptorSize,
+ CodeAlignmentFactor,
+ DataAlignmentFactor,
+ ReturnAddressRegister,
+ AugmentationData, FDEPointerEncoding,
+ LSDAPointerEncoding);
CIEs[StartOffset] = Cie.get();
Entries.emplace_back(std::move(Cie));
} else {
@@ -464,7 +654,6 @@ void DWARFDebugFrame::parse(DWARFDataExt
uint64_t CIEPointer = Id;
uint64_t InitialLocation = 0;
uint64_t AddressRange = 0;
- Optional<uint64_t> LSDAAddress;
CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
if (IsEH) {
@@ -473,15 +662,10 @@ void DWARFDebugFrame::parse(DWARFDataExt
ReportError(StartOffset,
"Parsing FDE data at %lx failed due to missing CIE");
- if (auto Val = Data.getEncodedPointer(
- &Offset, Cie->getFDEPointerEncoding(),
- EHFrameAddress ? EHFrameAddress + Offset : 0)) {
- InitialLocation = *Val;
- }
- if (auto Val = Data.getEncodedPointer(
- &Offset, Cie->getFDEPointerEncoding(), 0)) {
- AddressRange = *Val;
- }
+ InitialLocation = readPointer(Data, Offset,
+ Cie->getFDEPointerEncoding());
+ AddressRange = readPointer(Data, Offset,
+ Cie->getFDEPointerEncoding());
StringRef AugmentationString = Cie->getAugmentationString();
if (!AugmentationString.empty()) {
@@ -492,11 +676,8 @@ void DWARFDebugFrame::parse(DWARFDataExt
Offset + static_cast<uint32_t>(AugmentationLength);
// Decode the LSDA if the CIE augmentation string said we should.
- if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
- LSDAAddress = Data.getEncodedPointer(
- &Offset, Cie->getLSDAPointerEncoding(),
- EHFrameAddress ? Offset + EHFrameAddress : 0);
- }
+ if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
+ readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
if (Offset != EndAugmentationOffset)
ReportError(StartOffset, "Parsing augmentation data at %lx failed");
@@ -508,13 +689,10 @@ void DWARFDebugFrame::parse(DWARFDataExt
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
InitialLocation, AddressRange,
- Cie, LSDAAddress));
+ Cie));
}
- if (Error E =
- Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset)) {
- report_fatal_error(toString(std::move(E)));
- }
+ Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
if (Offset != EndStructureOffset)
ReportError(StartOffset, "Parsing entry instructions at %lx failed");
@@ -531,15 +709,14 @@ FrameEntry *DWARFDebugFrame::getEntryAtO
return nullptr;
}
-void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- Optional<uint64_t> Offset) const {
+void DWARFDebugFrame::dump(raw_ostream &OS, Optional<uint64_t> Offset) const {
if (Offset) {
if (auto *Entry = getEntryAtOffset(*Offset))
- Entry->dump(OS, MRI, IsEH);
+ Entry->dump(OS);
return;
}
OS << "\n";
for (const auto &Entry : Entries)
- Entry->dump(OS, MRI, IsEH);
+ Entry->dump(OS);
}
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp Wed Mar 7 14:29:48 2018
@@ -258,10 +258,9 @@ bool DWARFExpression::Operation::print(r
return true;
}
-void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
- bool IsEH) const {
+void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) {
for (auto &Op : *this) {
- if (!Op.print(OS, this, RegInfo, IsEH)) {
+ if (!Op.print(OS, this, RegInfo, /* isEH */ false)) {
uint32_t FailOffset = Op.getEndOffset();
while (FailOffset < Data.getData().size())
OS << format(" %02x", Data.getU8(&FailOffset));
Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Wed Mar 7 14:29:48 2018
@@ -50,7 +50,6 @@ void ScalarEnumerationTraits<ELFYAML::EL
ECase(PT_SHLIB);
ECase(PT_PHDR);
ECase(PT_TLS);
- ECase(PT_GNU_EH_FRAME);
#undef ECase
IO.enumFallback<Hex32>(Value);
}
Removed: llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml?rev=326952&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml (original)
+++ llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml (removed)
@@ -1,46 +0,0 @@
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
- Machine: EM_X86_64
- Entry: 0x0000000000400000
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Address: 0x0000000000400000
- AddressAlign: 16
- Content: 50C704240020400031C05AC3
- - Name: .eh_frame_hdr
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- Address: 0x00000000004013c0
- AddressAlign: 4
- Content: 011B033B3C00000006000000E0F0FFFF8800000010F1FFFF58000000F6F1FFFFB000000010F2FFFFD000000090FEFFFF0001000000FFFFFF30010000
- - Name: .eh_frame
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- Address: 0x0000000000401400
- AddressAlign: 8
- Content: 1400000000000000017A5200017810011B0C070890010710140000001C000000B0F0FFFF2A00000000000000000000001400000000000000017A5200017810011B0C070890010000240000001C00000050F0FFFF20000000000E10460E184A0F0B770880003F1A3B2A332422000000001C000000440000003EF1FFFF1000000000410E108602430D064B0C07080000002C0000006400000038F1FFFF7F0C000000450C0A00491006027600450F0376780603660C0C0A00450C070800000000002C0000009400000088FDFFFF6600000000410E108602430D06428F03458E04478D058C06488307024B0C07080000000014000000C4000000C8FDFFFF01000000000000000000000000000000
-Symbols:
- Global:
- - Name: myfunc
- Type: STT_FUNC
- Section: .text
- Value: 0x0000000000400000
-ProgramHeaders:
- - Type: PT_LOAD
- Flags: [ PF_X, PF_R ]
- VAddr: 0x00400000
- PAddr: 0x00400000
- Sections:
- - Section: .text
- - Type: PT_GNU_EH_FRAME
- Flags: [ PF_X, PF_R ]
- VAddr: 0x004013C0
- PAddr: 0x004013C0
- Sections:
- - Section: .eh_frame_hdr
-...
Removed: llvm/trunk/test/tools/llvm-readobj/unwind.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/unwind.test?rev=326952&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/unwind.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/unwind.test (removed)
@@ -1,170 +0,0 @@
-RUN: yaml2obj %p/Inputs/dwarf-exprs.exe-x86-64.yaml > %t.exe
-RUN: llvm-readobj -unwind %t.exe | FileCheck %s
-
-CHECK: EH_FRAME Header [
-CHECK-NEXT: Address: 0x4013c0
-CHECK-NEXT: Offset: 0x27c
-CHECK-NEXT: Size: 0x3c
-CHECK-NEXT: Corresponding Section: .eh_frame_hdr
-CHECK-NEXT: Header {
-CHECK-NEXT: version: 1
-CHECK-NEXT: eh_frame_ptr_enc: 0x1b
-CHECK-NEXT: fde_count_enc: 0x3
-CHECK-NEXT: table_enc: 0x3b
-CHECK-NEXT: eh_frame_ptr: 0x401400
-CHECK-NEXT: fde_count: 6
-CHECK-NEXT: entry 0 {
-CHECK-NEXT: initial_location: 0x4004a0
-CHECK-NEXT: address: 0x401448
-CHECK-NEXT: }
-CHECK-NEXT: entry 1 {
-CHECK-NEXT: initial_location: 0x4004d0
-CHECK-NEXT: address: 0x401418
-CHECK-NEXT: }
-CHECK-NEXT: entry 2 {
-CHECK-NEXT: initial_location: 0x4005b6
-CHECK-NEXT: address: 0x401470
-CHECK-NEXT: }
-CHECK-NEXT: entry 3 {
-CHECK-NEXT: initial_location: 0x4005d0
-CHECK-NEXT: address: 0x401490
-CHECK-NEXT: }
-CHECK-NEXT: entry 4 {
-CHECK-NEXT: initial_location: 0x401250
-CHECK-NEXT: address: 0x4014c0
-CHECK-NEXT: }
-CHECK-NEXT: entry 5 {
-CHECK-NEXT: initial_location: 0x4012c0
-CHECK-NEXT: address: 0x4014f0
-CHECK-NEXT: }
-CHECK-NEXT: }
-CHECK-NEXT:]
-
-CHECK: .eh_frame section at offset 0x2b8 address 0x401400:
-CHECK-NEXT: [0x401400] CIE length=20
-CHECK-NEXT: version: 1
-CHECK-NEXT: augmentation: zR
-CHECK-NEXT: code_alignment_factor: 1
-CHECK-NEXT: data_alignment_factor: -8
-CHECK-NEXT: return_address_register: 16
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
-CHECK-NEXT: DW_CFA_offset: reg16 -8
-CHECK-NEXT: DW_CFA_undefined: reg16
-
-CHECK: [0x401418] FDE length=20 cie=[0x401400]
-CHECK-NEXT: initial_location: 0x4004d0
-CHECK-NEXT: address_range: 0x2a (end : 0x4004fa)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x401430] CIE length=20
-CHECK-NEXT: version: 1
-CHECK-NEXT: augmentation: zR
-CHECK-NEXT: code_alignment_factor: 1
-CHECK-NEXT: data_alignment_factor: -8
-CHECK-NEXT: return_address_register: 16
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
-CHECK-NEXT: DW_CFA_offset: reg16 -8
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x401448] FDE length=36 cie=[0x401430]
-CHECK-NEXT: initial_location: 0x4004a0
-CHECK-NEXT: address_range: 0x20 (end : 0x4004c0)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_def_cfa_offset: +16
-CHECK-NEXT: DW_CFA_advance_loc: 6
-CHECK-NEXT: DW_CFA_def_cfa_offset: +24
-CHECK-NEXT: DW_CFA_advance_loc: 10
-CHECK-NEXT: DW_CFA_def_cfa_expression: DW_OP_breg7 +8, DW_OP_breg16 +0, DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge, DW_OP_lit3, DW_OP_shl, DW_OP_plus
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x401470] FDE length=28 cie=[0x401430]
-CHECK-NEXT: initial_location: 0x4005b6
-CHECK-NEXT: address_range: 0x10 (end : 0x4005c6)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_advance_loc: 1
-CHECK-NEXT: DW_CFA_def_cfa_offset: +16
-CHECK-NEXT: DW_CFA_offset: reg6 -16
-CHECK-NEXT: DW_CFA_advance_loc: 3
-CHECK-NEXT: DW_CFA_def_cfa_register: reg6
-CHECK-NEXT: DW_CFA_advance_loc: 11
-CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x401490] FDE length=44 cie=[0x401430]
-CHECK-NEXT: initial_location: 0x4005d0
-CHECK-NEXT: address_range: 0xc7f (end : 0x40124f)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_advance_loc: 5
-CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
-CHECK-NEXT: DW_CFA_advance_loc: 9
-CHECK-NEXT: DW_CFA_expression: reg6 DW_OP_breg6 +0
-CHECK-NEXT: DW_CFA_advance_loc: 5
-CHECK-NEXT: DW_CFA_def_cfa_expression: DW_OP_breg6 -8, DW_OP_deref
-CHECK-NEXT: DW_CFA_advance_loc2: 3174
-CHECK-NEXT: DW_CFA_def_cfa: reg10 +0
-CHECK-NEXT: DW_CFA_advance_loc: 5
-CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x4014c0] FDE length=44 cie=[0x401430]
-CHECK-NEXT: initial_location: 0x401250
-CHECK-NEXT: address_range: 0x66 (end : 0x4012b6)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_advance_loc: 1
-CHECK-NEXT: DW_CFA_def_cfa_offset: +16
-CHECK-NEXT: DW_CFA_offset: reg6 -16
-CHECK-NEXT: DW_CFA_advance_loc: 3
-CHECK-NEXT: DW_CFA_def_cfa_register: reg6
-CHECK-NEXT: DW_CFA_advance_loc: 2
-CHECK-NEXT: DW_CFA_offset: reg15 -24
-CHECK-NEXT: DW_CFA_advance_loc: 5
-CHECK-NEXT: DW_CFA_offset: reg14 -32
-CHECK-NEXT: DW_CFA_advance_loc: 7
-CHECK-NEXT: DW_CFA_offset: reg13 -40
-CHECK-NEXT: DW_CFA_offset: reg12 -48
-CHECK-NEXT: DW_CFA_advance_loc: 8
-CHECK-NEXT: DW_CFA_offset: reg3 -56
-CHECK-NEXT: DW_CFA_advance_loc1: 75
-CHECK-NEXT: DW_CFA_def_cfa: reg7 +8
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-
-CHECK: [0x4014f0] FDE length=20 cie=[0x401430]
-CHECK-NEXT: initial_location: 0x4012c0
-CHECK-NEXT: address_range: 0x1 (end : 0x4012c1)
-
-CHECK: Program:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
-CHECK-NEXT: DW_CFA_nop:
Modified: llvm/trunk/tools/llvm-readobj/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CMakeLists.txt?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-readobj/CMakeLists.txt Wed Mar 7 14:29:48 2018
@@ -1,6 +1,5 @@
set(LLVM_LINK_COMPONENTS
DebugInfoCodeView
- DebugInfoDWARF
Object
BinaryFormat
Support
Removed: llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h?rev=326952&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h (original)
+++ llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h (removed)
@@ -1,244 +0,0 @@
-//===--- DwarfCFIEHPrinter.h - DWARF-based Unwind Information Printer -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H
-#define LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H
-
-#include "Error.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/type_traits.h"
-
-namespace llvm {
-namespace DwarfCFIEH {
-
-template <typename ELFT>
-class PrinterContext {
- ScopedPrinter &W;
- const object::ELFFile<ELFT> *Obj;
-
- void printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;
-
- void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;
-
-public:
- PrinterContext(ScopedPrinter &W, const object::ELFFile<ELFT> *Obj)
- : W(W), Obj(Obj) {}
-
- void printUnwindInformation() const;
-};
-
-template <class ELFO>
-static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,
- uint64_t Addr) {
- auto Sections = Obj->sections();
- if (Error E = Sections.takeError())
- reportError(toString(std::move(E)));
-
- for (const auto &Shdr : *Sections)
- if (Shdr.sh_addr == Addr)
- return &Shdr;
- return nullptr;
-}
-
-template <typename ELFT>
-void PrinterContext<ELFT>::printUnwindInformation() const {
- const typename ELFT::Phdr *EHFramePhdr = nullptr;
-
- auto PHs = Obj->program_headers();
- if (Error E = PHs.takeError())
- reportError(toString(std::move(E)));
-
- for (const auto &Phdr : *PHs) {
- if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {
- EHFramePhdr = &Phdr;
- if (Phdr.p_memsz != Phdr.p_filesz)
- reportError("p_memsz does not match p_filesz for GNU_EH_FRAME");
- break;
- }
- }
-
- if (EHFramePhdr)
- printEHFrameHdr(EHFramePhdr->p_offset, EHFramePhdr->p_vaddr,
- EHFramePhdr->p_memsz);
-
- auto Sections = Obj->sections();
- if (Error E = Sections.takeError())
- reportError(toString(std::move(E)));
-
- for (const auto &Shdr : *Sections) {
- auto SectionName = Obj->getSectionName(&Shdr);
- if (Error E = SectionName.takeError())
- reportError(toString(std::move(E)));
-
- if (*SectionName == ".eh_frame")
- printEHFrame(&Shdr);
- }
-}
-
-template <typename ELFT>
-void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
- uint64_t EHFrameHdrAddress,
- uint64_t EHFrameHdrSize) const {
- ListScope L(W, "EH_FRAME Header");
- W.startLine() << format("Address: 0x%" PRIx64 "\n", EHFrameHdrAddress);
- W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
- W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);
-
- const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);
- if (EHFrameHdrShdr) {
- auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
- if (Error E = SectionName.takeError())
- reportError(toString(std::move(E)));
-
- W.printString("Corresponding Section", *SectionName);
- }
-
- DataExtractor DE(
- StringRef(reinterpret_cast<const char *>(Obj->base()) + EHFrameHdrOffset,
- EHFrameHdrSize),
- ELFT::TargetEndianness == support::endianness::little,
- ELFT::Is64Bits ? 8 : 4);
-
- DictScope D(W, "Header");
- uint32_t Offset = 0;
-
- auto Version = DE.getU8(&Offset);
- W.printNumber("version", Version);
- if (Version != 1)
- reportError("only version 1 of .eh_frame_hdr is supported");
-
- auto EHFramePtrEnc = DE.getU8(&Offset);
- W.startLine() << format("eh_frame_ptr_enc: 0x%" PRIx64 "\n", EHFramePtrEnc);
- if (EHFramePtrEnc != (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4))
- reportError("unexpected encoding eh_frame_ptr_enc");
-
- auto FDECountEnc = DE.getU8(&Offset);
- W.startLine() << format("fde_count_enc: 0x%" PRIx64 "\n", FDECountEnc);
- if (FDECountEnc != dwarf::DW_EH_PE_udata4)
- reportError("unexpected encoding fde_count_enc");
-
- auto TableEnc = DE.getU8(&Offset);
- W.startLine() << format("table_enc: 0x%" PRIx64 "\n", TableEnc);
- if (TableEnc != (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4))
- reportError("unexpected encoding table_enc");
-
- auto EHFramePtr = DE.getSigned(&Offset, 4) + EHFrameHdrAddress + 4;
- W.startLine() << format("eh_frame_ptr: 0x%" PRIx64 "\n", EHFramePtr);
-
- auto FDECount = DE.getUnsigned(&Offset, 4);
- W.printNumber("fde_count", FDECount);
-
- unsigned NumEntries = 0;
- uint64_t PrevPC = 0;
- while (Offset + 8 <= EHFrameHdrSize && NumEntries < FDECount) {
- DictScope D(W, std::string("entry ") + std::to_string(NumEntries));
-
- auto InitialPC = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;
- W.startLine() << format("initial_location: 0x%" PRIx64 "\n", InitialPC);
- auto Address = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;
- W.startLine() << format("address: 0x%" PRIx64 "\n", Address);
-
- if (InitialPC < PrevPC)
- reportError("initial_location is out of order");
-
- PrevPC = InitialPC;
- ++NumEntries;
- }
-}
-
-template <typename ELFT>
-void PrinterContext<ELFT>::printEHFrame(
- const typename ELFT::Shdr *EHFrameShdr) const {
- uint64_t Address = EHFrameShdr->sh_addr;
- uint64_t ShOffset = EHFrameShdr->sh_offset;
- W.startLine() << format(".eh_frame section at offset 0x%" PRIx64
- " address 0x%" PRIx64 ":\n",
- ShOffset, Address);
- W.indent();
-
- auto Result = Obj->getSectionContents(EHFrameShdr);
- if (Error E = Result.takeError())
- reportError(toString(std::move(E)));
-
- auto Contents = Result.get();
- DWARFDataExtractor DE(
- StringRef(reinterpret_cast<const char *>(Contents.data()),
- Contents.size()),
- ELFT::TargetEndianness == support::endianness::little,
- ELFT::Is64Bits ? 8 : 4);
- DWARFDebugFrame EHFrame(/*IsEH=*/true, /*EHFrameAddress=*/Address);
- EHFrame.parse(DE);
-
- for (const auto &Entry : EHFrame) {
- if (const auto *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
- W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",
- Address + CIE->getOffset(),
- CIE->getLength());
- W.indent();
-
- W.printNumber("version", CIE->getVersion());
- W.printString("augmentation", CIE->getAugmentationString());
- W.printNumber("code_alignment_factor", CIE->getCodeAlignmentFactor());
- W.printNumber("data_alignment_factor", CIE->getDataAlignmentFactor());
- W.printNumber("return_address_register", CIE->getReturnAddressRegister());
-
- W.getOStream() << "\n";
- W.startLine() << "Program:\n";
- W.indent();
- CIE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
- W.unindent();
-
- W.unindent();
- W.getOStream() << "\n";
-
- } else if (const auto *FDE = dyn_cast<dwarf::FDE>(&Entry)) {
- W.startLine() << format("[0x%" PRIx64 "] FDE length=%" PRIu64
- " cie=[0x%" PRIx64 "]\n",
- Address + FDE->getOffset(),
- FDE->getLength(),
- Address + FDE->getLinkedCIE()->getOffset());
- W.indent();
-
- W.startLine() << format("initial_location: 0x%" PRIx64 "\n",
- FDE->getInitialLocation());
- W.startLine()
- << format("address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
- FDE->getAddressRange(),
- FDE->getInitialLocation() + FDE->getAddressRange());
-
- W.getOStream() << "\n";
- W.startLine() << "Program:\n";
- W.indent();
- FDE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
- W.unindent();
-
- W.unindent();
- W.getOStream() << "\n";
- } else {
- llvm_unreachable("unexpected DWARF frame kind");
- }
- }
-
- W.unindent();
-}
-
-}
-}
-
-#endif
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=326953&r1=326952&r2=326953&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Mar 7 14:29:48 2018
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "ARMEHABIPrinter.h"
-#include "DwarfCFIEHPrinter.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
@@ -1809,11 +1808,6 @@ void ELFDumper<ELFT>::printValue(uint64_
template<class ELFT>
void ELFDumper<ELFT>::printUnwindInfo() {
- const unsigned Machine = Obj->getHeader()->e_machine;
- if (Machine == EM_386 || Machine == EM_X86_64) {
- DwarfCFIEH::PrinterContext<ELFT> Ctx(W, Obj);
- return Ctx.printUnwindInformation();
- }
W.startLine() << "UnwindInfo not implemented.\n";
}
More information about the llvm-commits
mailing list