//===- llvm/unittest/DebugInfo/DWARFDebugFrameTest.cpp --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

dwarf::CIE createCIE(bool IsDWARF64, uint64_t Offset, uint64_t Length) {
  return dwarf::CIE(IsDWARF64, Offset, Length,
                    /*Version=*/3,
                    /*Augmentation=*/StringRef(),
                    /*AddressSize=*/8,
                    /*SegmentDescriptorSize=*/0,
                    /*CodeAlignmentFactor=*/1,
                    /*DataAlignmentFactor=*/-8,
                    /*ReturnAddressRegister=*/16,
                    /*AugmentationData=*/StringRef(),
                    /*FDEPointerEncoding=*/dwarf::DW_EH_PE_absptr,
                    /*LSDAPointerEncoding=*/dwarf::DW_EH_PE_omit,
                    /*Personality=*/None,
                    /*PersonalityEnc=*/None,
                    /*Arch=*/Triple::x86_64);
}

void expectDumpResult(const dwarf::CIE &TestCIE, bool IsEH,
                      StringRef ExpectedFirstLine) {
  std::string Output;
  raw_string_ostream OS(Output);
  TestCIE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
  OS.flush();
  StringRef FirstLine = StringRef(Output).split('\n').first;
  EXPECT_EQ(FirstLine, ExpectedFirstLine);
}

void expectDumpResult(const dwarf::FDE &TestFDE, bool IsEH,
                      StringRef ExpectedFirstLine) {
  std::string Output;
  raw_string_ostream OS(Output);
  TestFDE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
  OS.flush();
  StringRef FirstLine = StringRef(Output).split('\n').first;
  EXPECT_EQ(FirstLine, ExpectedFirstLine);
}

TEST(DWARFDebugFrame, DumpDWARF32CIE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x1111abcd,
                                 /*Length=*/0x2222abcd);
  expectDumpResult(TestCIE, /*IsEH=*/false, "1111abcd 2222abcd ffffffff CIE");
}

TEST(DWARFDebugFrame, DumpDWARF64CIE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
                                 /*Offset=*/0x1111abcdabcd,
                                 /*Length=*/0x2222abcdabcd);
  expectDumpResult(TestCIE, /*IsEH=*/false,
                   "1111abcdabcd 00002222abcdabcd ffffffffffffffff CIE");
}

TEST(DWARFDebugFrame, DumpEHCIE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x1000,
                                 /*Length=*/0x20);
  expectDumpResult(TestCIE, /*IsEH=*/true, "00001000 00000020 00000000 CIE");
}

TEST(DWARFDebugFrame, DumpEH64CIE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
                                 /*Offset=*/0x1000,
                                 /*Length=*/0x20);
  expectDumpResult(TestCIE, /*IsEH=*/true,
                   "00001000 0000000000000020 00000000 CIE");
}

TEST(DWARFDebugFrame, DumpDWARF64FDE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
                                 /*Offset=*/0x1111abcdabcd,
                                 /*Length=*/0x2222abcdabcd);
  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x5555abcdabcd,
                     /*AddressRange=*/0x111111111111,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);
  expectDumpResult(TestFDE, /*IsEH=*/false,
                   "3333abcdabcd 00004444abcdabcd 00001111abcdabcd FDE "
                   "cie=1111abcdabcd pc=5555abcdabcd...6666bcdebcde");
}

TEST(DWARFDebugFrame, DumpEH64FDE) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/true,
                                 /*Offset=*/0x1111ab9a000c,
                                 /*Length=*/0x20);
  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x1111abcdabcd,
                     /*Length=*/0x2222abcdabcd,
                     /*CIEPointer=*/0x33abcd,
                     /*InitialLocation=*/0x4444abcdabcd,
                     /*AddressRange=*/0x111111111111,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);
  expectDumpResult(TestFDE, /*IsEH=*/true,
                   "1111abcdabcd 00002222abcdabcd 0033abcd FDE "
                   "cie=1111ab9a000c pc=4444abcdabcd...5555bcdebcde");
}

static Error parseCFI(dwarf::CIE &C, ArrayRef<uint8_t> Instructions,
                      Optional<uint64_t> Size = None) {
  DWARFDataExtractor Data(Instructions, /*IsLittleEndian=*/true,
                          /*AddressSize=*/8);
  uint64_t Offset = 0;
  const uint64_t EndOffset = Size ? *Size : (uint64_t)Instructions.size();
  return C.cfis().parse(Data, &Offset, EndOffset);
}

static Error parseCFI(dwarf::FDE &FDE, ArrayRef<uint8_t> Instructions) {
  DWARFDataExtractor Data(Instructions, /*IsLittleEndian=*/true,
                          /*AddressSize=*/8);
  uint64_t Offset = 0;
  return FDE.cfis().parse(Data, &Offset, Instructions.size());
}

TEST(DWARFDebugFrame, InvalidCFIOpcodesTest) {
  llvm::DenseSet<uint8_t> ValidExtendedOpcodes = {
      dwarf::DW_CFA_nop,
      dwarf::DW_CFA_advance_loc,
      dwarf::DW_CFA_offset,
      dwarf::DW_CFA_restore,
      dwarf::DW_CFA_set_loc,
      dwarf::DW_CFA_advance_loc1,
      dwarf::DW_CFA_advance_loc2,
      dwarf::DW_CFA_advance_loc4,
      dwarf::DW_CFA_offset_extended,
      dwarf::DW_CFA_restore_extended,
      dwarf::DW_CFA_undefined,
      dwarf::DW_CFA_same_value,
      dwarf::DW_CFA_register,
      dwarf::DW_CFA_remember_state,
      dwarf::DW_CFA_restore_state,
      dwarf::DW_CFA_def_cfa,
      dwarf::DW_CFA_def_cfa_register,
      dwarf::DW_CFA_def_cfa_offset,
      dwarf::DW_CFA_def_cfa_expression,
      dwarf::DW_CFA_expression,
      dwarf::DW_CFA_offset_extended_sf,
      dwarf::DW_CFA_def_cfa_sf,
      dwarf::DW_CFA_def_cfa_offset_sf,
      dwarf::DW_CFA_LLVM_def_aspace_cfa,
      dwarf::DW_CFA_LLVM_def_aspace_cfa_sf,
      dwarf::DW_CFA_val_offset,
      dwarf::DW_CFA_val_offset_sf,
      dwarf::DW_CFA_val_expression,
      dwarf::DW_CFA_MIPS_advance_loc8,
      dwarf::DW_CFA_GNU_window_save,
      dwarf::DW_CFA_AARCH64_negate_ra_state,
      dwarf::DW_CFA_GNU_args_size};

  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  // See DWARF standard v3, section 7.23: low 6 bits are used to encode an
  // extended opcode.
  for (uint8_t Code = 0; Code <= 63; ++Code) {
    if (ValidExtendedOpcodes.count(Code))
      continue;

    EXPECT_THAT_ERROR(parseCFI(TestCIE, Code),
                      FailedWithMessage(("invalid extended CFI opcode 0x" +
                                         Twine::utohexstr(Code))
                                            .str()
                                            .c_str()));
  }
}

// Here we test how truncated Call Frame Instructions are parsed.
TEST(DWARFDebugFrame, ParseTruncatedCFITest) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  // Having an empty instructions list is fine.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());

  // Unable to read an opcode, because the instructions list is empty, but we
  // say to the parser that it is not.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {}, /*Size=*/1),
      FailedWithMessage(
          "unexpected end of data at offset 0x0 while reading [0x0, 0x1)"));

  // Unable to read a truncated DW_CFA_offset instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_offset}),
      FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                        "malformed uleb128, extends past end"));

  // Unable to read a truncated DW_CFA_set_loc instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_set_loc}),
      FailedWithMessage(
          "unexpected end of data at offset 0x1 while reading [0x1, 0x9)"));

  // Unable to read a truncated DW_CFA_advance_loc1 instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc1}),
      FailedWithMessage(
          "unexpected end of data at offset 0x1 while reading [0x1, 0x2)"));

  // Unable to read a truncated DW_CFA_advance_loc2 instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc2}),
      FailedWithMessage(
          "unexpected end of data at offset 0x1 while reading [0x1, 0x3)"));

  // Unable to read a truncated DW_CFA_advance_loc4 instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_advance_loc4}),
      FailedWithMessage(
          "unexpected end of data at offset 0x1 while reading [0x1, 0x5)"));

  // A test for an instruction with a single ULEB128 operand.
  auto CheckOp_ULEB128 = [&](uint8_t Inst) {
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, Inst),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                          "malformed uleb128, extends past end"));
  };

  for (uint8_t Inst :
       {dwarf::DW_CFA_restore_extended, dwarf::DW_CFA_undefined,
        dwarf::DW_CFA_same_value, dwarf::DW_CFA_def_cfa_register,
        dwarf::DW_CFA_def_cfa_offset, dwarf::DW_CFA_GNU_args_size})
    CheckOp_ULEB128(Inst);

  // Unable to read a truncated DW_CFA_def_cfa_offset_sf instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_offset_sf}),
      FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                        "malformed sleb128, extends past end"));

  // A test for an instruction with two ULEB128 operands.
  auto CheckOp_ULEB128_ULEB128 = [&](uint8_t Inst) {
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, Inst),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                          "malformed uleb128, extends past end"));

    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, {Inst, /*Op1=*/0}),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
                          "malformed uleb128, extends past end"));
  };

  for (uint8_t Inst : {dwarf::DW_CFA_offset_extended, dwarf::DW_CFA_register,
                       dwarf::DW_CFA_def_cfa, dwarf::DW_CFA_LLVM_def_aspace_cfa,
                       dwarf::DW_CFA_val_offset})
    CheckOp_ULEB128_ULEB128(Inst);

  // A test for an instruction with two operands: ULEB128, SLEB128.
  auto CheckOp_ULEB128_SLEB128 = [&](uint8_t Inst) {
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, Inst),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                          "malformed uleb128, extends past end"));

    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, {Inst, /*Op1=*/0}),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
                          "malformed sleb128, extends past end"));
  };

  for (uint8_t Inst :
       {dwarf::DW_CFA_offset_extended_sf, dwarf::DW_CFA_def_cfa_sf,
        dwarf::DW_CFA_LLVM_def_aspace_cfa_sf, dwarf::DW_CFA_val_offset_sf})
    CheckOp_ULEB128_SLEB128(Inst);

  // Unable to read a truncated DW_CFA_def_cfa_expression instruction.
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression}),
      FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                        "malformed uleb128, extends past end"));
  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
                         /*expression length=*/0x1}),
      FailedWithMessage(
          "unexpected end of data at offset 0x2 while reading [0x2, 0x3)"));
  // The DW_CFA_def_cfa_expression can contain a zero length expression.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_expression,
                                       /*ExprLen=*/0}),
                    Succeeded());

  // A test for an instruction with three operands: ULEB128, expression length
  // (ULEB128) and expression bytes.
  auto CheckOp_ULEB128_Expr = [&](uint8_t Inst) {
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, {Inst}),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
                          "malformed uleb128, extends past end"));
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, {Inst, /*Op1=*/0}),
        FailedWithMessage("unable to decode LEB128 at offset 0x00000002: "
                          "malformed uleb128, extends past end"));
    // A zero length expression is fine
    EXPECT_THAT_ERROR(parseCFI(TestCIE, {Inst,
                                         /*Op1=*/0, /*ExprLen=*/0}),
                      Succeeded());
    EXPECT_THAT_ERROR(
        parseCFI(TestCIE, {Inst,
                           /*Op1=*/0, /*ExprLen=*/1}),
        FailedWithMessage(
            "unexpected end of data at offset 0x3 while reading [0x3, 0x4)"));
  };

  for (uint8_t Inst : {dwarf::DW_CFA_expression, dwarf::DW_CFA_val_expression})
    CheckOp_ULEB128_Expr(Inst);
}

void expectDumpResult(const dwarf::UnwindLocation &Loc,
                      StringRef ExpectedFirstLine) {
  std::string Output;
  raw_string_ostream OS(Output);
  OS << Loc;
  OS.flush();
  StringRef FirstLine = StringRef(Output).split('\n').first;
  EXPECT_EQ(FirstLine, ExpectedFirstLine);
}

TEST(DWARFDebugFrame, DumpUnwindLocations) {
  // Test constructing unwind locations and dumping each kind.
  constexpr int32_t PlusOff = 8;
  constexpr int32_t MinusOff = -8;
  constexpr uint8_t RegNum = 12;
  expectDumpResult(dwarf::UnwindLocation::createUnspecified(), "unspecified");
  expectDumpResult(dwarf::UnwindLocation::createUndefined(), "undefined");
  expectDumpResult(dwarf::UnwindLocation::createSame(), "same");
  expectDumpResult(dwarf::UnwindLocation::createIsCFAPlusOffset(PlusOff),
                   "CFA+8");
  expectDumpResult(dwarf::UnwindLocation::createIsCFAPlusOffset(MinusOff),
                   "CFA-8");
  expectDumpResult(dwarf::UnwindLocation::createAtCFAPlusOffset(PlusOff),
                   "[CFA+8]");
  expectDumpResult(dwarf::UnwindLocation::createAtCFAPlusOffset(MinusOff),
                   "[CFA-8]");

  expectDumpResult(
      dwarf::UnwindLocation::createIsRegisterPlusOffset(RegNum, PlusOff),
      "reg12+8");
  expectDumpResult(
      dwarf::UnwindLocation::createIsRegisterPlusOffset(RegNum, MinusOff),
      "reg12-8");
  expectDumpResult(
      dwarf::UnwindLocation::createAtRegisterPlusOffset(RegNum, PlusOff),
      "[reg12+8]");
  expectDumpResult(
      dwarf::UnwindLocation::createAtRegisterPlusOffset(RegNum, MinusOff),
      "[reg12-8]");
  expectDumpResult(dwarf::UnwindLocation::createIsConstant(12), "12");
  expectDumpResult(dwarf::UnwindLocation::createIsConstant(-32), "-32");
}

void expectDumpResult(const dwarf::RegisterLocations &Locs,
                      StringRef ExpectedFirstLine) {
  std::string Output;
  raw_string_ostream OS(Output);
  OS << Locs;
  OS.flush();
  StringRef FirstLine = StringRef(Output).split('\n').first;
  EXPECT_EQ(FirstLine, ExpectedFirstLine);
}

TEST(DWARFDebugFrame, RegisterLocations) {
  // Test the functionality of the RegisterLocations class.
  dwarf::RegisterLocations Locs;
  expectDumpResult(Locs, "");
  EXPECT_FALSE(Locs.hasLocations());
  // Set a register location for reg12 to unspecified and verify it dumps
  // correctly.
  Locs.setRegisterLocation(12, dwarf::UnwindLocation::createUnspecified());
  EXPECT_TRUE(Locs.hasLocations());
  expectDumpResult(Locs, "reg12=unspecified");

  // Replace the register location for reg12 to "same" and verify it dumps
  // correctly after it is modified
  Locs.setRegisterLocation(12, dwarf::UnwindLocation::createSame());
  EXPECT_TRUE(Locs.hasLocations());
  expectDumpResult(Locs, "reg12=same");

  // Remove the register location for reg12 verify it dumps correctly after it
  // is removed.
  Locs.removeRegisterLocation(12);
  EXPECT_FALSE(Locs.hasLocations());
  expectDumpResult(Locs, "");

  // Verify multiple registers added to the list dump correctly.
  auto Reg12Loc = dwarf::UnwindLocation::createAtCFAPlusOffset(4);
  auto Reg13Loc = dwarf::UnwindLocation::createAtCFAPlusOffset(8);
  auto Reg14Loc = dwarf::UnwindLocation::createSame();
  Locs.setRegisterLocation(12, Reg12Loc);
  Locs.setRegisterLocation(13, Reg13Loc);
  Locs.setRegisterLocation(14, Reg14Loc);
  EXPECT_TRUE(Locs.hasLocations());
  expectDumpResult(Locs, "reg12=[CFA+4], reg13=[CFA+8], reg14=same");

  // Verify RegisterLocations::getRegisterLocation() works as expected.
  Optional<dwarf::UnwindLocation> OptionalLoc;
  OptionalLoc = Locs.getRegisterLocation(0);
  EXPECT_FALSE(OptionalLoc.hasValue());

  OptionalLoc = Locs.getRegisterLocation(12);
  EXPECT_TRUE(OptionalLoc.hasValue());
  EXPECT_EQ(*OptionalLoc, Reg12Loc);

  OptionalLoc = Locs.getRegisterLocation(13);
  EXPECT_TRUE(OptionalLoc.hasValue());
  EXPECT_EQ(*OptionalLoc, Reg13Loc);

  OptionalLoc = Locs.getRegisterLocation(14);
  EXPECT_TRUE(OptionalLoc.hasValue());
  EXPECT_EQ(*OptionalLoc, Reg14Loc);

  // Verify registers are correctly removed when multiple exist in the list.
  Locs.removeRegisterLocation(13);
  EXPECT_FALSE(Locs.getRegisterLocation(13).hasValue());
  EXPECT_TRUE(Locs.hasLocations());
  expectDumpResult(Locs, "reg12=[CFA+4], reg14=same");
  Locs.removeRegisterLocation(14);
  EXPECT_FALSE(Locs.getRegisterLocation(14).hasValue());
  EXPECT_TRUE(Locs.hasLocations());
  expectDumpResult(Locs, "reg12=[CFA+4]");
  Locs.removeRegisterLocation(12);
  EXPECT_FALSE(Locs.getRegisterLocation(12).hasValue());
  EXPECT_FALSE(Locs.hasLocations());
  expectDumpResult(Locs, "");
}

// Test that empty rows are not added to UnwindTable when
// dwarf::CIE::CFIs or dwarf::FDE::CFIs is empty.
TEST(DWARFDebugFrame, UnwindTableEmptyRows) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  // Having an empty instructions list is fine.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());
  EXPECT_TRUE(TestCIE.cfis().empty());

  // Verify dwarf::UnwindTable::create() won't result in errors and
  // and empty rows are not added to CIE UnwindTable.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestCIE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const size_t ExpectedNumOfRows = 0;
  EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Having an empty instructions list is fine.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {}), Succeeded());
  EXPECT_TRUE(TestFDE.cfis().empty());

  // Verify dwarf::UnwindTable::create() won't result in errors and
  // and empty rows are not added to FDE UnwindTable.
  RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
}

// Test that empty rows are not added to UnwindTable when dwarf::CIE::CFIs
// or dwarf::FDE::CFIs is not empty but has only DW_CFA_nop instructions.
TEST(DWARFDebugFrame, UnwindTableEmptyRows_NOPs) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  // Make a CIE that has only DW_CFA_nop instructions.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_nop}), Succeeded());
  EXPECT_TRUE(!TestCIE.cfis().empty());

  // Verify dwarf::UnwindTable::create() won't result in errors and
  // and empty rows are not added to CIE UnwindTable.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestCIE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const size_t ExpectedNumOfRows = 0;
  EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make an FDE that has only DW_CFA_nop instructions.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_nop}), Succeeded());
  EXPECT_TRUE(!TestFDE.cfis().empty());

  // Verify dwarf::UnwindTable::create() won't result in errors and
  // and empty rows are not added to FDE UnwindTable.
  RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  EXPECT_EQ(RowsOrErr->size(), ExpectedNumOfRows);
}

TEST(DWARFDebugFrame, UnwindTableErrorNonAscendingFDERows) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition.
  constexpr uint8_t Reg = 12;
  constexpr uint8_t Offset = 32;
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode two DW_CFA_set_loc opcodes:
  //   DW_CFA_set_loc(0x1100)
  //   DW_CFA_set_loc(0x1000)
  // These opcodes cause a new row to be appended to the rows in a UnwindTable
  // and the resulting rows are not in ascending address order and should cause
  // a state machine error.
  EXPECT_THAT_ERROR(
      parseCFI(TestFDE, {dwarf::DW_CFA_set_loc, 0x00, 0x11, 0, 0, 0, 0, 0, 0,
                         dwarf::DW_CFA_set_loc, 0x00, 0x10, 0, 0, 0, 0, 0, 0}),
      Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(),
                    FailedWithMessage("DW_CFA_set_loc with adrress 0x1000 which"
                                      " must be greater than the current row "
                                      "address 0x1100"));
}

TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_restore_state) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition.
  constexpr uint8_t Reg = 12;
  constexpr uint8_t Offset = 32;
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode a DW_CFA_restore_state opcode that was not preceded by a
  // DW_CFA_remember_state, and an error should be returned.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_restore_state}),
                    Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(),
                    FailedWithMessage("DW_CFA_restore_state without a matching "
                                      "previous DW_CFA_remember_state"));
}

TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_GNU_window_save) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition.
  constexpr uint8_t Reg = 12;
  constexpr uint8_t Offset = 32;
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, Reg, Offset}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode a DW_CFA_GNU_window_save that is not supported. I have not
  // found any documentation that describes what this does after some brief
  // searching.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_GNU_window_save}),
                    Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(),
                    FailedWithMessage("DW_CFA opcode 0x2d is not supported for "
                                      "architecture x86_64"));
}

TEST(DWARFDebugFrame, UnwindTableError_DW_CFA_def_cfa_offset) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has an invalid CFA definition. We do this so we can try
  // and use a DW_CFA_def_cfa_register opcode in the FDE and get an appropriate
  // error back.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode a DW_CFA_def_cfa_offset with a offset of 16, but our CIE
  // didn't define the CFA in terms of a register plus offset, so this should
  // cause an error.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_def_cfa_offset, 16}),
                    Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(),
                    FailedWithMessage("DW_CFA_def_cfa_offset found when CFA "
                                      "rule was not RegPlusOffset"));
}

TEST(DWARFDebugFrame, UnwindTableDefCFAOffsetSFCFAError) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has an invalid CFA definition. We do this so we can try
  // and use a DW_CFA_def_cfa_offset_sf opcode in the FDE and get an
  // appropriate error back.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {}), Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode a DW_CFA_def_cfa_offset_sf with a offset of 4, but our CIE
  // didn't define the CFA in terms of a register plus offset, so this should
  // cause an error.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_def_cfa_offset_sf, 4}),
                    Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(),
                    FailedWithMessage("DW_CFA_def_cfa_offset_sf found when CFA "
                                      "rule was not RegPlusOffset"));
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_def_cfa_register) {
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has only defines the CFA register with no offset. Some
  // architectures do this and we must ensure that we set the CFA value to be
  // equal to that register with no offset.
  constexpr uint8_t CFAReg = 12;
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa_register, CFAReg}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that have valid
  // syntax, but will cause an error when we parse them into a UnwindTable.
  // Here we encode a DW_CFA_def_cfa_register with a register number of 12, but
  // our CIE didn't define the CFA in terms of a register plus offset, so this
  // should cause an error.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {}), Succeeded());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg, 0));
}

TEST(DWARFDebugFrame, UnwindTableRowPushingOpcodes) {
  // Test all opcodes that should end up pushing a UnwindRow into a UnwindTable.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  constexpr uint8_t CFAReg = 12;
  constexpr uint8_t CFAOffset = 32;
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;

  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
                                       dwarf::DW_CFA_register, Reg, InReg}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that use all of the
  // row pushing opcodes. This will verify that all opcodes that should create
  // a row are correctly working. Each opcode will push a row prior to
  // advancing the address, and then a row will be automatically pushed at the
  // end of the parsing, so we should end up with 6 rows starting at address
  // 0x1000 (from the FDE) and incrementing each one by 4 * CodeAlignmentFactor
  // from the CIE.
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_advance_loc | 4,
                                       dwarf::DW_CFA_advance_loc1,
                                       4,
                                       dwarf::DW_CFA_advance_loc2,
                                       4,
                                       0,
                                       dwarf::DW_CFA_advance_loc4,
                                       4,
                                       0,
                                       0,
                                       0,
                                       dwarf::DW_CFA_set_loc,
                                       0x14,
                                       0x10,
                                       0,
                                       0,
                                       0,
                                       0,
                                       0,
                                       0}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  ASSERT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 6u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);
  EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
  EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);
  EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
  EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);
  EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
  EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
  EXPECT_EQ(Rows[5].getAddress(), 0x1014u);
  EXPECT_EQ(Rows[5].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[5].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_restore) {
  // Test that DW_CFA_restore works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  constexpr uint8_t CFAReg = 12;
  constexpr uint8_t CFAOffset = 32;
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;
  constexpr int32_t RegCFAOffset = -8;

  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
                                       dwarf::DW_CFA_register, Reg, InReg}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that changes the rule
  // for register "Reg" to be [CFA-8], then push a row, and then restore the
  // register unwind rule for "Reg" using DW_CFA_restore. We should end up with
  // two rows:
  //   - one with Reg = [CFA-8]
  //   - one with Reg = InReg
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_offset | Reg, 1,
                                       dwarf::DW_CFA_advance_loc | 4,
                                       dwarf::DW_CFA_restore | Reg}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs1;
  VerifyLocs1.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createAtCFAPlusOffset(RegCFAOffset));

  dwarf::RegisterLocations VerifyLocs2;
  VerifyLocs2.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 2u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);
  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_restore_extended) {
  // Test that DW_CFA_restore works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  constexpr uint8_t CFAReg = 12;
  constexpr uint8_t CFAOffset = 32;
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;
  constexpr int32_t RegCFAOffset = -8;

  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg, CFAOffset,
                                       dwarf::DW_CFA_register, Reg, InReg}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that changes the rule
  // for register "Reg" to be [CFA-8], then push a row, and then restore the
  // register unwind rule for "Reg" using DW_CFA_restore_extended. We should
  // end up with two rows:
  //   - one with Reg = [CFA-8]
  //   - one with Reg = InReg
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_offset | Reg, 1,
                                       dwarf::DW_CFA_advance_loc | 4,
                                       dwarf::DW_CFA_restore_extended, Reg}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs1;
  VerifyLocs1.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createAtCFAPlusOffset(RegCFAOffset));

  dwarf::RegisterLocations VerifyLocs2;
  VerifyLocs2.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 2u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);
  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_offset) {
  // Test that DW_CFA_offset, DW_CFA_offset_extended and
  // DW_CFA_offset_extended_sf work as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that changes the
  // unwind rules for the follwing registers:
  //   Reg1 = [CFA-8]
  //   Reg2 = [CFA-16]
  //   Reg3 = [CFA+8]
  constexpr uint8_t Reg1 = 14;
  constexpr uint8_t Reg2 = 15;
  constexpr uint8_t Reg3 = 16;
  constexpr uint8_t Neg1SLEB = 0x7f;
  EXPECT_THAT_ERROR(
      parseCFI(TestFDE,
               {dwarf::DW_CFA_offset | Reg1, 1, dwarf::DW_CFA_offset_extended,
                Reg2, 2, dwarf::DW_CFA_offset_extended_sf, Reg3, Neg1SLEB}),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
  VerifyLocs.setRegisterLocation(
      Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));
  VerifyLocs.setRegisterLocation(
      Reg3, dwarf::UnwindLocation::createAtCFAPlusOffset(8));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_val_offset) {
  // Test that DW_CFA_val_offset and DW_CFA_val_offset_sf work as expected when
  // parsed in the state machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that changes the
  // unwind rules for the follwing registers:
  //   Reg1 = [CFA-8]
  //   Reg2 = [CFA-16]
  //   Reg3 = [CFA+8]
  constexpr uint8_t Reg1 = 14;
  constexpr uint8_t Reg2 = 15;
  constexpr uint8_t Neg1SLEB = 0x7f;
  EXPECT_THAT_ERROR(
      parseCFI(TestFDE, {dwarf::DW_CFA_val_offset, Reg1, 1,
                         dwarf::DW_CFA_val_offset_sf, Reg2, Neg1SLEB}),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createIsCFAPlusOffset(-8));
  VerifyLocs.setRegisterLocation(
      Reg2, dwarf::UnwindLocation::createIsCFAPlusOffset(8));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_nop) {
  // Test that DW_CFA_nop works as expected when parsed in the state machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that changes the
  // unwind rules for the follwing registers:
  //   Reg1 = [CFA-8]
  // The opcodes for setting Reg1 are preceded by a DW_CFA_nop.
  constexpr uint8_t Reg1 = 14;
  EXPECT_THAT_ERROR(
      parseCFI(TestFDE, {dwarf::DW_CFA_nop, dwarf::DW_CFA_offset | Reg1, 1}),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_remember_state) {
  // Test that DW_CFA_remember_state and DW_CFA_restore_state work as expected
  // when parsed in the state machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=[CFA-8]
  // 0x1004: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16]
  // 0x1008: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16] Reg3=[CFA-24]
  // 0x100C: CFA=reg12+32: Reg1=[CFA-8] Reg2=[CFA-16]
  // 0x1010: CFA=reg12+32: Reg1=[CFA-8]
  // This state machine will:
  //  - set Reg1 location
  //  - push a row (from DW_CFA_advance_loc)
  //  - remember the state
  //  - set Reg2 location
  //  - push a row (from DW_CFA_advance_loc)
  //  - remember the state
  //  - set Reg3 location
  //  - push a row (from DW_CFA_advance_loc)
  //  - remember the state where Reg1 and Reg2 were set
  //  - push a row (from DW_CFA_advance_loc)
  //  - remember the state where only Reg1 was set
  //  - push a row (automatically at the end of instruction parsing)
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg1 = 14;
  constexpr uint8_t Reg2 = 15;
  constexpr uint8_t Reg3 = 16;
  EXPECT_THAT_ERROR(
      parseCFI(TestFDE,
               {dwarf::DW_CFA_offset | Reg1, 1, dwarf::DW_CFA_advance_loc | 4,
                dwarf::DW_CFA_remember_state, dwarf::DW_CFA_offset | Reg2, 2,
                dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_remember_state,
                dwarf::DW_CFA_offset | Reg3, 3, dwarf::DW_CFA_advance_loc | 4,
                dwarf::DW_CFA_restore_state, dwarf::DW_CFA_advance_loc | 4,
                dwarf::DW_CFA_restore_state}),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs1;
  VerifyLocs1.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));

  dwarf::RegisterLocations VerifyLocs2;
  VerifyLocs2.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
  VerifyLocs2.setRegisterLocation(
      Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));

  dwarf::RegisterLocations VerifyLocs3;
  VerifyLocs3.setRegisterLocation(
      Reg1, dwarf::UnwindLocation::createAtCFAPlusOffset(-8));
  VerifyLocs3.setRegisterLocation(
      Reg2, dwarf::UnwindLocation::createAtCFAPlusOffset(-16));
  VerifyLocs3.setRegisterLocation(
      Reg3, dwarf::UnwindLocation::createAtCFAPlusOffset(-24));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 5u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs1);

  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs2);

  EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
  EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs3);

  EXPECT_EQ(Rows[3].getAddress(), 0x100Cu);
  EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs2);

  EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
  EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs1);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_undefined) {
  // Test that DW_CFA_undefined works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=undefined
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg1 = 14;
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_undefined, Reg1}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(Reg1,
                                 dwarf::UnwindLocation::createUndefined());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_same_value) {
  // Test that DW_CFA_same_value works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=same
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg1 = 14;
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_same_value, Reg1}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(Reg1, dwarf::UnwindLocation::createSame());

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_register) {
  // Test that DW_CFA_register works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=same
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;
  EXPECT_THAT_ERROR(parseCFI(TestFDE, {dwarf::DW_CFA_register, Reg, InReg}),
                    Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_expression) {
  // Test that DW_CFA_expression works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=DWARFExpr(DW_OP_reg12)
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg = 13;
  constexpr uint8_t AddrSize = 8;
  std::vector<uint8_t> CFIBytes = {dwarf::DW_CFA_expression, Reg, 1,
                                   dwarf::DW_OP_reg12};

  EXPECT_THAT_ERROR(parseCFI(TestFDE, CFIBytes), Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;

  std::vector<uint8_t> ExprBytes = {dwarf::DW_OP_reg12};
  DataExtractor ExprData(ExprBytes, true, AddrSize);
  DWARFExpression Expr(ExprData, AddrSize);
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createAtDWARFExpression(Expr));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_val_expression) {
  // Test that DW_CFA_val_expression works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, 12, 32}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that encodes the
  // follwing rows:
  // 0x1000: CFA=reg12+32: Reg1=DWARFExpr(DW_OP_reg12)
  // Then we verify that all registers are correct in all generated rows.
  constexpr uint8_t Reg = 13;
  constexpr uint8_t AddrSize = 8;
  std::vector<uint8_t> CFIBytes = {dwarf::DW_CFA_val_expression, Reg, 1,
                                   dwarf::DW_OP_reg12};

  EXPECT_THAT_ERROR(parseCFI(TestFDE, CFIBytes), Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;

  std::vector<uint8_t> ExprBytes = {dwarf::DW_OP_reg12};
  DataExtractor ExprData(ExprBytes, true, AddrSize);
  DWARFExpression Expr(ExprData, AddrSize);
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsDWARFExpression(Expr));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 1u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_def_cfa) {
  // Test that DW_CFA_def_cfa, DW_CFA_def_cfa_sf, DW_CFA_def_cfa_register,
  // DW_CFA_def_cfa_offset, and DW_CFA_def_cfa_offset_sf works as expected when
  // parsed in the state machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  constexpr uint8_t CFAReg1 = 12;
  constexpr uint8_t CFAOff1 = 32;
  constexpr uint8_t CFAReg2 = 13;
  constexpr uint8_t CFAOff2 = 48;
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;

  EXPECT_THAT_ERROR(parseCFI(TestCIE, {dwarf::DW_CFA_def_cfa, CFAReg1, CFAOff1,
                                       dwarf::DW_CFA_register, Reg, InReg}),
                    Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that use all of the
  // DW_CFA_def_cfa* opcodes. This will verify that all opcodes that should
  // create a row are correctly working.
  EXPECT_THAT_ERROR(
      parseCFI(
          TestFDE,
          {
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_register,
              CFAReg2, dwarf::DW_CFA_advance_loc | 4,
              dwarf::DW_CFA_def_cfa_offset, CFAOff2,
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_offset_sf,
              0x7c, // -4 SLEB to make offset = 32 (CFAOff1)
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_sf, CFAReg1,
              0x7a, // -6 SLEB to make CFA offset 48 (CFAOff2)
          }),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 5u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(
      Rows[0].getCFAValue(),
      dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff1));
  EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(
      Rows[1].getCFAValue(),
      dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1));
  EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
  EXPECT_EQ(
      Rows[2].getCFAValue(),
      dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff2));
  EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
  EXPECT_EQ(
      Rows[3].getCFAValue(),
      dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1));
  EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
  EXPECT_EQ(
      Rows[4].getCFAValue(),
      dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff2));
  EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
}

TEST(DWARFDebugFrame, UnwindTable_DW_CFA_LLVM_def_aspace_cfa) {
  // Test that DW_CFA_LLVM_def_aspace_cfa, DW_CFA_LLVM_def_aspace_cfa_sf,
  // DW_CFA_def_cfa_register, DW_CFA_def_cfa_offset, and
  // DW_CFA_def_cfa_offset_sf works as expected when parsed in the state
  // machine.
  dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,
                                 /*Offset=*/0x0,
                                 /*Length=*/0xff);

  dwarf::FDE TestFDE(/*IsDWARF64=*/true,
                     /*Offset=*/0x3333abcdabcd,
                     /*Length=*/0x4444abcdabcd,
                     /*CIEPointer=*/0x1111abcdabcd,
                     /*InitialLocation=*/0x1000,
                     /*AddressRange=*/0x1000,
                     /*Cie=*/&TestCIE,
                     /*LSDAAddress=*/None,
                     /*Arch=*/Triple::x86_64);

  // Make a CIE that has a valid CFA definition and a single register unwind
  // rule for register that we will verify is in all of the pushed rows.
  constexpr uint8_t CFAReg1 = 12;
  constexpr uint8_t CFAOff1 = 32;
  constexpr uint8_t CFAReg2 = 13;
  constexpr uint8_t CFAOff2 = 48;
  constexpr uint8_t Reg = 13;
  constexpr uint8_t InReg = 14;
  constexpr uint8_t AddrSpace = 2;

  EXPECT_THAT_ERROR(
      parseCFI(TestCIE, {dwarf::DW_CFA_LLVM_def_aspace_cfa, CFAReg1, CFAOff1,
                         AddrSpace, dwarf::DW_CFA_register, Reg, InReg}),
      Succeeded());

  // Make a FDE with DWARF call frame instruction opcodes that use all of the
  // DW_CFA_def_cfa* opcodes. This will verify that all opcodes that should
  // create a row are correctly working.
  EXPECT_THAT_ERROR(
      parseCFI(
          TestFDE,
          {
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_register,
              CFAReg2, dwarf::DW_CFA_advance_loc | 4,
              dwarf::DW_CFA_def_cfa_offset, CFAOff2,
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_offset_sf,
              0x7c, // -4 SLEB to make offset = 32 (CFAOff1)
              dwarf::DW_CFA_advance_loc | 4, dwarf::DW_CFA_def_cfa_sf, CFAReg1,
              0x7a, // -6 SLEB to make CFA offset 48 (CFAOff2)
          }),
      Succeeded());

  // Create locations that we expect the UnwindRow objects to contain after
  // parsing the DWARF call frame instructions.
  dwarf::RegisterLocations VerifyLocs;
  VerifyLocs.setRegisterLocation(
      Reg, dwarf::UnwindLocation::createIsRegisterPlusOffset(InReg, 0));

  // Verify we catch state machine error.
  Expected<dwarf::UnwindTable> RowsOrErr = dwarf::UnwindTable::create(&TestFDE);
  EXPECT_THAT_ERROR(RowsOrErr.takeError(), Succeeded());
  const dwarf::UnwindTable &Rows = RowsOrErr.get();
  EXPECT_EQ(Rows.size(), 5u);
  EXPECT_EQ(Rows[0].getAddress(), 0x1000u);
  EXPECT_EQ(Rows[0].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff1,
                                                              AddrSpace));
  EXPECT_EQ(Rows[0].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[0].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[1].getAddress(), 0x1004u);
  EXPECT_EQ(Rows[1].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1,
                                                              AddrSpace));
  EXPECT_EQ(Rows[1].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[1].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[2].getAddress(), 0x1008u);
  EXPECT_EQ(Rows[2].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff2,
                                                              AddrSpace));
  EXPECT_EQ(Rows[2].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[2].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[3].getAddress(), 0x100cu);
  EXPECT_EQ(Rows[3].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg2, CFAOff1,
                                                              AddrSpace));
  EXPECT_EQ(Rows[3].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[3].getRegisterLocations(), VerifyLocs);

  EXPECT_EQ(Rows[4].getAddress(), 0x1010u);
  EXPECT_EQ(Rows[4].getCFAValue(),
            dwarf::UnwindLocation::createIsRegisterPlusOffset(CFAReg1, CFAOff2,
                                                              AddrSpace));
  EXPECT_EQ(Rows[4].getRegisterLocations().size(), 1u);
  EXPECT_EQ(Rows[4].getRegisterLocations(), VerifyLocs);
}

} // end anonymous namespace
