Revert r326932: [DebugInfo] Support DWARF expressions in eh_frame

This reverts commit rr326932 because it broke lld/test/ELF/eh-frame-hdr-augmentation.s.

llvm-svn: 326953
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 2b1c91e..de7ef66 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -349,11 +349,11 @@
 
   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 @@
   // 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 @@
   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();
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index 03e3174..861dd31 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -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 @@
     *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;
-}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b9dc215..3312da6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -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 @@
       // 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 @@
           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 @@
   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 @@
     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 @@
   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 @@
   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 @@
 
     // 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 @@
       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 @@
                 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 @@
         }
       }
 
-      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 @@
       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 @@
           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 @@
             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 @@
 
       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 @@
   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);
 }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index a9ea26c..c704c29 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -258,10 +258,9 @@
   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));