<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Thanks for flagging this, Galina. This commit was reverted already, but I relanded it with a fix for your builder in rL326970.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">Galina Kistanova <gkistanova@gmail.com><br>
<b>Date: </b>Wednesday, March 7, 2018 at 3:31 PM<br>
<b>To: </b>Rafael Auler <rafaelauler@fb.com><br>
<b>Cc: </b>Artur Pilipenko via llvm-commits <llvm-commits@lists.llvm.org><br>
<b>Subject: </b>Re: [llvm] r326932 - [DebugInfo] Support DWARF expressions in eh_frame<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><a name="_MailOriginalBody">Hello Rafael,<br>
<br>
The test tools/llvm-readobj/unwind.test failed on one of our builders:<br>
<br>
</a><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lab.llvm.org-3A8011_builders_llvm-2Dclang-2Dlld-2Dx86-5F64-2Dscei-2Dps4-2Dwindows10pro-2Dfast_builds_15776&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=PhFmLof-Dt0HxeFHMxmSRJG7P0iKWvRCFPXh1fVLqv0&e="><span style="mso-bookmark:_MailOriginalBody">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/15776</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
<br>
The builder was already red and did not send notifications on the changes.<br>
Please have a look?<br>
<br>
Thanks<br>
<br>
Galina<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="mso-bookmark:_MailOriginalBody"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal"><span style="mso-bookmark:_MailOriginalBody">On Wed, Mar 7, 2018 at 11:19 AM, Rafael Auler via llvm-commits <</span><a href="mailto:llvm-commits@lists.llvm.org" target="_blank"><span style="mso-bookmark:_MailOriginalBody">llvm-commits@lists.llvm.org</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody">>
 wrote:<o:p></o:p></span></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal"><span style="mso-bookmark:_MailOriginalBody">Author: rafauler<br>
Date: Wed Mar  7 11:19:51 2018<br>
New Revision: 326932<br>
<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D326932-26view-3Drev&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=ejAW0CVup7F6ODznkSltuKmsVVX4BGAMS_R_meluu0Y&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project?rev=326932&view=rev</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
Log:<br>
[DebugInfo] Support DWARF expressions in eh_frame<br>
<br>
This patch enhances DWARFDebugFrame with the capability of parsing and<br>
printing DWARF expressions in CFI instructions. It also makes FDEs and<br>
CIEs accessible to lib users, so they can process them in client tools<br>
that rely on LLVM. To make it self-contained with a test case, it<br>
teaches llvm-readobj to be able to dump EH frames and checks they are<br>
correct in a unit test. The llvm-readobj code is Maksim Panchenko's work<br>
(maksfb).<br>
<br>
Reviewers: JDevlieghere, espindola<br>
<br>
Reviewed By: JDevlieghere<br>
<br>
Differential Revision: </span><a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__reviews.llvm.org_D43313&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=c0lbBf4QPTuM8VaeiQKxqeqNR4-9S4LErHdJFSKZavs&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">https://reviews.llvm.org/D43313</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
<br>
Added:<br>
    llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml<br>
    llvm/trunk/test/tools/llvm-readobj/unwind.test<br>
    llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h<br>
Modified:<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h<br>
    llvm/trunk/include/llvm/Support/ScopedPrinter.h<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp<br>
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp<br>
    llvm/trunk/tools/llvm-readobj/CMakeLists.txt<br>
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_DebugInfo_DWARF_DWARFDataExtractor.h-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=bFjkP14k3MkjPLdqQAxMPVpayrw0hBcze7sBigjVmIc&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h Wed Mar  7 11:19:51 2018<br>
@@ -44,6 +44,13 @@ public:<br>
   uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const {<br>
     return getRelocatedValue(getAddressSize(), Off, SecIx);<br>
   }<br>
+<br>
+  /// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding.<br>
+  /// There is a DWARF encoding that uses a PC-relative adjustment.<br>
+  /// For these values, \p AbsPosOffset is used to fix them, which should<br>
+  /// reflect the absolute address of this pointer.<br>
+  Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding,<br>
+                                       uint64_t AbsPosOffset = 0) const;<br>
 };<br>
<br>
 } // end namespace llvm<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_DebugInfo_DWARF_DWARFDebugFrame.h-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=MaQ9qWyW9f9dKoFXOFUAG30G12b4O834uzYBw-Ln-GE&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h Wed Mar  7 11:19:51 2018<br>
@@ -10,40 +10,290 @@<br>
 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H<br>
 #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H<br>
<br>
-#include "llvm/Support/DataExtractor.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/iterator.h"<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"<br>
+#include "llvm/Support/Error.h"<br>
 #include <memory><br>
 #include <vector><br>
<br>
 namespace llvm {<br>
<br>
-class FrameEntry;<br>
 class raw_ostream;<br>
<br>
-/// \brief A parsed .debug_frame or .eh_frame section<br>
-///<br>
+namespace dwarf {<br>
+<br>
+/// Represent a sequence of Call Frame Information instructions that, when read<br>
+/// in order, construct a table mapping PC to frame state. This can also be<br>
+/// referred to as "CFI rules" in DWARF literature to avoid confusion with<br>
+/// computer programs in the broader sense, and in this context each instruction<br>
+/// would be a rule to establish the mapping. Refer to pg. 172 in the DWARF5<br>
+/// manual, "6.4.1 Structure of Call Frame Information".<br>
+class CFIProgram {<br>
+public:<br>
+  typedef SmallVector<uint64_t, 2> Operands;<br>
+<br>
+  /// An instruction consists of a DWARF CFI opcode and an optional sequence of<br>
+  /// operands. If it refers to an expression, then this expression has its own<br>
+  /// sequence of operations and operands handled separately by DWARFExpression.<br>
+  struct Instruction {<br>
+    Instruction(uint8_t Opcode) : Opcode(Opcode) {}<br>
+<br>
+    uint8_t Opcode;<br>
+    Operands Ops;<br>
+    // Associated DWARF expression in case this instruction refers to one<br>
+    Optional<DWARFExpression> Expression;<br>
+  };<br>
+<br>
+  using InstrList = std::vector<Instruction>;<br>
+  using iterator = InstrList::iterator;<br>
+  using const_iterator = InstrList::const_iterator;<br>
+<br>
+  iterator begin() { return Instructions.begin(); }<br>
+  const_iterator begin() const { return Instructions.begin(); }<br>
+  iterator end() { return Instructions.end(); }<br>
+  const_iterator end() const { return Instructions.end(); }<br>
+<br>
+  unsigned size() const { return (unsigned)Instructions.size(); }<br>
+  bool empty() const { return Instructions.empty(); }<br>
+<br>
+  CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)<br>
+      : CodeAlignmentFactor(CodeAlignmentFactor),<br>
+        DataAlignmentFactor(DataAlignmentFactor) {}<br>
+<br>
+  /// Parse and store a sequence of CFI instructions from Data,<br>
+  /// starting at *Offset and ending at EndOffset. *Offset is updated<br>
+  /// to EndOffset upon successful parsing, or indicates the offset<br>
+  /// where a problem occurred in case an error is returned.<br>
+  Error parse(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset);<br>
+<br>
+  void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,<br>
+            unsigned IndentLevel = 1) const;<br>
+<br>
+private:<br>
+  std::vector<Instruction> Instructions;<br>
+  const uint64_t CodeAlignmentFactor;<br>
+  const int64_t DataAlignmentFactor;<br>
+<br>
+  /// Convenience method to add a new instruction with the given opcode.<br>
+  void addInstruction(uint8_t Opcode) {<br>
+    Instructions.push_back(Instruction(Opcode));<br>
+  }<br>
+<br>
+  /// Add a new single-operand instruction.<br>
+  void addInstruction(uint8_t Opcode, uint64_t Operand1) {<br>
+    Instructions.push_back(Instruction(Opcode));<br>
+    Instructions.back().Ops.push_back(Operand1);<br>
+  }<br>
+<br>
+  /// Add a new instruction that has two operands.<br>
+  void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {<br>
+    Instructions.push_back(Instruction(Opcode));<br>
+    Instructions.back().Ops.push_back(Operand1);<br>
+    Instructions.back().Ops.push_back(Operand2);<br>
+  }<br>
+<br>
+  /// Types of operands to CFI instructions<br>
+  /// In DWARF, this type is implicitly tied to a CFI instruction opcode and<br>
+  /// thus this type doesn't need to be explictly written to the file (this is<br>
+  /// not a DWARF encoding). The relationship of instrs to operand types can<br>
+  /// be obtained from getOperandTypes() and is only used to simplify<br>
+  /// instruction printing.<br>
+  enum OperandType {<br>
+    OT_Unset,<br>
+    OT_None,<br>
+    OT_Address,<br>
+    OT_Offset,<br>
+    OT_FactoredCodeOffset,<br>
+    OT_SignedFactDataOffset,<br>
+    OT_UnsignedFactDataOffset,<br>
+    OT_Register,<br>
+    OT_Expression<br>
+  };<br>
+<br>
+  /// Retrieve the array describing the types of operands according to the enum<br>
+  /// above. This is indexed by opcode.<br>
+  static ArrayRef<OperandType[2]> getOperandTypes();<br>
+<br>
+  /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.<br>
+  void printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,<br>
+                    const Instruction &Instr, unsigned OperandIdx,<br>
+                    uint64_t Operand) const;<br>
+};<br>
+<br>
+/// An entry in either debug_frame or eh_frame. This entry can be a CIE or an<br>
+/// FDE.<br>
+class FrameEntry {<br>
+public:<br>
+  enum FrameKind { FK_CIE, FK_FDE };<br>
+<br>
+  FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,<br>
+             int64_t DataAlign)<br>
+      : Kind(K), Offset(Offset), Length(Length), CFIs(CodeAlign, DataAlign) {}<br>
+<br>
+  virtual ~FrameEntry() {}<br>
+<br>
+  FrameKind getKind() const { return Kind; }<br>
+  uint64_t getOffset() const { return Offset; }<br>
+  uint64_t getLength() const { return Length; }<br>
+  const CFIProgram &cfis() const { return CFIs; }<br>
+  CFIProgram &cfis() { return CFIs; }<br>
+<br>
+  /// Dump the instructions in this CFI fragment<br>
+  virtual void dump(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+                    bool IsEH) const = 0;<br>
+<br>
+protected:<br>
+  const FrameKind Kind;<br>
+<br>
+  /// Offset of this entry in the section.<br>
+  const uint64_t Offset;<br>
+<br>
+  /// Entry length as specified in DWARF.<br>
+  const uint64_t Length;<br>
+<br>
+  CFIProgram CFIs;<br>
+};<br>
+<br>
+/// DWARF Common Information Entry (CIE)<br>
+class CIE : public FrameEntry {<br>
+public:<br>
+  // CIEs (and FDEs) are simply container classes, so the only sensible way to<br>
+  // create them is by providing the full parsed contents in the constructor.<br>
+  CIE(uint64_t Offset, uint64_t Length, uint8_t Version,<br>
+      SmallString<8> Augmentation, uint8_t AddressSize,<br>
+      uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,<br>
+      int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,<br>
+      SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,<br>
+      uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,<br>
+      Optional<uint32_t> PersonalityEnc)<br>
+      : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,<br>
+                   DataAlignmentFactor),<br>
+        Version(Version), Augmentation(std::move(Augmentation)),<br>
+        AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),<br>
+        CodeAlignmentFactor(CodeAlignmentFactor),<br>
+        DataAlignmentFactor(DataAlignmentFactor),<br>
+        ReturnAddressRegister(ReturnAddressRegister),<br>
+        AugmentationData(std::move(AugmentationData)),<br>
+        FDEPointerEncoding(FDEPointerEncoding),<br>
+        LSDAPointerEncoding(LSDAPointerEncoding), Personality(Personality),<br>
+        PersonalityEnc(PersonalityEnc) {}<br>
+<br>
+  static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_CIE; }<br>
+<br>
+  StringRef getAugmentationString() const { return Augmentation; }<br>
+  uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }<br>
+  int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }<br>
+  uint8_t getVersion() const { return Version; }<br>
+  uint64_t getReturnAddressRegister() const { return ReturnAddressRegister; }<br>
+  Optional<uint64_t> getPersonalityAddress() const { return Personality; }<br>
+  Optional<uint32_t> getPersonalityEncoding() const { return PersonalityEnc; }<br>
+<br>
+  uint32_t getFDEPointerEncoding() const { return FDEPointerEncoding; }<br>
+<br>
+  uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }<br>
+<br>
+  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+            bool IsEH) const override;<br>
+<br>
+private:<br>
+  /// The following fields are defined in section 6.4.1 of the DWARF standard v4<br>
+  const uint8_t Version;<br>
+  const SmallString<8> Augmentation;<br>
+  const uint8_t AddressSize;<br>
+  const uint8_t SegmentDescriptorSize;<br>
+  const uint64_t CodeAlignmentFactor;<br>
+  const int64_t DataAlignmentFactor;<br>
+  const uint64_t ReturnAddressRegister;<br>
+<br>
+  // The following are used when the CIE represents an EH frame entry.<br>
+  const SmallString<8> AugmentationData;<br>
+  const uint32_t FDEPointerEncoding;<br>
+  const uint32_t LSDAPointerEncoding;<br>
+  const Optional<uint64_t> Personality;<br>
+  const Optional<uint32_t> PersonalityEnc;<br>
+};<br>
+<br>
+/// DWARF Frame Description Entry (FDE)<br>
+class FDE : public FrameEntry {<br>
+public:<br>
+  // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with<br>
+  // an offset to the CIE (provided by parsing the FDE header). The CIE itself<br>
+  // is obtained lazily once it's actually required.<br>
+  FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,<br>
+      uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,<br>
+      Optional<uint64_t> LSDAAddress)<br>
+      : FrameEntry(FK_FDE, Offset, Length,<br>
+                   Cie ? Cie->getCodeAlignmentFactor() : 0,<br>
+                   Cie ? Cie->getDataAlignmentFactor() : 0),<br>
+        LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),<br>
+        AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}<br>
+<br>
+  ~FDE() override = default;<br>
+<br>
+  const CIE *getLinkedCIE() const { return LinkedCIE; }<br>
+  uint64_t getInitialLocation() const { return InitialLocation; }<br>
+  uint64_t getAddressRange() const { return AddressRange; }<br>
+  Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }<br>
+<br>
+  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+            bool IsEH) const override;<br>
+<br>
+  static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }<br>
+<br>
+private:<br>
+  /// The following fields are defined in section 6.4.1 of the DWARF standard v3<br>
+  const uint64_t LinkedCIEOffset;<br>
+  const uint64_t InitialLocation;<br>
+  const uint64_t AddressRange;<br>
+  const CIE *LinkedCIE;<br>
+  const Optional<uint64_t> LSDAAddress;<br>
+};<br>
+<br>
+} // end namespace dwarf<br>
+<br>
+/// A parsed .debug_frame or .eh_frame section<br>
 class DWARFDebugFrame {<br>
   // True if this is parsing an eh_frame section.<br>
-  bool IsEH;<br>
+  const bool IsEH;<br>
+  // Not zero for sane pointer values coming out of eh_frame<br>
+  const uint64_t EHFrameAddress;<br>
+<br>
+  std::vector<std::unique_ptr<dwarf::FrameEntry>> Entries;<br>
+  using iterator = pointee_iterator<decltype(Entries)::const_iterator>;<br>
+<br>
+  /// Return the entry at the given offset or nullptr.<br>
+  dwarf::FrameEntry *getEntryAtOffset(uint64_t Offset) const;<br>
<br>
 public:<br>
-  DWARFDebugFrame(bool IsEH);<br>
+  // If IsEH is true, assume it is a .eh_frame section. Otherwise,<br>
+  // it is a .debug_frame section. EHFrameAddress should be different<br>
+  // than zero for correct parsing of .eh_frame addresses when they<br>
+  // use a PC-relative encoding.<br>
+  DWARFDebugFrame(bool IsEH = false, uint64_t EHFrameAddress = 0);<br>
   ~DWARFDebugFrame();<br>
<br>
   /// Dump the section data into the given stream.<br>
-  void dump(raw_ostream &OS, Optional<uint64_t> Offset) const;<br>
+  void dump(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+            Optional<uint64_t> Offset) const;<br>
<br>
-  /// \brief Parse the section from raw data.<br>
-  /// data is assumed to be pointing to the beginning of the section.<br>
-  void parse(DataExtractor Data);<br>
+  /// Parse the section from raw data. \p Data is assumed to contain the whole<br>
+  /// frame section contents to be parsed.<br>
+  void parse(DWARFDataExtractor Data);<br>
<br>
   /// Return whether the section has any entries.<br>
   bool empty() const { return Entries.empty(); }<br>
<br>
-  /// Return the entry at the given offset or nullptr.<br>
-  FrameEntry *getEntryAtOffset(uint64_t Offset) const;<br>
+  /// DWARF Frame entries accessors<br>
+  iterator begin() const { return Entries.begin(); }<br>
+  iterator end() const { return Entries.end(); }<br>
+  iterator_range<iterator> entries() const {<br>
+    return iterator_range<iterator>(Entries.begin(), Entries.end());<br>
+  }<br>
<br>
-private:<br>
-  std::vector<std::unique_ptr<FrameEntry>> Entries;<br>
+  uint64_t getEHFrameAddress() const { return EHFrameAddress; }<br>
 };<br>
<br>
 } // end namespace llvm<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_DebugInfo_DWARF_DWARFExpression.h-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=_pDNdT71sDHcRczizsvrH-YBGGCC4BPxJTbhS6-CeDo&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h Wed Mar  7 11:19:51 2018<br>
@@ -93,12 +93,13 @@ public:<br>
<br>
   /// An iterator to go through the expression operations.<br>
   class iterator<br>
-      : public iterator_facade_base<iterator, std::forward_iterator_tag, Operation> {<br>
+      : public iterator_facade_base<iterator, std::forward_iterator_tag,<br>
+                                    Operation> {<br>
     friend class DWARFExpression;<br>
-    DWARFExpression *Expr;<br>
+    const DWARFExpression *Expr;<br>
     uint32_t Offset;<br>
     Operation Op;<br>
-    iterator(DWARFExpression *Expr, uint32_t Offset)<br>
+    iterator(const DWARFExpression *Expr, uint32_t Offset)<br>
         : Expr(Expr), Offset(Offset) {<br>
       Op.Error =<br>
           Offset >= Expr->Data.getData().size() ||<br>
@@ -127,10 +128,11 @@ public:<br>
     assert(AddressSize == 8 || AddressSize == 4);<br>
   }<br>
<br>
-  iterator begin() { return iterator(this, 0); }<br>
-  iterator end() { return iterator(this, Data.getData().size()); }<br>
+  iterator begin() const { return iterator(this, 0); }<br>
+  iterator end() const { return iterator(this, Data.getData().size()); }<br>
<br>
-  void print(raw_ostream &OS, const MCRegisterInfo *RegInfo);<br>
+  void print(raw_ostream &OS, const MCRegisterInfo *RegInfo,<br>
+             bool IsEH = false) const;<br>
<br>
 private:<br>
   DataExtractor Data;<br>
<br>
Modified: llvm/trunk/include/llvm/Support/ScopedPrinter.h<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_Support_ScopedPrinter.h-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=w3W3rp8IkerupV5yW9U-31cTW2pHqVxsut4PppZNO-Q&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ScopedPrinter.h?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/ScopedPrinter.h (original)<br>
+++ llvm/trunk/include/llvm/Support/ScopedPrinter.h Wed Mar  7 11:19:51 2018<br>
@@ -80,6 +80,8 @@ public:<br>
<br>
   void resetIndent() { IndentLevel = 0; }<br>
<br>
+  int getIndentLevel() { return IndentLevel; }<br>
+<br>
   void setPrefix(StringRef P) { Prefix = P; }<br>
<br>
   void printIndent() {<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_DebugInfo_DWARF_DWARFContext.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=Nn2FkAazemaZDxB7N0nqw4l_rpB4spwrz7UQR6rHbHQ&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Mar  7 11:19:51 2018<br>
@@ -349,11 +349,11 @@ void DWARFContext::dump(<br>
<br>
   if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,<br>
                  DObj->getDebugFrameSection()))<br>
-    getDebugFrame()->dump(OS, DumpOffset);<br>
+    getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);<br>
<br>
   if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,<br>
                  DObj->getEHFrameSection()))<br>
-    getEHFrame()->dump(OS, DumpOffset);<br>
+    getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);<br>
<br>
   if (DumpType & DIDT_DebugMacro) {<br>
     if (Explicit || !getDebugMacro()->empty()) {<br>
@@ -712,8 +712,8 @@ const DWARFDebugFrame *DWARFContext::get<br>
   // provides this information). This problem is fixed in DWARFv4<br>
   // See this dwarf-discuss discussion for more details:<br>
   // </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.dwarfstd.org_htdig.cgi_dwarf-2Ddiscuss-2Ddwarfstd.org_2011-2DDecember_001173.html&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=0WOhY6-xghwdUnAZiE2xzx1-VpfE-ifA3OswZu8rAnk&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
-  DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),<br>
-                               DObj->getAddressSize());<br>
+  DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),<br>
+                                    isLittleEndian(), DObj->getAddressSize());<br>
   DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));<br>
   DebugFrame->parse(debugFrameData);<br>
   return DebugFrame.get();<br>
@@ -723,8 +723,8 @@ const DWARFDebugFrame *DWARFContext::get<br>
   if (EHFrame)<br>
     return EHFrame.get();<br>
<br>
-  DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),<br>
-                               DObj->getAddressSize());<br>
+  DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),<br>
+                                    DObj->getAddressSize());<br>
   DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));<br>
   DebugFrame->parse(debugFrameData);<br>
   return DebugFrame.get();<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_DebugInfo_DWARF_DWARFDataExtractor.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=Tu1QyBo8NJiXY_80mQ6KSfJ95O-4xemuN6iSiB5Hc5A&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp Wed Mar  7 11:19:51 2018<br>
@@ -8,6 +8,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
+#include "llvm/BinaryFormat/Dwarf.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
<br>
 using namespace llvm;<br>
@@ -25,3 +26,71 @@ uint64_t DWARFDataExtractor::getRelocate<br>
     *SecNdx = Rel->SectionIndex;<br>
   return getUnsigned(Off, Size) + Rel->Value;<br>
 }<br>
+<br>
+Optional<uint64_t><br>
+DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding,<br>
+                                      uint64_t PCRelOffset) const {<br>
+  if (Encoding == dwarf::DW_EH_PE_omit)<br>
+    return None;<br>
+<br>
+  uint64_t Result = 0;<br>
+  uint32_t OldOffset = *Offset;<br>
+  // First get value<br>
+  switch (Encoding & 0x0F) {<br>
+  case dwarf::DW_EH_PE_absptr:<br>
+    switch (getAddressSize()) {<br>
+    case 2:<br>
+    case 4:<br>
+    case 8:<br>
+      Result = getUnsigned(Offset, getAddressSize());<br>
+      break;<br>
+    default:<br>
+      return None;<br>
+    }<br>
+    break;<br>
+  case dwarf::DW_EH_PE_uleb128:<br>
+    Result = getULEB128(Offset);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_sleb128:<br>
+    Result = getSLEB128(Offset);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_udata2:<br>
+    Result = getUnsigned(Offset, 2);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_udata4:<br>
+    Result = getUnsigned(Offset, 4);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_udata8:<br>
+    Result = getUnsigned(Offset, 8);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_sdata2:<br>
+    Result = getSigned(Offset, 2);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_sdata4:<br>
+    Result = getSigned(Offset, 4);<br>
+    break;<br>
+  case dwarf::DW_EH_PE_sdata8:<br>
+    Result = getSigned(Offset, 8);<br>
+    break;<br>
+  default:<br>
+    return None;<br>
+  }<br>
+  // Then add relative offset, if required<br>
+  switch (Encoding & 0x70) {<br>
+  case dwarf::DW_EH_PE_absptr:<br>
+    // do nothing<br>
+    break;<br>
+  case dwarf::DW_EH_PE_pcrel:<br>
+    Result += PCRelOffset;<br>
+    break;<br>
+  case dwarf::DW_EH_PE_datarel:<br>
+  case dwarf::DW_EH_PE_textrel:<br>
+  case dwarf::DW_EH_PE_funcrel:<br>
+  case dwarf::DW_EH_PE_aligned:<br>
+  default:<br>
+    *Offset = OldOffset;<br>
+    return None;<br>
+  }<br>
+<br>
+  return Result;<br>
+}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_DebugInfo_DWARF_DWARFDebugFrame.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=0rUYguiuBVS__pfVAzENzTTy1DYdCz9R7IxjIGlrnd0&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp Wed Mar  7 11:19:51 2018<br>
@@ -8,10 +8,8 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"<br>
-#include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/ADT/Optional.h"<br>
-#include "llvm/ADT/SmallString.h"<br>
 #include "llvm/ADT/StringExtras.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include "llvm/BinaryFormat/Dwarf.h"<br>
@@ -31,87 +29,13 @@<br>
 using namespace llvm;<br>
 using namespace dwarf;<br>
<br>
-/// \brief Abstract frame entry defining the common interface concrete<br>
-/// entries implement.<br>
-class llvm::FrameEntry {<br>
-public:<br>
-  enum FrameKind {FK_CIE, FK_FDE};<br>
-<br>
-  FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)<br>
-      : Kind(K), Offset(Offset), Length(Length) {}<br>
-<br>
-  virtual ~FrameEntry() = default;<br>
-<br>
-  FrameKind getKind() const { return Kind; }<br>
-  virtual uint64_t getOffset() const { return Offset; }<br>
-<br>
-  /// Parse and store a sequence of CFI instructions from Data,<br>
-  /// starting at *Offset and ending at EndOffset. If everything<br>
-  /// goes well, *Offset should be equal to EndOffset when this method<br>
-  /// returns. Otherwise, an error occurred.<br>
-  virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,<br>
-                                 uint32_t EndOffset);<br>
-<br>
-  /// Dump the entry header to the given output stream.<br>
-  virtual void dumpHeader(raw_ostream &OS) const = 0;<br>
-<br>
-  /// Dump the entry's instructions to the given output stream.<br>
-  virtual void dumpInstructions(raw_ostream &OS) const;<br>
-<br>
-  /// Dump the entire entry to the given output stream.<br>
-  void dump(raw_ostream &OS) const {<br>
-    dumpHeader(OS);<br>
-    dumpInstructions(OS);<br>
-    OS << "\n";<br>
-  }<br>
-<br>
-protected:<br>
-  const FrameKind Kind;<br>
-<br>
-  /// \brief Offset of this entry in the section.<br>
-  uint64_t Offset;<br>
-<br>
-  /// \brief Entry length as specified in DWARF.<br>
-  uint64_t Length;<br>
-<br>
-  /// An entry may contain CFI instructions. An instruction consists of an<br>
-  /// opcode and an optional sequence of operands.<br>
-  using Operands = std::vector<uint64_t>;<br>
-  struct Instruction {<br>
-    Instruction(uint8_t Opcode)<br>
-      : Opcode(Opcode)<br>
-    {}<br>
-<br>
-    uint8_t Opcode;<br>
-    Operands Ops;<br>
-  };<br>
-<br>
-  std::vector<Instruction> Instructions;<br>
-<br>
-  /// Convenience methods to add a new instruction with the given opcode and<br>
-  /// operands to the Instructions vector.<br>
-  void addInstruction(uint8_t Opcode) {<br>
-    Instructions.push_back(Instruction(Opcode));<br>
-  }<br>
-<br>
-  void addInstruction(uint8_t Opcode, uint64_t Operand1) {<br>
-    Instructions.push_back(Instruction(Opcode));<br>
-    Instructions.back().Ops.push_back(Operand1);<br>
-  }<br>
-<br>
-  void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {<br>
-    Instructions.push_back(Instruction(Opcode));<br>
-    Instructions.back().Ops.push_back(Operand1);<br>
-    Instructions.back().Ops.push_back(Operand2);<br>
-  }<br>
-};<br>
<br>
 // See DWARF standard v3, section 7.23<br>
 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;<br>
 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;<br>
<br>
-void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,<br>
-                                   uint32_t EndOffset) {<br>
+Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,<br>
+                        uint32_t EndOffset) {<br>
   while (*Offset < EndOffset) {<br>
     uint8_t Opcode = Data.getU8(Offset);<br>
     // Some instructions have a primary opcode encoded in the top bits.<br>
@@ -122,67 +46,73 @@ void FrameEntry::parseInstructions(DataE<br>
       // bits of the opcode itself.<br>
       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;<br>
       switch (Primary) {<br>
-        default: llvm_unreachable("Impossible primary CFI opcode");<br>
-        case DW_CFA_advance_loc:<br>
-        case DW_CFA_restore:<br>
-          addInstruction(Primary, Op1);<br>
-          break;<br>
-        case DW_CFA_offset:<br>
-          addInstruction(Primary, Op1, Data.getULEB128(Offset));<br>
-          break;<br>
+      default:<br>
+        return make_error<StringError>(<br>
+            "Invalid primary CFI opcode",<br>
+            std::make_error_code(std::errc::illegal_byte_sequence));<br>
+      case DW_CFA_advance_loc:<br>
+      case DW_CFA_restore:<br>
+        addInstruction(Primary, Op1);<br>
+        break;<br>
+      case DW_CFA_offset:<br>
+        addInstruction(Primary, Op1, Data.getULEB128(Offset));<br>
+        break;<br>
       }<br>
     } else {<br>
       // Extended opcode - its value is Opcode itself.<br>
       switch (Opcode) {<br>
-        default: llvm_unreachable("Invalid extended CFI opcode");<br>
-        case DW_CFA_nop:<br>
-        case DW_CFA_remember_state:<br>
-        case DW_CFA_restore_state:<br>
-        case DW_CFA_GNU_window_save:<br>
-          // No operands<br>
-          addInstruction(Opcode);<br>
-          break;<br>
-        case DW_CFA_set_loc:<br>
-          // Operands: Address<br>
-          addInstruction(Opcode, Data.getAddress(Offset));<br>
-          break;<br>
-        case DW_CFA_advance_loc1:<br>
-          // Operands: 1-byte delta<br>
-          addInstruction(Opcode, Data.getU8(Offset));<br>
-          break;<br>
-        case DW_CFA_advance_loc2:<br>
-          // Operands: 2-byte delta<br>
-          addInstruction(Opcode, Data.getU16(Offset));<br>
-          break;<br>
-        case DW_CFA_advance_loc4:<br>
-          // Operands: 4-byte delta<br>
-          addInstruction(Opcode, Data.getU32(Offset));<br>
-          break;<br>
-        case DW_CFA_restore_extended:<br>
-        case DW_CFA_undefined:<br>
-        case DW_CFA_same_value:<br>
-        case DW_CFA_def_cfa_register:<br>
-        case DW_CFA_def_cfa_offset:<br>
-        case DW_CFA_GNU_args_size:<br>
-          // Operands: ULEB128<br>
-          addInstruction(Opcode, Data.getULEB128(Offset));<br>
-          break;<br>
-        case DW_CFA_def_cfa_offset_sf:<br>
-          // Operands: SLEB128<br>
-          addInstruction(Opcode, Data.getSLEB128(Offset));<br>
-          break;<br>
-        case DW_CFA_offset_extended:<br>
-        case DW_CFA_register:<br>
-        case DW_CFA_def_cfa:<br>
-        case DW_CFA_val_offset: {<br>
-          // Operands: ULEB128, ULEB128<br>
-          // Note: We can not embed getULEB128 directly into function<br>
-          // argument list. getULEB128 changes Offset and order of evaluation<br>
-          // for arguments is unspecified.<br>
-          auto op1 = Data.getULEB128(Offset);<br>
-          auto op2 = Data.getULEB128(Offset);<br>
-          addInstruction(Opcode, op1, op2);<br>
-          break;<br>
+      default:<br>
+        return make_error<StringError>(<br>
+            "Invalid extended CFI opcode",<br>
+            std::make_error_code(std::errc::illegal_byte_sequence));<br>
+      case DW_CFA_nop:<br>
+      case DW_CFA_remember_state:<br>
+      case DW_CFA_restore_state:<br>
+      case DW_CFA_GNU_window_save:<br>
+        // No operands<br>
+        addInstruction(Opcode);<br>
+        break;<br>
+      case DW_CFA_set_loc:<br>
+        // Operands: Address<br>
+        addInstruction(Opcode, Data.getAddress(Offset));<br>
+        break;<br>
+      case DW_CFA_advance_loc1:<br>
+        // Operands: 1-byte delta<br>
+        addInstruction(Opcode, Data.getU8(Offset));<br>
+        break;<br>
+      case DW_CFA_advance_loc2:<br>
+        // Operands: 2-byte delta<br>
+        addInstruction(Opcode, Data.getU16(Offset));<br>
+        break;<br>
+      case DW_CFA_advance_loc4:<br>
+        // Operands: 4-byte delta<br>
+        addInstruction(Opcode, Data.getU32(Offset));<br>
+        break;<br>
+      case DW_CFA_restore_extended:<br>
+      case DW_CFA_undefined:<br>
+      case DW_CFA_same_value:<br>
+      case DW_CFA_def_cfa_register:<br>
+      case DW_CFA_def_cfa_offset:<br>
+      case DW_CFA_GNU_args_size:<br>
+        // Operands: ULEB128<br>
+        addInstruction(Opcode, Data.getULEB128(Offset));<br>
+        break;<br>
+      case DW_CFA_def_cfa_offset_sf:<br>
+        // Operands: SLEB128<br>
+        addInstruction(Opcode, Data.getSLEB128(Offset));<br>
+        break;<br>
+      case DW_CFA_offset_extended:<br>
+      case DW_CFA_register:<br>
+      case DW_CFA_def_cfa:<br>
+      case DW_CFA_val_offset: {<br>
+        // Operands: ULEB128, ULEB128<br>
+        // Note: We can not embed getULEB128 directly into function<br>
+        // argument list. getULEB128 changes Offset and order of evaluation<br>
+        // for arguments is unspecified.<br>
+        auto op1 = Data.getULEB128(Offset);<br>
+        auto op2 = Data.getULEB128(Offset);<br>
+        addInstruction(Opcode, op1, op2);<br>
+        break;<br>
         }<br>
         case DW_CFA_offset_extended_sf:<br>
         case DW_CFA_def_cfa_sf:<br>
@@ -194,162 +124,49 @@ void FrameEntry::parseInstructions(DataE<br>
           addInstruction(Opcode, op1, op2);<br>
           break;<br>
         }<br>
-        case DW_CFA_def_cfa_expression:<br>
-          // FIXME: Parse the actual instruction.<br>
-          *Offset += Data.getULEB128(Offset);<br>
+        case DW_CFA_def_cfa_expression: {<br>
+          uint32_t ExprLength = Data.getULEB128(Offset);<br>
+          addInstruction(Opcode, 0);<br>
+          DataExtractor Extractor(<br>
+              Data.getData().slice(*Offset, *Offset + ExprLength),<br>
+              Data.isLittleEndian(), Data.getAddressSize());<br>
+          Instructions.back().Expression = DWARFExpression(<br>
+              Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);<br>
+          *Offset += ExprLength;<br>
           break;<br>
+        }<br>
         case DW_CFA_expression:<br>
         case DW_CFA_val_expression: {<br>
-          // FIXME: Parse the actual instruction.<br>
-          Data.getULEB128(Offset);<br>
-          *Offset += Data.getULEB128(Offset);<br>
+          auto RegNum = Data.getULEB128(Offset);<br>
+          auto BlockLength = Data.getULEB128(Offset);<br>
+          addInstruction(Opcode, RegNum, 0);<br>
+          DataExtractor Extractor(<br>
+              Data.getData().slice(*Offset, *Offset + BlockLength),<br>
+              Data.isLittleEndian(), Data.getAddressSize());<br>
+          Instructions.back().Expression = DWARFExpression(<br>
+              Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);<br>
+          *Offset += BlockLength;<br>
           break;<br>
         }<br>
       }<br>
     }<br>
   }<br>
+<br>
+  return Error::success();<br>
 }<br>
<br>
 namespace {<br>
<br>
-/// \brief DWARF Common Information Entry (CIE)<br>
-class CIE : public FrameEntry {<br>
-public:<br>
-  // CIEs (and FDEs) are simply container classes, so the only sensible way to<br>
-  // create them is by providing the full parsed contents in the constructor.<br>
-  CIE(uint64_t Offset, uint64_t Length, uint8_t Version,<br>
-      SmallString<8> Augmentation, uint8_t AddressSize,<br>
-      uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,<br>
-      int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,<br>
-      SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,<br>
-      uint32_t LSDAPointerEncoding)<br>
-      : FrameEntry(FK_CIE, Offset, Length), Version(Version),<br>
-        Augmentation(std::move(Augmentation)), AddressSize(AddressSize),<br>
-        SegmentDescriptorSize(SegmentDescriptorSize),<br>
-        CodeAlignmentFactor(CodeAlignmentFactor),<br>
-        DataAlignmentFactor(DataAlignmentFactor),<br>
-        ReturnAddressRegister(ReturnAddressRegister),<br>
-        AugmentationData(std::move(AugmentationData)),<br>
-        FDEPointerEncoding(FDEPointerEncoding),<br>
-        LSDAPointerEncoding(LSDAPointerEncoding) {}<br>
-<br>
-  ~CIE() override = default;<br>
-<br>
-  StringRef getAugmentationString() const { return Augmentation; }<br>
-  uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }<br>
-  int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }<br>
-<br>
-  uint32_t getFDEPointerEncoding() const {<br>
-    return FDEPointerEncoding;<br>
-  }<br>
-<br>
-  uint32_t getLSDAPointerEncoding() const {<br>
-    return LSDAPointerEncoding;<br>
-  }<br>
-<br>
-  void dumpHeader(raw_ostream &OS) const override {<br>
-    OS << format("%08x %08x %08x CIE",<br>
-                 (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)<br>
-       << "\n";<br>
-    OS << format("  Version:               %d\n", Version);<br>
-    OS << "  Augmentation:          \"" << Augmentation << "\"\n";<br>
-    if (Version >= 4) {<br>
-      OS << format("  Address size:          %u\n",<br>
-                   (uint32_t)AddressSize);<br>
-      OS << format("  Segment desc size:     %u\n",<br>
-                   (uint32_t)SegmentDescriptorSize);<br>
-    }<br>
-    OS << format("  Code alignment factor: %u\n",<br>
-                 (uint32_t)CodeAlignmentFactor);<br>
-    OS << format("  Data alignment factor: %d\n",<br>
-                 (int32_t)DataAlignmentFactor);<br>
-    OS << format("  Return address column: %d\n",<br>
-                 (int32_t)ReturnAddressRegister);<br>
-    if (!AugmentationData.empty()) {<br>
-      OS << "  Augmentation data:    ";<br>
-      for (uint8_t Byte : AugmentationData)<br>
-        OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);<br>
-      OS << "\n";<br>
-    }<br>
-    OS << "\n";<br>
-  }<br>
-<br>
-  static bool classof(const FrameEntry *FE) {<br>
-    return FE->getKind() == FK_CIE;<br>
-  }<br>
-<br>
-private:<br>
-  /// The following fields are defined in section 6.4.1 of the DWARF standard v4<br>
-  uint8_t Version;<br>
-  SmallString<8> Augmentation;<br>
-  uint8_t AddressSize;<br>
-  uint8_t SegmentDescriptorSize;<br>
-  uint64_t CodeAlignmentFactor;<br>
-  int64_t DataAlignmentFactor;<br>
-  uint64_t ReturnAddressRegister;<br>
-<br>
-  // The following are used when the CIE represents an EH frame entry.<br>
-  SmallString<8> AugmentationData;<br>
-  uint32_t FDEPointerEncoding;<br>
-  uint32_t LSDAPointerEncoding;<br>
-};<br>
-<br>
-/// \brief DWARF Frame Description Entry (FDE)<br>
-class FDE : public FrameEntry {<br>
-public:<br>
-  // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with<br>
-  // an offset to the CIE (provided by parsing the FDE header). The CIE itself<br>
-  // is obtained lazily once it's actually required.<br>
-  FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,<br>
-      uint64_t InitialLocation, uint64_t AddressRange,<br>
-      CIE *Cie)<br>
-      : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),<br>
-        InitialLocation(InitialLocation), AddressRange(AddressRange),<br>
-        LinkedCIE(Cie) {}<br>
-<br>
-  ~FDE() override = default;<br>
-<br>
-  CIE *getLinkedCIE() const { return LinkedCIE; }<br>
-<br>
-  void dumpHeader(raw_ostream &OS) const override {<br>
-    OS << format("%08x %08x %08x FDE ",<br>
-                 (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);<br>
-    OS << format("cie=%08x pc=%08x...%08x\n",<br>
-                 (int32_t)LinkedCIEOffset,<br>
-                 (uint32_t)InitialLocation,<br>
-                 (uint32_t)InitialLocation + (uint32_t)AddressRange);<br>
-  }<br>
-<br>
-  static bool classof(const FrameEntry *FE) {<br>
-    return FE->getKind() == FK_FDE;<br>
-  }<br>
-<br>
-private:<br>
-  /// The following fields are defined in section 6.4.1 of the DWARF standard v3<br>
-  uint64_t LinkedCIEOffset;<br>
-  uint64_t InitialLocation;<br>
-  uint64_t AddressRange;<br>
-  CIE *LinkedCIE;<br>
-};<br>
-<br>
-/// \brief Types of operands to CF instructions.<br>
-enum OperandType {<br>
-  OT_Unset,<br>
-  OT_None,<br>
-  OT_Address,<br>
-  OT_Offset,<br>
-  OT_FactoredCodeOffset,<br>
-  OT_SignedFactDataOffset,<br>
-  OT_UnsignedFactDataOffset,<br>
-  OT_Register,<br>
-  OT_Expression<br>
-};<br>
<br>
 } // end anonymous namespace<br>
<br>
-/// \brief Initialize the array describing the types of operands.<br>
-static ArrayRef<OperandType[2]> getOperandTypes() {<br>
+ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {<br>
   static OperandType OpTypes[DW_CFA_restore+1][2];<br>
+  static bool Initialized = false;<br>
+  if (Initialized) {<br>
+    return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);<br>
+  }<br>
+  Initialized = true;<br>
<br>
 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \<br>
   do {                                          \<br>
@@ -396,15 +213,13 @@ static ArrayRef<OperandType[2]> getOpera<br>
   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);<br>
 }<br>
<br>
-static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();<br>
-<br>
-/// \brief Print \p Opcode's operand number \p OperandIdx which has<br>
-/// value \p Operand.<br>
-static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,<br>
-                         uint64_t Operand, uint64_t CodeAlignmentFactor,<br>
-                         int64_t DataAlignmentFactor) {<br>
+/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.<br>
+void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+                              bool IsEH, const Instruction &Instr,<br>
+                              unsigned OperandIdx, uint64_t Operand) const {<br>
   assert(OperandIdx < 2);<br>
-  OperandType Type = OpTypes[Opcode][OperandIdx];<br>
+  uint8_t Opcode = Instr.Opcode;<br>
+  OperandType Type = getOperandTypes()[Opcode][OperandIdx];<br>
<br>
   switch (Type) {<br>
   case OT_Unset: {<br>
@@ -449,36 +264,68 @@ static void printOperand(raw_ostream &OS<br>
     OS << format(" reg%" PRId64, Operand);<br>
     break;<br>
   case OT_Expression:<br>
-    OS << " expression";<br>
+    assert(Instr.Expression && "missing DWARFExpression object");<br>
+    OS << " ";<br>
+    Instr.Expression->print(OS, MRI, IsEH);<br>
     break;<br>
   }<br>
 }<br>
<br>
-void FrameEntry::dumpInstructions(raw_ostream &OS) const {<br>
-  uint64_t CodeAlignmentFactor = 0;<br>
-  int64_t DataAlignmentFactor = 0;<br>
-  const CIE *Cie = dyn_cast<CIE>(this);<br>
-<br>
-  if (!Cie)<br>
-    Cie = cast<FDE>(this)->getLinkedCIE();<br>
-  if (Cie) {<br>
-    CodeAlignmentFactor = Cie->getCodeAlignmentFactor();<br>
-    DataAlignmentFactor = Cie->getDataAlignmentFactor();<br>
-  }<br>
-<br>
+void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,<br>
+                      unsigned IndentLevel) const {<br>
   for (const auto &Instr : Instructions) {<br>
     uint8_t Opcode = Instr.Opcode;<br>
     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)<br>
       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;<br>
-    OS << "  " << CallFrameString(Opcode) << ":";<br>
+    OS.indent(2 * IndentLevel);<br>
+    OS << CallFrameString(Opcode) << ":";<br>
     for (unsigned i = 0; i < Instr.Ops.size(); ++i)<br>
-      printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,<br>
-                   DataAlignmentFactor);<br>
+      printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);<br>
     OS << '\n';<br>
   }<br>
 }<br>
<br>
-DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {}<br>
+void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {<br>
+  OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length,<br>
+               DW_CIE_ID)<br>
+     << "\n";<br>
+  OS << format("  Version:               %d\n", Version);<br>
+  OS << "  Augmentation:          \"" << Augmentation << "\"\n";<br>
+  if (Version >= 4) {<br>
+    OS << format("  Address size:          %u\n", (uint32_t)AddressSize);<br>
+    OS << format("  Segment desc size:     %u\n",<br>
+                 (uint32_t)SegmentDescriptorSize);<br>
+  }<br>
+  OS << format("  Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);<br>
+  OS << format("  Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);<br>
+  OS << format("  Return address column: %d\n", (int32_t)ReturnAddressRegister);<br>
+  if (Personality)<br>
+    OS << format("  Personality Address: %08x\n", *Personality);<br>
+  if (!AugmentationData.empty()) {<br>
+    OS << "  Augmentation data:    ";<br>
+    for (uint8_t Byte : AugmentationData)<br>
+      OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);<br>
+    OS << "\n";<br>
+  }<br>
+  OS << "\n";<br>
+  CFIs.dump(OS, MRI, IsEH);<br>
+  OS << "\n";<br>
+}<br>
+<br>
+void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {<br>
+  OS << format("%08x %08x %08x FDE ", (uint32_t)Offset, (uint32_t)Length,<br>
+               (int32_t)LinkedCIEOffset);<br>
+  OS << format("cie=%08x pc=%08x...%08x\n", (int32_t)LinkedCIEOffset,<br>
+               (uint32_t)InitialLocation,<br>
+               (uint32_t)InitialLocation + (uint32_t)AddressRange);<br>
+  if (LSDAAddress)<br>
+    OS << format("  LSDA Address: %08x\n", *LSDAAddress);<br>
+  CFIs.dump(OS, MRI, IsEH);<br>
+  OS << "\n";<br>
+}<br>
+<br>
+DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)<br>
+    : IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}<br>
<br>
 DWARFDebugFrame::~DWARFDebugFrame() = default;<br>
<br>
@@ -492,40 +339,6 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDa<br>
   errs() << "\n";<br>
 }<br>
<br>
-static unsigned getSizeForEncoding(const DataExtractor &Data,<br>
-                                   unsigned symbolEncoding) {<br>
-  unsigned format = symbolEncoding & 0x0f;<br>
-  switch (format) {<br>
-    default: llvm_unreachable("Unknown Encoding");<br>
-    case DW_EH_PE_absptr:<br>
-    case DW_EH_PE_signed:<br>
-      return Data.getAddressSize();<br>
-    case DW_EH_PE_udata2:<br>
-    case DW_EH_PE_sdata2:<br>
-      return 2;<br>
-    case DW_EH_PE_udata4:<br>
-    case DW_EH_PE_sdata4:<br>
-      return 4;<br>
-    case DW_EH_PE_udata8:<br>
-    case DW_EH_PE_sdata8:<br>
-      return 8;<br>
-  }<br>
-}<br>
-<br>
-static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,<br>
-                            unsigned Encoding) {<br>
-  switch (getSizeForEncoding(Data, Encoding)) {<br>
-    case 2:<br>
-      return Data.getU16(&Offset);<br>
-    case 4:<br>
-      return Data.getU32(&Offset);<br>
-    case 8:<br>
-      return Data.getU64(&Offset);<br>
-    default:<br>
-      llvm_unreachable("Illegal data size");<br>
-  }<br>
-}<br>
-<br>
 // This is a workaround for old compilers which do not allow<br>
 // noreturn attribute usage in lambdas. Once the support for those<br>
 // compilers are phased out, we can remove this and return back to<br>
@@ -539,7 +352,7 @@ static void LLVM_ATTRIBUTE_NORETURN Repo<br>
   report_fatal_error(Str);<br>
 }<br>
<br>
-void DWARFDebugFrame::parse(DataExtractor Data) {<br>
+void DWARFDebugFrame::parse(DWARFDataExtractor Data) {<br>
   uint32_t Offset = 0;<br>
   DenseMap<uint32_t, CIE *> CIEs;<br>
<br>
@@ -569,9 +382,8 @@ void DWARFDebugFrame::parse(DataExtracto<br>
<br>
     // The Id field's size depends on the DWARF format<br>
     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);<br>
-    bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||<br>
-                  Id == DW_CIE_ID ||<br>
-                  (IsEH && !Id));<br>
+    bool IsCIE =<br>
+        ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID || (IsEH && !Id));<br>
<br>
     if (IsCIE) {<br>
       uint8_t Version = Data.getU8(&Offset);<br>
@@ -589,10 +401,9 @@ void DWARFDebugFrame::parse(DataExtracto<br>
       StringRef AugmentationData("");<br>
       uint32_t FDEPointerEncoding = DW_EH_PE_omit;<br>
       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;<br>
+      Optional<uint64_t> Personality;<br>
+      Optional<uint32_t> PersonalityEncoding;<br>
       if (IsEH) {<br>
-        Optional<uint32_t> PersonalityEncoding;<br>
-        Optional<uint64_t> Personality;<br>
-<br>
         Optional<uint64_t> AugmentationLength;<br>
         uint32_t StartAugmentationOffset;<br>
         uint32_t EndAugmentationOffset;<br>
@@ -611,7 +422,9 @@ void DWARFDebugFrame::parse(DataExtracto<br>
                 ReportError(StartOffset,<br>
                             "Duplicate personality in entry at %lx");<br>
               PersonalityEncoding = Data.getU8(&Offset);<br>
-              Personality = readPointer(Data, Offset, *PersonalityEncoding);<br>
+              Personality = Data.getEncodedPointer(<br>
+                  &Offset, *PersonalityEncoding,<br>
+                  EHFrameAddress ? EHFrameAddress + Offset : 0);<br>
               break;<br>
             }<br>
             case 'R':<br>
@@ -639,14 +452,11 @@ void DWARFDebugFrame::parse(DataExtracto<br>
         }<br>
       }<br>
<br>
-      auto Cie = llvm::make_unique<CIE>(StartOffset, Length, Version,<br>
-                                        AugmentationString, AddressSize,<br>
-                                        SegmentDescriptorSize,<br>
-                                        CodeAlignmentFactor,<br>
-                                        DataAlignmentFactor,<br>
-                                        ReturnAddressRegister,<br>
-                                        AugmentationData, FDEPointerEncoding,<br>
-                                        LSDAPointerEncoding);<br>
+      auto Cie = llvm::make_unique<CIE>(<br>
+          StartOffset, Length, Version, AugmentationString, AddressSize,<br>
+          SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,<br>
+          ReturnAddressRegister, AugmentationData, FDEPointerEncoding,<br>
+          LSDAPointerEncoding, Personality, PersonalityEncoding);<br>
       CIEs[StartOffset] = Cie.get();<br>
       Entries.emplace_back(std::move(Cie));<br>
     } else {<br>
@@ -654,6 +464,7 @@ void DWARFDebugFrame::parse(DataExtracto<br>
       uint64_t CIEPointer = Id;<br>
       uint64_t InitialLocation = 0;<br>
       uint64_t AddressRange = 0;<br>
+      Optional<uint64_t> LSDAAddress;<br>
       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];<br>
<br>
       if (IsEH) {<br>
@@ -662,10 +473,15 @@ void DWARFDebugFrame::parse(DataExtracto<br>
           ReportError(StartOffset,<br>
                       "Parsing FDE data at %lx failed due to missing CIE");<br>
<br>
-        InitialLocation = readPointer(Data, Offset,<br>
-                                      Cie->getFDEPointerEncoding());<br>
-        AddressRange = readPointer(Data, Offset,<br>
-                                   Cie->getFDEPointerEncoding());<br>
+        if (auto Val = Data.getEncodedPointer(<br>
+                &Offset, Cie->getFDEPointerEncoding(),<br>
+                EHFrameAddress ? EHFrameAddress + Offset : 0)) {<br>
+          InitialLocation = *Val;<br>
+        }<br>
+        if (auto Val = Data.getEncodedPointer(<br>
+                &Offset, Cie->getFDEPointerEncoding(), 0)) {<br>
+          AddressRange = *Val;<br>
+        }<br>
<br>
         StringRef AugmentationString = Cie->getAugmentationString();<br>
         if (!AugmentationString.empty()) {<br>
@@ -676,8 +492,11 @@ void DWARFDebugFrame::parse(DataExtracto<br>
             Offset + static_cast<uint32_t>(AugmentationLength);<br>
<br>
           // Decode the LSDA if the CIE augmentation string said we should.<br>
-          if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)<br>
-            readPointer(Data, Offset, Cie->getLSDAPointerEncoding());<br>
+          if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {<br>
+            LSDAAddress = Data.getEncodedPointer(<br>
+                &Offset, Cie->getLSDAPointerEncoding(),<br>
+                EHFrameAddress ? Offset + EHFrameAddress : 0);<br>
+          }<br>
<br>
           if (Offset != EndAugmentationOffset)<br>
             ReportError(StartOffset, "Parsing augmentation data at %lx failed");<br>
@@ -689,10 +508,13 @@ void DWARFDebugFrame::parse(DataExtracto<br>
<br>
       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,<br>
                                    InitialLocation, AddressRange,<br>
-                                   Cie));<br>
+                                   Cie, LSDAAddress));<br>
     }<br>
<br>
-    Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);<br>
+    if (Error E =<br>
+            Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset)) {<br>
+      report_fatal_error(toString(std::move(E)));<br>
+    }<br>
<br>
     if (Offset != EndStructureOffset)<br>
       ReportError(StartOffset, "Parsing entry instructions at %lx failed");<br>
@@ -709,14 +531,15 @@ FrameEntry *DWARFDebugFrame::getEntryAtO<br>
   return nullptr;<br>
 }<br>
<br>
-void DWARFDebugFrame::dump(raw_ostream &OS, Optional<uint64_t> Offset) const {<br>
+void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,<br>
+                           Optional<uint64_t> Offset) const {<br>
   if (Offset) {<br>
     if (auto *Entry = getEntryAtOffset(*Offset))<br>
-      Entry->dump(OS);<br>
+      Entry->dump(OS, MRI, IsEH);<br>
     return;<br>
   }<br>
<br>
   OS << "\n";<br>
   for (const auto &Entry : Entries)<br>
-    Entry->dump(OS);<br>
+    Entry->dump(OS, MRI, IsEH);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_DebugInfo_DWARF_DWARFExpression.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=1KCno-6FiWH4cMtzG9SNYSxfM25rP5Ky7xwfFEKVOSo&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp Wed Mar  7 11:19:51 2018<br>
@@ -258,9 +258,10 @@ bool DWARFExpression::Operation::print(r<br>
   return true;<br>
 }<br>
<br>
-void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo) {<br>
+void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,<br>
+                            bool IsEH) const {<br>
   for (auto &Op : *this) {<br>
-    if (!Op.print(OS, this, RegInfo, /* isEH */ false)) {<br>
+    if (!Op.print(OS, this, RegInfo, IsEH)) {<br>
       uint32_t FailOffset = Op.getEndOffset();<br>
       while (FailOffset < Data.getData().size())<br>
         OS << format(" %02x", Data.getU8(&FailOffset));<br>
<br>
Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_ObjectYAML_ELFYAML.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=P6Oq8-vesYg2Kh9fo1DsvD6Ypjr_K10FnP9aZfiwQCY&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)<br>
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Wed Mar  7 11:19:51 2018<br>
@@ -50,6 +50,7 @@ void ScalarEnumerationTraits<ELFYAML::EL<br>
   ECase(PT_SHLIB);<br>
   ECase(PT_PHDR);<br>
   ECase(PT_TLS);<br>
+  ECase(PT_GNU_EH_FRAME);<br>
 #undef ECase<br>
   IO.enumFallback<Hex32>(Value);<br>
 }<br>
<br>
Added: llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_llvm-2Dreadobj_Inputs_dwarf-2Dexprs.exe-2Dx86-2D64.yaml-3Frev-3D326932-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=9ie5_Cl9nLG6VsRu1VgWqfxT9AmdFlYUJ6eXgcrKbNE&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml?rev=326932&view=auto</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml (added)<br>
+++ llvm/trunk/test/tools/llvm-readobj/Inputs/dwarf-exprs.exe-x86-64.yaml Wed Mar  7 11:19:51 2018<br>
@@ -0,0 +1,46 @@<br>
+--- !ELF<br>
+FileHeader:<br>
+  Class:           ELFCLASS64<br>
+  Data:            ELFDATA2LSB<br>
+  Type:            ET_EXEC<br>
+  Machine:         EM_X86_64<br>
+  Entry:           0x0000000000400000<br>
+Sections:<br>
+  - Name:            .text<br>
+    Type:            SHT_PROGBITS<br>
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]<br>
+    Address:         0x0000000000400000<br>
+    AddressAlign:    16<br>
+    Content:         50C704240020400031C05AC3<br>
+  - Name:            .eh_frame_hdr<br>
+    Type:            SHT_PROGBITS<br>
+    Flags:           [ SHF_ALLOC ]<br>
+    Address:         0x00000000004013c0<br>
+    AddressAlign:    4<br>
+    Content:         011B033B3C00000006000000E0F0FFFF8800000010F1FFFF58000000F6F1FFFFB000000010F2FFFFD000000090FEFFFF0001000000FFFFFF30010000<br>
+  - Name:            .eh_frame<br>
+    Type:            SHT_PROGBITS<br>
+    Flags:           [ SHF_ALLOC ]<br>
+    Address:         0x0000000000401400<br>
+    AddressAlign:    8<br>
+    Content:         1400000000000000017A5200017810011B0C070890010710140000001C000000B0F0FFFF2A00000000000000000000001400000000000000017A5200017810011B0C070890010000240000001C00000050F0FFFF20000000000E10460E184A0F0B770880003F1A3B2A332422000000001C000000440000003EF1FFFF1000000000410E108602430D064B0C07080000002C0000006400000038F1FFFF7F0C000000450C0A00491006027600450F0376780603660C0C0A00450C070800000000002C0000009400000088FDFFFF6600000000410E108602430D06428F03458E04478D058C06488307024B0C07080000000014000000C4000000C8FDFFFF01000000000000000000000000000000<br>
+Symbols:<br>
+  Global:<br>
+    - Name:            myfunc<br>
+      Type:            STT_FUNC<br>
+      Section:         .text<br>
+      Value:           0x0000000000400000<br>
+ProgramHeaders:<br>
+  - Type: PT_LOAD<br>
+    Flags: [ PF_X, PF_R ]<br>
+    VAddr: 0x00400000<br>
+    PAddr: 0x00400000<br>
+    Sections:<br>
+      - Section: .text<br>
+  - Type: PT_GNU_EH_FRAME<br>
+    Flags: [ PF_X, PF_R ]<br>
+    VAddr: 0x004013C0<br>
+    PAddr: 0x004013C0<br>
+    Sections:<br>
+      - Section: .eh_frame_hdr<br>
+...<br>
<br>
Added: llvm/trunk/test/tools/llvm-readobj/unwind.test<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_tools_llvm-2Dreadobj_unwind.test-3Frev-3D326932-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=3HEkDEO0SS6aO5oiv6aqNBD0L7dckPAPqPJzpi1pVrU&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/unwind.test?rev=326932&view=auto</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-readobj/unwind.test (added)<br>
+++ llvm/trunk/test/tools/llvm-readobj/unwind.test Wed Mar  7 11:19:51 2018<br>
@@ -0,0 +1,170 @@<br>
+RUN: yaml2obj %p/Inputs/dwarf-exprs.exe-x86-64.yaml > %t.exe<br>
+RUN: llvm-readobj -unwind %t.exe | FileCheck %s<br>
+<br>
+CHECK:      EH_FRAME Header [<br>
+CHECK-NEXT:  Address: 0x4013c0<br>
+CHECK-NEXT:  Offset: 0x27c<br>
+CHECK-NEXT:  Size: 0x3c<br>
+CHECK-NEXT:  Corresponding Section: .eh_frame_hdr<br>
+CHECK-NEXT:  Header {<br>
+CHECK-NEXT:    version: 1<br>
+CHECK-NEXT:    eh_frame_ptr_enc: 0x1b<br>
+CHECK-NEXT:    fde_count_enc: 0x3<br>
+CHECK-NEXT:    table_enc: 0x3b<br>
+CHECK-NEXT:    eh_frame_ptr: 0x401400<br>
+CHECK-NEXT:    fde_count: 6<br>
+CHECK-NEXT:    entry 0 {<br>
+CHECK-NEXT:      initial_location: 0x4004a0<br>
+CHECK-NEXT:      address: 0x401448<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:    entry 1 {<br>
+CHECK-NEXT:      initial_location: 0x4004d0<br>
+CHECK-NEXT:      address: 0x401418<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:    entry 2 {<br>
+CHECK-NEXT:      initial_location: 0x4005b6<br>
+CHECK-NEXT:      address: 0x401470<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:    entry 3 {<br>
+CHECK-NEXT:      initial_location: 0x4005d0<br>
+CHECK-NEXT:      address: 0x401490<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:    entry 4 {<br>
+CHECK-NEXT:      initial_location: 0x401250<br>
+CHECK-NEXT:      address: 0x4014c0<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:    entry 5 {<br>
+CHECK-NEXT:      initial_location: 0x4012c0<br>
+CHECK-NEXT:      address: 0x4014f0<br>
+CHECK-NEXT:    }<br>
+CHECK-NEXT:  }<br>
+CHECK-NEXT:]<br>
+<br>
+CHECK:      .eh_frame section at offset 0x2b8 address 0x401400:<br>
+CHECK-NEXT:  [0x401400] CIE length=20<br>
+CHECK-NEXT:    version: 1<br>
+CHECK-NEXT:    augmentation: zR<br>
+CHECK-NEXT:    code_alignment_factor: 1<br>
+CHECK-NEXT:    data_alignment_factor: -8<br>
+CHECK-NEXT:    return_address_register: 16<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg7 +8<br>
+CHECK-NEXT:      DW_CFA_offset: reg16 -8<br>
+CHECK-NEXT:      DW_CFA_undefined: reg16<br>
+<br>
+CHECK:       [0x401418] FDE length=20 cie=[0x401400]<br>
+CHECK-NEXT:    initial_location: 0x4004d0<br>
+CHECK-NEXT:    address_range: 0x2a (end : 0x4004fa)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x401430] CIE length=20<br>
+CHECK-NEXT:    version: 1<br>
+CHECK-NEXT:    augmentation: zR<br>
+CHECK-NEXT:    code_alignment_factor: 1<br>
+CHECK-NEXT:    data_alignment_factor: -8<br>
+CHECK-NEXT:    return_address_register: 16<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg7 +8<br>
+CHECK-NEXT:      DW_CFA_offset: reg16 -8<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x401448] FDE length=36 cie=[0x401430]<br>
+CHECK-NEXT:    initial_location: 0x4004a0<br>
+CHECK-NEXT:    address_range: 0x20 (end : 0x4004c0)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_def_cfa_offset: +16<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 6<br>
+CHECK-NEXT:      DW_CFA_def_cfa_offset: +24<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 10<br>
+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<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x401470] FDE length=28 cie=[0x401430]<br>
+CHECK-NEXT:    initial_location: 0x4005b6<br>
+CHECK-NEXT:    address_range: 0x10 (end : 0x4005c6)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 1<br>
+CHECK-NEXT:      DW_CFA_def_cfa_offset: +16<br>
+CHECK-NEXT:      DW_CFA_offset: reg6 -16<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 3<br>
+CHECK-NEXT:      DW_CFA_def_cfa_register: reg6<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 11<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg7 +8<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x401490] FDE length=44 cie=[0x401430]<br>
+CHECK-NEXT:    initial_location: 0x4005d0<br>
+CHECK-NEXT:    address_range: 0xc7f (end : 0x40124f)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 5<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg10 +0<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 9<br>
+CHECK-NEXT:      DW_CFA_expression: reg6 DW_OP_breg6 +0<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 5<br>
+CHECK-NEXT:      DW_CFA_def_cfa_expression: DW_OP_breg6 -8, DW_OP_deref<br>
+CHECK-NEXT:      DW_CFA_advance_loc2: 3174<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg10 +0<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 5<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg7 +8<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x4014c0] FDE length=44 cie=[0x401430]<br>
+CHECK-NEXT:    initial_location: 0x401250<br>
+CHECK-NEXT:    address_range: 0x66 (end : 0x4012b6)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 1<br>
+CHECK-NEXT:      DW_CFA_def_cfa_offset: +16<br>
+CHECK-NEXT:      DW_CFA_offset: reg6 -16<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 3<br>
+CHECK-NEXT:      DW_CFA_def_cfa_register: reg6<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 2<br>
+CHECK-NEXT:      DW_CFA_offset: reg15 -24<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 5<br>
+CHECK-NEXT:      DW_CFA_offset: reg14 -32<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 7<br>
+CHECK-NEXT:      DW_CFA_offset: reg13 -40<br>
+CHECK-NEXT:      DW_CFA_offset: reg12 -48<br>
+CHECK-NEXT:      DW_CFA_advance_loc: 8<br>
+CHECK-NEXT:      DW_CFA_offset: reg3 -56<br>
+CHECK-NEXT:      DW_CFA_advance_loc1: 75<br>
+CHECK-NEXT:      DW_CFA_def_cfa: reg7 +8<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+<br>
+CHECK:       [0x4014f0] FDE length=20 cie=[0x401430]<br>
+CHECK-NEXT:    initial_location: 0x4012c0<br>
+CHECK-NEXT:    address_range: 0x1 (end : 0x4012c1)<br>
+<br>
+CHECK:         Program:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
+CHECK-NEXT:      DW_CFA_nop:<br>
<br>
Modified: llvm/trunk/tools/llvm-readobj/CMakeLists.txt<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_llvm-2Dreadobj_CMakeLists.txt-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=s7959hjlgLewujjVoNZ67799P5w_nKadrB_H9Ps-tgY&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CMakeLists.txt?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-readobj/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/llvm-readobj/CMakeLists.txt Wed Mar  7 11:19:51 2018<br>
@@ -1,5 +1,6 @@<br>
 set(LLVM_LINK_COMPONENTS<br>
   DebugInfoCodeView<br>
+  DebugInfoDWARF<br>
   Object<br>
   BinaryFormat<br>
   Support<br>
<br>
Added: llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_llvm-2Dreadobj_DwarfCFIEHPrinter.h-3Frev-3D326932-26view-3Dauto&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=tcB6Mk-ZjzEj56j2PErxziJLxj0VrQcW9XIyAeIHtzs&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h?rev=326932&view=auto</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h (added)<br>
+++ llvm/trunk/tools/llvm-readobj/DwarfCFIEHPrinter.h Wed Mar  7 11:19:51 2018<br>
@@ -0,0 +1,244 @@<br>
+//===--- DwarfCFIEHPrinter.h - DWARF-based Unwind Information Printer -----===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H<br>
+#define LLVM_TOOLS_LLVM_READOBJ_DWARFCFIEHPRINTER_H<br>
+<br>
+#include "Error.h"<br>
+#include "llvm/ADT/STLExtras.h"<br>
+#include "llvm/BinaryFormat/Dwarf.h"<br>
+#include "llvm/Object/ELF.h"<br>
+#include "llvm/Object/ELFTypes.h"<br>
+#include "llvm/Support/Casting.h"<br>
+#include "llvm/Support/ScopedPrinter.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"<br>
+#include "llvm/Support/Endian.h"<br>
+#include "llvm/Support/Format.h"<br>
+#include "llvm/Support/type_traits.h"<br>
+<br>
+namespace llvm {<br>
+namespace DwarfCFIEH {<br>
+<br>
+template <typename ELFT><br>
+class PrinterContext {<br>
+  ScopedPrinter &W;<br>
+  const object::ELFFile<ELFT> *Obj;<br>
+<br>
+  void printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;<br>
+<br>
+  void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;<br>
+<br>
+public:<br>
+  PrinterContext(ScopedPrinter &W, const object::ELFFile<ELFT> *Obj)<br>
+      : W(W), Obj(Obj) {}<br>
+<br>
+  void printUnwindInformation() const;<br>
+};<br>
+<br>
+template <class ELFO><br>
+static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,<br>
+                                                           uint64_t Addr) {<br>
+  auto Sections = Obj->sections();<br>
+  if (Error E = Sections.takeError())<br>
+    reportError(toString(std::move(E)));<br>
+<br>
+  for (const auto &Shdr : *Sections)<br>
+    if (Shdr.sh_addr == Addr)<br>
+      return &Shdr;<br>
+  return nullptr;<br>
+}<br>
+<br>
+template <typename ELFT><br>
+void PrinterContext<ELFT>::printUnwindInformation() const {<br>
+  const typename ELFT::Phdr *EHFramePhdr = nullptr;<br>
+<br>
+  auto PHs = Obj->program_headers();<br>
+  if (Error E = PHs.takeError())<br>
+    reportError(toString(std::move(E)));<br>
+<br>
+  for (const auto &Phdr : *PHs) {<br>
+    if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {<br>
+      EHFramePhdr = &Phdr;<br>
+      if (Phdr.p_memsz != Phdr.p_filesz)<br>
+        reportError("p_memsz does not match p_filesz for GNU_EH_FRAME");<br>
+      break;<br>
+    }<br>
+  }<br>
+<br>
+  if (EHFramePhdr)<br>
+    printEHFrameHdr(EHFramePhdr->p_offset, EHFramePhdr->p_vaddr,<br>
+                    EHFramePhdr->p_memsz);<br>
+<br>
+  auto Sections = Obj->sections();<br>
+  if (Error E = Sections.takeError())<br>
+    reportError(toString(std::move(E)));<br>
+<br>
+  for (const auto &Shdr : *Sections) {<br>
+    auto SectionName = Obj->getSectionName(&Shdr);<br>
+    if (Error E = SectionName.takeError())<br>
+      reportError(toString(std::move(E)));<br>
+<br>
+    if (*SectionName == ".eh_frame")<br>
+      printEHFrame(&Shdr);<br>
+  }<br>
+}<br>
+<br>
+template <typename ELFT><br>
+void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,<br>
+                                           uint64_t EHFrameHdrAddress,<br>
+                                           uint64_t EHFrameHdrSize) const {<br>
+  ListScope L(W, "EH_FRAME Header");<br>
+  W.startLine() << format("Address: 0x%" PRIx64 "\n", EHFrameHdrAddress);<br>
+  W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);<br>
+  W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);<br>
+<br>
+  const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);<br>
+  if (EHFrameHdrShdr) {<br>
+    auto SectionName = Obj->getSectionName(EHFrameHdrShdr);<br>
+    if (Error E = SectionName.takeError())<br>
+      reportError(toString(std::move(E)));<br>
+<br>
+    W.printString("Corresponding Section", *SectionName);<br>
+  }<br>
+<br>
+  DataExtractor DE(<br>
+      StringRef(reinterpret_cast<const char *>(Obj->base()) + EHFrameHdrOffset,<br>
+                EHFrameHdrSize),<br>
+      ELFT::TargetEndianness == support::endianness::little,<br>
+      ELFT::Is64Bits ? 8 : 4);<br>
+<br>
+  DictScope D(W, "Header");<br>
+  uint32_t Offset = 0;<br>
+<br>
+  auto Version = DE.getU8(&Offset);<br>
+  W.printNumber("version", Version);<br>
+  if (Version != 1)<br>
+    reportError("only version 1 of .eh_frame_hdr is supported");<br>
+<br>
+  auto EHFramePtrEnc = DE.getU8(&Offset);<br>
+  W.startLine() << format("eh_frame_ptr_enc: 0x%" PRIx64 "\n", EHFramePtrEnc);<br>
+  if (EHFramePtrEnc != (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4))<br>
+    reportError("unexpected encoding eh_frame_ptr_enc");<br>
+<br>
+  auto FDECountEnc = DE.getU8(&Offset);<br>
+  W.startLine() << format("fde_count_enc: 0x%" PRIx64 "\n", FDECountEnc);<br>
+  if (FDECountEnc != dwarf::DW_EH_PE_udata4)<br>
+    reportError("unexpected encoding fde_count_enc");<br>
+<br>
+  auto TableEnc = DE.getU8(&Offset);<br>
+  W.startLine() << format("table_enc: 0x%" PRIx64 "\n", TableEnc);<br>
+  if (TableEnc != (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4))<br>
+    reportError("unexpected encoding table_enc");<br>
+<br>
+  auto EHFramePtr = DE.getSigned(&Offset, 4) + EHFrameHdrAddress + 4;<br>
+  W.startLine() << format("eh_frame_ptr: 0x%" PRIx64 "\n", EHFramePtr);<br>
+<br>
+  auto FDECount = DE.getUnsigned(&Offset, 4);<br>
+  W.printNumber("fde_count", FDECount);<br>
+<br>
+  unsigned NumEntries = 0;<br>
+  uint64_t PrevPC = 0;<br>
+  while (Offset + 8 <= EHFrameHdrSize && NumEntries < FDECount) {<br>
+    DictScope D(W, std::string("entry ")  + std::to_string(NumEntries));<br>
+<br>
+    auto InitialPC = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;<br>
+    W.startLine() << format("initial_location: 0x%" PRIx64 "\n", InitialPC);<br>
+    auto Address = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;<br>
+    W.startLine() << format("address: 0x%" PRIx64 "\n", Address);<br>
+<br>
+    if (InitialPC < PrevPC)<br>
+      reportError("initial_location is out of order");<br>
+<br>
+    PrevPC = InitialPC;<br>
+    ++NumEntries;<br>
+  }<br>
+}<br>
+<br>
+template <typename ELFT><br>
+void PrinterContext<ELFT>::printEHFrame(<br>
+    const typename ELFT::Shdr *EHFrameShdr) const {<br>
+  uint64_t Address = EHFrameShdr->sh_addr;<br>
+  uint64_t ShOffset = EHFrameShdr->sh_offset;<br>
+  W.startLine() << format(".eh_frame section at offset 0x%" PRIx64<br>
+                          " address 0x%" PRIx64 ":\n",<br>
+                          ShOffset, Address);<br>
+  W.indent();<br>
+<br>
+  auto Result = Obj->getSectionContents(EHFrameShdr);<br>
+  if (Error E = Result.takeError())<br>
+    reportError(toString(std::move(E)));<br>
+<br>
+  auto Contents = Result.get();<br>
+  DWARFDataExtractor DE(<br>
+      StringRef(reinterpret_cast<const char *>(Contents.data()),<br>
+                Contents.size()),<br>
+      ELFT::TargetEndianness == support::endianness::little,<br>
+      ELFT::Is64Bits ? 8 : 4);<br>
+  DWARFDebugFrame EHFrame(/*IsEH=*/true, /*EHFrameAddress=*/Address);<br>
+  EHFrame.parse(DE);<br>
+<br>
+  for (const auto &Entry : EHFrame) {<br>
+    if (const auto *CIE = dyn_cast<dwarf::CIE>(&Entry)) {<br>
+      W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",<br>
+                              Address + CIE->getOffset(),<br>
+                              CIE->getLength());<br>
+      W.indent();<br>
+<br>
+      W.printNumber("version", CIE->getVersion());<br>
+      W.printString("augmentation", CIE->getAugmentationString());<br>
+      W.printNumber("code_alignment_factor", CIE->getCodeAlignmentFactor());<br>
+      W.printNumber("data_alignment_factor", CIE->getDataAlignmentFactor());<br>
+      W.printNumber("return_address_register", CIE->getReturnAddressRegister());<br>
+<br>
+      W.getOStream() << "\n";<br>
+      W.startLine() << "Program:\n";<br>
+      W.indent();<br>
+      CIE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());<br>
+      W.unindent();<br>
+<br>
+      W.unindent();<br>
+      W.getOStream() << "\n";<br>
+<br>
+    } else if (const auto *FDE = dyn_cast<dwarf::FDE>(&Entry)) {<br>
+      W.startLine() << format("[0x%" PRIx64 "] FDE length=%" PRIu64<br>
+                              " cie=[0x%" PRIx64 "]\n",<br>
+                              Address + FDE->getOffset(),<br>
+                              FDE->getLength(),<br>
+                              Address + FDE->getLinkedCIE()->getOffset());<br>
+      W.indent();<br>
+<br>
+      W.startLine() << format("initial_location: 0x%" PRIx64 "\n",<br>
+                              FDE->getInitialLocation());<br>
+      W.startLine()<br>
+        << format("address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",<br>
+                  FDE->getAddressRange(),<br>
+                  FDE->getInitialLocation() + FDE->getAddressRange());<br>
+<br>
+      W.getOStream() << "\n";<br>
+      W.startLine() << "Program:\n";<br>
+      W.indent();<br>
+      FDE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());<br>
+      W.unindent();<br>
+<br>
+      W.unindent();<br>
+      W.getOStream() << "\n";<br>
+    } else {<br>
+      llvm_unreachable("unexpected DWARF frame kind");<br>
+    }<br>
+  }<br>
+<br>
+  W.unindent();<br>
+}<br>
+<br>
+}<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp<br>
URL: </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_tools_llvm-2Dreadobj_ELFDumper.cpp-3Frev-3D326932-26r1-3D326931-26r2-3D326932-26view-3Ddiff&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=ROdAe8c8_4kgxxSw21q2CYH5acaHFecu52DiAxOqqUI&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=326932&r1=326931&r2=326932&view=diff</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)<br>
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Mar  7 11:19:51 2018<br>
@@ -13,6 +13,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "ARMEHABIPrinter.h"<br>
+#include "DwarfCFIEHPrinter.h"<br>
 #include "Error.h"<br>
 #include "ObjDumper.h"<br>
 #include "StackMapPrinter.h"<br>
@@ -1808,6 +1809,11 @@ void ELFDumper<ELFT>::printValue(uint64_<br>
<br>
 template<class ELFT><br>
 void ELFDumper<ELFT>::printUnwindInfo() {<br>
+  const unsigned Machine = Obj->getHeader()->e_machine;<br>
+  if (Machine == EM_386 || Machine == EM_X86_64) {<br>
+    DwarfCFIEH::PrinterContext<ELFT> Ctx(W, Obj);<br>
+    return Ctx.printUnwindInformation();<br>
+  }<br>
   W.startLine() << "UnwindInfo not implemented.\n";<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
</span><a href="mailto:llvm-commits@lists.llvm.org"><span style="mso-bookmark:_MailOriginalBody">llvm-commits@lists.llvm.org</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><br>
</span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_llvm-2Dcommits&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=kx31RNFp5lAJejEYwuEQ4Zc5A6GakBit07EY08bIAvc&m=_LqijQYASaPHXQaTZ_L29zoOCiZu0bBh0uAVnCAJTI0&s=GyoQTnOVLr3q-Y0yyIQ76HG1_PHNv-0oHv00qLZeji0&e=" target="_blank"><span style="mso-bookmark:_MailOriginalBody">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</span><span style="mso-bookmark:_MailOriginalBody"></span></a><span style="mso-bookmark:_MailOriginalBody"><o:p></o:p></span></p>
</blockquote>
</div>
<p class="MsoNormal"><span style="mso-bookmark:_MailOriginalBody"><o:p> </o:p></span></p>
</div>
</div>
</body>
</html>