//===-- UnwindAssemblyInstEmulation.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 "UnwindAssemblyInstEmulation.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/SmallSet.h"
#include <deque>

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(UnwindAssemblyInstEmulation)

//  UnwindAssemblyInstEmulation method definitions

bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
    AddressRange &range, Thread &thread, UnwindPlan &unwind_plan) {
  std::vector<uint8_t> function_text(range.GetByteSize());
  ProcessSP process_sp(thread.GetProcess());
  if (process_sp) {
    Status error;
    const bool force_live_memory = true;
    if (process_sp->GetTarget().ReadMemory(
            range.GetBaseAddress(), function_text.data(), range.GetByteSize(),
            error, force_live_memory) != range.GetByteSize()) {
      return false;
    }
  }
  return GetNonCallSiteUnwindPlanFromAssembly(
      range, function_text.data(), function_text.size(), unwind_plan);
}

static void DumpUnwindRowsToLog(Log *log, AddressRange range,
                                const UnwindPlan &unwind_plan) {
  if (!log || !log->GetVerbose())
    return;
  StreamString strm;
  lldb::addr_t base_addr = range.GetBaseAddress().GetFileAddress();
  strm.Printf("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):",
              base_addr, base_addr + range.GetByteSize());
  unwind_plan.Dump(strm, nullptr, base_addr);
  log->PutString(strm.GetString());
}

static void DumpInstToLog(Log *log, Instruction &inst,
                          const InstructionList &inst_list) {
  if (!log || !log->GetVerbose())
    return;
  const bool show_address = true;
  const bool show_bytes = true;
  const bool show_control_flow_kind = false;
  StreamString strm;
  lldb_private::FormatEntity::Entry format;
  FormatEntity::Parse("${frame.pc}: ", format);
  inst.Dump(&strm, inst_list.GetMaxOpcocdeByteSize(), show_address, show_bytes,
            show_control_flow_kind, nullptr, nullptr, nullptr, &format, 0);
  log->PutString(strm.GetString());
}

bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
    AddressRange &range, uint8_t *opcode_data, size_t opcode_size,
    UnwindPlan &unwind_plan) {
  if (opcode_data == nullptr || opcode_size == 0)
    return false;

  if (range.GetByteSize() == 0 || !range.GetBaseAddress().IsValid() ||
      !m_inst_emulator_up)
    return false;

  // The instruction emulation subclass setup the unwind plan for the first
  // instruction.
  m_inst_emulator_up->CreateFunctionEntryUnwind(unwind_plan);

  // CreateFunctionEntryUnwind should have created the first row. If it doesn't,
  // then we are done.
  if (unwind_plan.GetRowCount() == 0)
    return false;

  const bool prefer_file_cache = true;
  DisassemblerSP disasm_sp(Disassembler::DisassembleBytes(
      m_arch, nullptr, nullptr, nullptr, nullptr, range.GetBaseAddress(),
      opcode_data, opcode_size, 99999, prefer_file_cache));

  if (!disasm_sp)
    return false;

  Log *log = GetLog(LLDBLog::Unwind);

  m_range_ptr = &range;
  m_unwind_plan_ptr = &unwind_plan;

  m_state.cfa_reg_info = *m_inst_emulator_up->GetRegisterInfo(
      unwind_plan.GetRegisterKind(), unwind_plan.GetInitialCFARegister());
  m_state.fp_is_cfa = false;
  m_state.register_values.clear();

  m_pushed_regs.clear();

  RegisterValue cfa_reg_value;
  cfa_reg_value.SetUInt(m_initial_cfa, m_state.cfa_reg_info.byte_size);
  SetRegisterValue(m_state.cfa_reg_info, cfa_reg_value);

  InstructionList inst_list = disasm_sp->GetInstructionList();

  if (inst_list.GetSize() == 0) {
    DumpUnwindRowsToLog(log, range, unwind_plan);
    return unwind_plan.GetRowCount() > 0;
  }

  Instruction &first_inst = *inst_list.GetInstructionAtIndex(0);
  const lldb::addr_t base_addr = first_inst.GetAddress().GetFileAddress();

  // Map for storing the unwind state at a given offset. When we see a forward
  // branch we add a new entry to this map with the actual unwind plan row and
  // register context for the target address of the branch as the current data
  // have to be valid for the target address of the branch too if we are in
  // the same function.
  std::map<lldb::addr_t, UnwindState> saved_unwind_states;

  // Make a copy of the current instruction Row and save it in m_state so
  // we can add updates as we process the instructions.
  m_state.row = *unwind_plan.GetLastRow();

  // Add the initial state to the save list with offset 0.
  auto condition_block_start_state =
      saved_unwind_states.emplace(0, m_state).first;

  // The architecture dependent condition code of the last processed
  // instruction.
  EmulateInstruction::InstructionCondition last_condition =
      EmulateInstruction::UnconditionalCondition;

  std::deque<std::size_t> to_visit = {0};
  llvm::SmallSet<std::size_t, 0> enqueued = {0};

  // Instructions reachable through jumps are inserted on the front.
  // The next instruction is inserted on the back.
  // Pop from the back to ensure non-branching instructions are visited
  // sequentially.
  while (!to_visit.empty()) {
    const std::size_t current_index = to_visit.back();
    Instruction &inst = *inst_list.GetInstructionAtIndex(current_index);
    to_visit.pop_back();
    DumpInstToLog(log, inst, inst_list);

    m_curr_row_modified = false;
    m_branch_offset = 0;

    lldb::addr_t current_offset =
        inst.GetAddress().GetFileAddress() - base_addr;
    auto it = saved_unwind_states.upper_bound(current_offset);
    assert(it != saved_unwind_states.begin() &&
           "Unwind row for the function entry missing");
    --it; // Move it to the row corresponding to the current offset

    // When state is forwarded through a branch, the offset of m_state.row is
    // different from the offset available in saved_unwind_states. Use the
    // forwarded state in this case, as the previous instruction may have been
    // an unconditional jump.
    // FIXME: this assignment can always be done unconditionally.
    if (it->second.row.GetOffset() != m_state.row.GetOffset())
      m_state = it->second;

    m_inst_emulator_up->SetInstruction(inst.GetOpcode(), inst.GetAddress(),
                                       nullptr);
    const EmulateInstruction::InstructionCondition new_condition =
        m_inst_emulator_up->GetInstructionCondition();

    if (last_condition != new_condition) {
      // If the last instruction was conditional with a different condition
      // than the current condition then restore the state.
      if (last_condition != EmulateInstruction::UnconditionalCondition) {
        m_state = condition_block_start_state->second;
        m_state.row.SetOffset(current_offset);
        // The last instruction might already created a row for this offset
        // and we want to overwrite it.
        saved_unwind_states.insert_or_assign(current_offset, m_state);
      }

      // We are starting a new conditional block at the actual offset
      condition_block_start_state = it;
    }

    last_condition = new_condition;

    m_inst_emulator_up->EvaluateInstruction(
        eEmulateInstructionOptionIgnoreConditions);

    // If the current instruction is a branch forward then save the current
    // CFI information for the offset where we are branching.
    Address branch_address = inst.GetAddress();
    branch_address.Slide(m_branch_offset);
    if (m_branch_offset != 0 &&
        range.ContainsFileAddress(branch_address.GetFileAddress())) {
      if (auto [it, inserted] = saved_unwind_states.emplace(
              current_offset + m_branch_offset, m_state);
          inserted) {
        it->second.row.SetOffset(current_offset + m_branch_offset);
        if (std::size_t dest_instr_index =
                inst_list.GetIndexOfInstructionAtAddress(branch_address);
            dest_instr_index < inst_list.GetSize()) {
          to_visit.push_front(dest_instr_index);
          enqueued.insert(dest_instr_index);
        }
      }
    }

    // If inst is a barrier, do not propagate state to the next instruction.
    if (inst.IsBarrier())
      continue;

    // Were there any changes to the CFI while evaluating this instruction?
    if (m_curr_row_modified) {
      // Save the modified row if we don't already have a CFI row in the
      // current address
      const lldb::addr_t next_inst_offset =
          current_offset + inst.GetOpcode().GetByteSize();
      if (saved_unwind_states.count(next_inst_offset) == 0) {
        m_state.row.SetOffset(next_inst_offset);
        saved_unwind_states.emplace(next_inst_offset, m_state);
      }
    }

    const size_t next_idx = current_index + 1;
    const bool never_enqueued = enqueued.insert(next_idx).second;
    if (never_enqueued && next_idx < inst_list.GetSize())
      to_visit.push_back(next_idx);
  }

  for (auto &[_, state] : saved_unwind_states)
    unwind_plan.InsertRow(std::move(state.row),
                          /*replace_existing=*/true);

  DumpUnwindRowsToLog(log, range, unwind_plan);
  return unwind_plan.GetRowCount() > 0;
}

bool UnwindAssemblyInstEmulation::AugmentUnwindPlanFromCallSite(
    AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
  return false;
}

bool UnwindAssemblyInstEmulation::GetFastUnwindPlan(AddressRange &func,
                                                    Thread &thread,
                                                    UnwindPlan &unwind_plan) {
  return false;
}

bool UnwindAssemblyInstEmulation::FirstNonPrologueInsn(
    AddressRange &func, const ExecutionContext &exe_ctx,
    Address &first_non_prologue_insn) {
  return false;
}

UnwindAssembly *
UnwindAssemblyInstEmulation::CreateInstance(const ArchSpec &arch) {
  std::unique_ptr<EmulateInstruction> inst_emulator_up(
      EmulateInstruction::FindPlugin(arch, eInstructionTypePrologueEpilogue,
                                     nullptr));
  // Make sure that all prologue instructions are handled
  if (inst_emulator_up)
    return new UnwindAssemblyInstEmulation(arch, inst_emulator_up.release());
  return nullptr;
}

void UnwindAssemblyInstEmulation::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance);
}

void UnwindAssemblyInstEmulation::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

llvm::StringRef UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() {
  return "Instruction emulation based unwind information.";
}

uint64_t UnwindAssemblyInstEmulation::MakeRegisterKindValuePair(
    const RegisterInfo &reg_info) {
  lldb::RegisterKind reg_kind;
  uint32_t reg_num;
  if (EmulateInstruction::GetBestRegisterKindAndNumber(&reg_info, reg_kind,
                                                       reg_num))
    return (uint64_t)reg_kind << 24 | reg_num;
  return 0ull;
}

void UnwindAssemblyInstEmulation::SetRegisterValue(
    const RegisterInfo &reg_info, const RegisterValue &reg_value) {
  m_state.register_values[MakeRegisterKindValuePair(reg_info)] = reg_value;
}

bool UnwindAssemblyInstEmulation::GetRegisterValue(const RegisterInfo &reg_info,
                                                   RegisterValue &reg_value) {
  const uint64_t reg_id = MakeRegisterKindValuePair(reg_info);
  RegisterValueMap::const_iterator pos = m_state.register_values.find(reg_id);
  if (pos != m_state.register_values.end()) {
    reg_value = pos->second;
    return true; // We had a real value that comes from an opcode that wrote
                 // to it...
  }
  // We are making up a value that is recognizable...
  reg_value.SetUInt(reg_id, reg_info.byte_size);
  return false;
}

size_t UnwindAssemblyInstEmulation::ReadMemory(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
    size_t dst_len) {
  Log *log = GetLog(LLDBLog::Unwind);

  if (log && log->GetVerbose()) {
    StreamString strm;
    strm.Printf(
        "UnwindAssemblyInstEmulation::ReadMemory    (addr = 0x%16.16" PRIx64
        ", dst = %p, dst_len = %" PRIu64 ", context = ",
        addr, dst, (uint64_t)dst_len);
    context.Dump(strm, instruction);
    log->PutString(strm.GetString());
  }
  memset(dst, 0, dst_len);
  return dst_len;
}

size_t UnwindAssemblyInstEmulation::WriteMemory(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context, lldb::addr_t addr,
    const void *dst, size_t dst_len) {
  if (baton && dst && dst_len)
    return ((UnwindAssemblyInstEmulation *)baton)
        ->WriteMemory(instruction, context, addr, dst, dst_len);
  return 0;
}

size_t UnwindAssemblyInstEmulation::WriteMemory(
    EmulateInstruction *instruction, const EmulateInstruction::Context &context,
    lldb::addr_t addr, const void *dst, size_t dst_len) {
  DataExtractor data(dst, dst_len,
                     instruction->GetArchitecture().GetByteOrder(),
                     instruction->GetArchitecture().GetAddressByteSize());

  Log *log = GetLog(LLDBLog::Unwind);

  if (log && log->GetVerbose()) {
    StreamString strm;

    strm.PutCString("UnwindAssemblyInstEmulation::WriteMemory   (");
    DumpDataExtractor(data, &strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX,
                      addr, 0, 0);
    strm.PutCString(", context = ");
    context.Dump(strm, instruction);
    log->PutString(strm.GetString());
  }

  switch (context.type) {
  default:
  case EmulateInstruction::eContextInvalid:
  case EmulateInstruction::eContextReadOpcode:
  case EmulateInstruction::eContextImmediate:
  case EmulateInstruction::eContextAdjustBaseRegister:
  case EmulateInstruction::eContextRegisterPlusOffset:
  case EmulateInstruction::eContextAdjustPC:
  case EmulateInstruction::eContextRegisterStore:
  case EmulateInstruction::eContextRegisterLoad:
  case EmulateInstruction::eContextRelativeBranchImmediate:
  case EmulateInstruction::eContextAbsoluteBranchRegister:
  case EmulateInstruction::eContextSupervisorCall:
  case EmulateInstruction::eContextTableBranchReadMemory:
  case EmulateInstruction::eContextWriteRegisterRandomBits:
  case EmulateInstruction::eContextWriteMemoryRandomBits:
  case EmulateInstruction::eContextArithmetic:
  case EmulateInstruction::eContextAdvancePC:
  case EmulateInstruction::eContextReturnFromException:
  case EmulateInstruction::eContextPopRegisterOffStack:
  case EmulateInstruction::eContextAdjustStackPointer:
    break;

  case EmulateInstruction::eContextPushRegisterOnStack: {
    uint32_t reg_num = LLDB_INVALID_REGNUM;
    uint32_t generic_regnum = LLDB_INVALID_REGNUM;
    assert(context.GetInfoType() ==
               EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset &&
           "unhandled case, add code to handle this!");
    const uint32_t unwind_reg_kind = m_unwind_plan_ptr->GetRegisterKind();
    reg_num = context.info.RegisterToRegisterPlusOffset.data_reg
                  .kinds[unwind_reg_kind];
    generic_regnum = context.info.RegisterToRegisterPlusOffset.data_reg
                         .kinds[eRegisterKindGeneric];

    if (reg_num != LLDB_INVALID_REGNUM &&
        generic_regnum != LLDB_REGNUM_GENERIC_SP) {
      if (m_pushed_regs.try_emplace(reg_num, addr).second) {
        const int32_t offset = addr - m_initial_cfa;
        m_state.row.SetRegisterLocationToAtCFAPlusOffset(reg_num, offset,
                                                         /*can_replace=*/true);
        m_curr_row_modified = true;
      }
    }
  } break;
  }

  return dst_len;
}

bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
                                               void *baton,
                                               const RegisterInfo *reg_info,
                                               RegisterValue &reg_value) {

  if (baton && reg_info)
    return ((UnwindAssemblyInstEmulation *)baton)
        ->ReadRegister(instruction, reg_info, reg_value);
  return false;
}
bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction,
                                               const RegisterInfo *reg_info,
                                               RegisterValue &reg_value) {
  bool synthetic = GetRegisterValue(*reg_info, reg_value);

  Log *log = GetLog(LLDBLog::Unwind);

  if (log && log->GetVerbose()) {

    StreamString strm;
    strm.Printf("UnwindAssemblyInstEmulation::ReadRegister  (name = \"%s\") => "
                "synthetic_value = %i, value = ",
                reg_info->name, synthetic);
    DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault);
    log->PutString(strm.GetString());
  }
  return true;
}

bool UnwindAssemblyInstEmulation::WriteRegister(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context, const RegisterInfo *reg_info,
    const RegisterValue &reg_value) {
  if (baton && reg_info)
    return ((UnwindAssemblyInstEmulation *)baton)
        ->WriteRegister(instruction, context, reg_info, reg_value);
  return false;
}
bool UnwindAssemblyInstEmulation::WriteRegister(
    EmulateInstruction *instruction, const EmulateInstruction::Context &context,
    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
  Log *log = GetLog(LLDBLog::Unwind);

  if (log && log->GetVerbose()) {

    StreamString strm;
    strm.Printf(
        "UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ",
        reg_info->name);
    DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault);
    strm.PutCString(", context = ");
    context.Dump(strm, instruction);
    log->PutString(strm.GetString());
  }

  SetRegisterValue(*reg_info, reg_value);

  switch (context.type) {
  case EmulateInstruction::eContextInvalid:
  case EmulateInstruction::eContextReadOpcode:
  case EmulateInstruction::eContextImmediate:
  case EmulateInstruction::eContextAdjustBaseRegister:
  case EmulateInstruction::eContextRegisterPlusOffset:
  case EmulateInstruction::eContextAdjustPC:
  case EmulateInstruction::eContextRegisterStore:
  case EmulateInstruction::eContextSupervisorCall:
  case EmulateInstruction::eContextTableBranchReadMemory:
  case EmulateInstruction::eContextWriteRegisterRandomBits:
  case EmulateInstruction::eContextWriteMemoryRandomBits:
  case EmulateInstruction::eContextAdvancePC:
  case EmulateInstruction::eContextReturnFromException:
  case EmulateInstruction::eContextPushRegisterOnStack:
  case EmulateInstruction::eContextRegisterLoad:
    //            {
    //                const uint32_t reg_num =
    //                reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
    //                if (reg_num != LLDB_INVALID_REGNUM)
    //                {
    //                    const bool can_replace_only_if_unspecified = true;
    //
    //                    m_curr_row.SetRegisterLocationToUndefined (reg_num,
    //                                                               can_replace_only_if_unspecified,
    //                                                               can_replace_only_if_unspecified);
    //                    m_curr_row_modified = true;
    //                }
    //            }
    break;

  case EmulateInstruction::eContextArithmetic: {
    // If we adjusted the current frame pointer by a constant then adjust the
    // CFA offset
    // with the same amount.
    lldb::RegisterKind kind = m_unwind_plan_ptr->GetRegisterKind();
    if (m_state.fp_is_cfa &&
        reg_info->kinds[kind] == m_state.cfa_reg_info.kinds[kind] &&
        context.GetInfoType() ==
            EmulateInstruction::eInfoTypeRegisterPlusOffset &&
        context.info.RegisterPlusOffset.reg.kinds[kind] ==
            m_state.cfa_reg_info.kinds[kind]) {
      const int64_t offset = context.info.RegisterPlusOffset.signed_offset;
      m_state.row.GetCFAValue().IncOffset(-1 * offset);
      m_curr_row_modified = true;
    }
  } break;

  case EmulateInstruction::eContextAbsoluteBranchRegister:
  case EmulateInstruction::eContextRelativeBranchImmediate: {
    if (context.GetInfoType() == EmulateInstruction::eInfoTypeISAAndImmediate &&
        context.info.ISAAndImmediate.unsigned_data32 != 0) {
      m_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
    } else if (context.GetInfoType() ==
                   EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
               context.info.ISAAndImmediateSigned.signed_data32 != 0) {
      m_branch_offset = context.info.ISAAndImmediateSigned.signed_data32;
    } else if (context.GetInfoType() ==
                   EmulateInstruction::eInfoTypeImmediate &&
               context.info.unsigned_immediate != 0) {
      m_branch_offset = context.info.unsigned_immediate;
    } else if (context.GetInfoType() ==
                   EmulateInstruction::eInfoTypeImmediateSigned &&
               context.info.signed_immediate != 0) {
      m_branch_offset = context.info.signed_immediate;
    }
  } break;

  case EmulateInstruction::eContextPopRegisterOffStack: {
    const uint32_t reg_num =
        reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
    const uint32_t generic_regnum = reg_info->kinds[eRegisterKindGeneric];
    if (reg_num != LLDB_INVALID_REGNUM &&
        generic_regnum != LLDB_REGNUM_GENERIC_SP) {
      switch (context.GetInfoType()) {
      case EmulateInstruction::eInfoTypeAddress:
        if (auto it = m_pushed_regs.find(reg_num);
            it != m_pushed_regs.end() && context.info.address == it->second) {
          m_state.row.SetRegisterLocationToSame(reg_num,
                                                false /*must_replace*/);
          m_curr_row_modified = true;

          // FP has been restored to its original value, we are back
          // to using SP to calculate the CFA.
          if (m_state.fp_is_cfa) {
            m_state.fp_is_cfa = false;
            lldb::RegisterKind sp_reg_kind = eRegisterKindGeneric;
            uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
            RegisterInfo sp_reg_info =
                *m_inst_emulator_up->GetRegisterInfo(sp_reg_kind, sp_reg_num);
            RegisterValue sp_reg_val;
            if (GetRegisterValue(sp_reg_info, sp_reg_val)) {
              m_state.cfa_reg_info = sp_reg_info;
              const uint32_t cfa_reg_num =
                  sp_reg_info.kinds[m_unwind_plan_ptr->GetRegisterKind()];
              assert(cfa_reg_num != LLDB_INVALID_REGNUM);
              m_state.row.GetCFAValue().SetIsRegisterPlusOffset(
                  cfa_reg_num, m_initial_cfa - sp_reg_val.GetAsUInt64());
            }
          }
        }
        break;
      case EmulateInstruction::eInfoTypeISA:
        assert(
            (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
             generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
            "eInfoTypeISA used for popping a register other the PC/FLAGS");
        if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS) {
          m_state.row.SetRegisterLocationToSame(reg_num,
                                                false /*must_replace*/);
          m_curr_row_modified = true;
        }
        break;
      default:
        assert(false && "unhandled case, add code to handle this!");
        break;
      }
    }
  } break;

  case EmulateInstruction::eContextSetFramePointer:
    if (!m_state.fp_is_cfa) {
      m_state.fp_is_cfa = true;
      m_state.cfa_reg_info = *reg_info;
      const uint32_t cfa_reg_num =
          reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
      assert(cfa_reg_num != LLDB_INVALID_REGNUM);
      m_state.row.GetCFAValue().SetIsRegisterPlusOffset(
          cfa_reg_num, m_initial_cfa - reg_value.GetAsUInt64());
      m_curr_row_modified = true;
    }
    break;

  case EmulateInstruction::eContextRestoreStackPointer:
    if (m_state.fp_is_cfa) {
      m_state.fp_is_cfa = false;
      m_state.cfa_reg_info = *reg_info;
      const uint32_t cfa_reg_num =
          reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
      assert(cfa_reg_num != LLDB_INVALID_REGNUM);
      m_state.row.GetCFAValue().SetIsRegisterPlusOffset(
          cfa_reg_num, m_initial_cfa - reg_value.GetAsUInt64());
      m_curr_row_modified = true;
    }
    break;

  case EmulateInstruction::eContextAdjustStackPointer:
    // If we have created a frame using the frame pointer, don't follow
    // subsequent adjustments to the stack pointer.
    if (!m_state.fp_is_cfa) {
      m_state.row.GetCFAValue().SetIsRegisterPlusOffset(
          m_state.row.GetCFAValue().GetRegisterNumber(),
          m_initial_cfa - reg_value.GetAsUInt64());
      m_curr_row_modified = true;
    }
    break;
  }
  return true;
}
