Example #1
0
bool
RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
{
    bool is_vacant = false;
    RegisterValue value;

    assert(hw_index < NumSupportedHardwareWatchpoints());

    if (m_watchpoints_initialized == false)
    {
        // Reset the debug status and debug control registers
        RegisterValue zero_bits = RegisterValue(uint64_t(0));
        if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
            assert(false && "Could not initialize watchpoint registers");
        m_watchpoints_initialized = true;
    }

    if (ReadRegister(dr7, value))
    {
        uint64_t val = value.GetAsUInt64();
        is_vacant = (val & (3 << 2*hw_index)) == 0;
    }

    return is_vacant;
}
uint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
                                                 uint64_t fail_value) {
  if (reg_info) {
    RegisterValue value;
    if (ReadRegister(reg_info, value))
      return value.GetAsUInt64();
  }
  return fail_value;
}
static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
                                  const EmulateInstruction::Context &context,
                                  const RegisterInfo *reg_info,
                                  const RegisterValue &reg_value) {
  if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64) {
    EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
    emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64();
  }

  return true;
}
Error
NativeRegisterContextLinux::DoWriteRegisterValue(uint32_t offset,
                                                 const char* reg_name,
                                                 const RegisterValue &value)
{
    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));

    void* buf = reinterpret_cast<void *>(value.GetAsUInt64());

    if (log)
        log->Printf ("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__, reg_name, buf);

    return NativeProcessLinux::PtraceWrapper(
            PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
}
bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];

  if (IsGPR(reg)) {
    return WriteRegister(reg, value);
  } else if (IsFPR(reg)) {
    assert(reg_info->byte_offset < sizeof(m_fpr_powerpc));
    uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
    *(uint64_t *)dst = value.GetAsUInt64();
    return WriteFPR();
  }

  return false;
}
Example #6
0
addr_t
RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
{
    addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;

    if (hw_index < NumSupportedHardwareWatchpoints())
    {
        if (!IsWatchpointVacant(hw_index))
        {
            RegisterValue value;

            if (ReadRegister(dr0 + hw_index, value))
                wp_monitor_addr = value.GetAsUInt64();
        }
    }

    return wp_monitor_addr;
}
bool
UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
                                            const EmulateInstruction::Context &context, 
                                            const RegisterInfo *reg_info,
                                            const RegisterValue &reg_value)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));

    if (log && log->GetVerbose ())
    {
        
        StreamString strm;
        strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
        reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
        strm.PutCString (", context = ");
        context.Dump(strm, instruction);
        log->PutCString(strm.GetData());
    }

    if (!instruction->IsInstructionConditional())
        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::eContextArithmetic:
        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::eContextAbsoluteBranchRegister:
        case EmulateInstruction::eContextRelativeBranchImmediate:
            {
                if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediate &&
                    context.info.ISAAndImmediate.unsigned_data32 > 0)
                {
                    m_forward_branch_offset = context.info.ISAAndImmediateSigned.signed_data32;
                }
                else if (context.info_type == EmulateInstruction::eInfoTypeISAAndImmediateSigned &&
                         context.info.ISAAndImmediateSigned.signed_data32 > 0)
                {
                    m_forward_branch_offset = context.info.ISAAndImmediate.unsigned_data32;
                }
                else if (context.info_type == EmulateInstruction::eInfoTypeImmediate &&
                         context.info.unsigned_immediate > 0)
                {
                    m_forward_branch_offset = context.info.unsigned_immediate;
                }
                else if (context.info_type == EmulateInstruction::eInfoTypeImmediateSigned &&
                         context.info.signed_immediate > 0)
                {
                    m_forward_branch_offset = context.info.signed_immediate;
                }
            }
            break;

        case EmulateInstruction::eContextPopRegisterOffStack:
            {
                if (!instruction->IsInstructionConditional())
                {
                    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.info_type)
                        {
                            case EmulateInstruction::eInfoTypeAddress:
                                if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() &&
                                    context.info.address == m_pushed_regs[reg_num])
                                {
                                    m_curr_row->SetRegisterLocationToSame(reg_num,
                                                                          false /*must_replace*/);
                                    m_curr_row_modified = true;
                                }
                                break;
                            case EmulateInstruction::eInfoTypeISA:
                                assert((generic_regnum == LLDB_REGNUM_GENERIC_PC ||
                                        generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
                                       "eInfoTypeISA used for poping a register other the the PC/FLAGS");
                                if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS)
                                {
                                    m_curr_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_fp_is_cfa && !instruction->IsInstructionConditional())
            {
                m_fp_is_cfa = true;
                m_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_curr_row->GetCFAValue().SetIsRegisterPlusOffset(cfa_reg_num, m_initial_sp -
                        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_fp_is_cfa && !instruction->IsInstructionConditional())
            {
                m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
                        m_curr_row->GetCFAValue().GetRegisterNumber(),
                        m_initial_sp - reg_value.GetAsUInt64());
                m_curr_row_modified = true;
            }
            break;
    }
    return true;
}
Example #8
0
bool
RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
{
    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    if (IsGPR(reg))
        return WriteRegister(reg, value);

    if (IsFPR(reg, GetFPRType()))
    {
        switch (reg)
        {
        default:
            if (reg_info->encoding != eEncodingVector)
                return false;

            if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
               ::memcpy (m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
            
            if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
               ::memcpy (m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
            
            if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
               if (GetFPRType() != eXSAVE)
                   return false; // the target processor does not support AVX

               // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
               ::memcpy (m_ymm_set.ymm[reg - fpu_ymm0].bytes, value.GetBytes(), value.GetByteSize());
               if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
                   return false;
            }
            break;
        case fpu_dp:
            m_fpr.xstate.fxsave.dp = value.GetAsUInt64();
            break;
        case fpu_fcw:
            m_fpr.xstate.fxsave.fcw = value.GetAsUInt16();
            break;
        case fpu_fsw:
            m_fpr.xstate.fxsave.fsw = value.GetAsUInt16();
            break;
        case fpu_ip:
            m_fpr.xstate.fxsave.ip = value.GetAsUInt64();
            break;
        case fpu_fop:
            m_fpr.xstate.fxsave.fop = value.GetAsUInt16();
            break;
        case fpu_ftw:
            m_fpr.xstate.fxsave.ftw = value.GetAsUInt16();
            break;
        case fpu_mxcsr:
            m_fpr.xstate.fxsave.mxcsr = value.GetAsUInt32();
            break;
        case fpu_mxcsrmask:
            m_fpr.xstate.fxsave.mxcsrmask = value.GetAsUInt32();
            break;
        }
        if (WriteFPR())
        {
            if (IsAVX(reg))
                return CopyYMMtoXSTATE(reg, GetByteOrder());
            return true;
        }
    }
    return false;
}
bool
RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
    // Since we cannot only write a single register value to the inferior, we need to make sure
    // our cached copy of the register values are fresh.  Otherwise when writing EAX, for example,
    // we may also overwrite some other register with a stale value.
    if (!CacheAllRegisterValues())
        return false;

    switch (reg_info->kinds[eRegisterKindLLDB])
    {
        case lldb_rax_x86_64:
            m_context.Rax = reg_value.GetAsUInt64();
            break;
        case lldb_rbx_x86_64:
            m_context.Rbx = reg_value.GetAsUInt64();
            break;
        case lldb_rcx_x86_64:
            m_context.Rcx = reg_value.GetAsUInt64();
            break;
        case lldb_rdx_x86_64:
            m_context.Rdx = reg_value.GetAsUInt64();
            break;
        case lldb_rdi_x86_64:
            m_context.Rdi = reg_value.GetAsUInt64();
            break;
        case lldb_rsi_x86_64:
            m_context.Rsi = reg_value.GetAsUInt64();
            break;
        case lldb_r8_x86_64:
            m_context.R8 = reg_value.GetAsUInt64();
            break;
        case lldb_r9_x86_64:
            m_context.R9 = reg_value.GetAsUInt64();
            break;
        case lldb_r10_x86_64:
            m_context.R10 = reg_value.GetAsUInt64();
            break;
        case lldb_r11_x86_64:
            m_context.R11 = reg_value.GetAsUInt64();
            break;
        case lldb_r12_x86_64:
            m_context.R12 = reg_value.GetAsUInt64();
            break;
        case lldb_r13_x86_64:
            m_context.R13 = reg_value.GetAsUInt64();
            break;
        case lldb_r14_x86_64:
            m_context.R14 = reg_value.GetAsUInt64();
            break;
        case lldb_r15_x86_64:
            m_context.R15 = reg_value.GetAsUInt64();
            break;
        case lldb_rbp_x86_64:
            m_context.Rbp = reg_value.GetAsUInt64();
            break;
        case lldb_rsp_x86_64:
            m_context.Rsp = reg_value.GetAsUInt64();
            break;
        case lldb_rip_x86_64:
            m_context.Rip = reg_value.GetAsUInt64();
            break;
        case lldb_rflags_x86_64:
            m_context.EFlags = reg_value.GetAsUInt64();
            break;
    }

    // Physically update the registers in the target process.
    TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
    return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
                                                const RegisterValue &value) {
  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
  int set = GetSetForNativeRegNum(reg);

  if (set == -1)
    return false;

  if (ReadRegisterSet(set, false) != KERN_SUCCESS)
    return false;

  switch (reg) {
  case gpr_x0:
  case gpr_x1:
  case gpr_x2:
  case gpr_x3:
  case gpr_x4:
  case gpr_x5:
  case gpr_x6:
  case gpr_x7:
  case gpr_x8:
  case gpr_x9:
  case gpr_x10:
  case gpr_x11:
  case gpr_x12:
  case gpr_x13:
  case gpr_x14:
  case gpr_x15:
  case gpr_x16:
  case gpr_x17:
  case gpr_x18:
  case gpr_x19:
  case gpr_x20:
  case gpr_x21:
  case gpr_x22:
  case gpr_x23:
  case gpr_x24:
  case gpr_x25:
  case gpr_x26:
  case gpr_x27:
  case gpr_x28:
  case gpr_fp:
  case gpr_sp:
  case gpr_lr:
  case gpr_pc:
  case gpr_cpsr:
    gpr.x[reg - gpr_x0] = value.GetAsUInt64();
    break;

  case fpu_v0:
  case fpu_v1:
  case fpu_v2:
  case fpu_v3:
  case fpu_v4:
  case fpu_v5:
  case fpu_v6:
  case fpu_v7:
  case fpu_v8:
  case fpu_v9:
  case fpu_v10:
  case fpu_v11:
  case fpu_v12:
  case fpu_v13:
  case fpu_v14:
  case fpu_v15:
  case fpu_v16:
  case fpu_v17:
  case fpu_v18:
  case fpu_v19:
  case fpu_v20:
  case fpu_v21:
  case fpu_v22:
  case fpu_v23:
  case fpu_v24:
  case fpu_v25:
  case fpu_v26:
  case fpu_v27:
  case fpu_v28:
  case fpu_v29:
  case fpu_v30:
  case fpu_v31:
    ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
    break;

  case fpu_fpsr:
    fpu.fpsr = value.GetAsUInt32();
    break;

  case fpu_fpcr:
    fpu.fpcr = value.GetAsUInt32();
    break;

  case exc_exception:
    exc.exception = value.GetAsUInt32();
    break;
  case exc_esr:
    exc.esr = value.GetAsUInt32();
    break;
  case exc_far:
    exc.far = value.GetAsUInt64();
    break;

  default:
    return false;
  }
  return WriteRegisterSet(set) == KERN_SUCCESS;
}
Status NativeRegisterContextLinux_s390x::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
  if (!reg_info)
    return Status("reg_info NULL");

  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
  if (reg == LLDB_INVALID_REGNUM)
    return Status("register \"%s\" is an internal-only lldb register, cannot "
                  "write directly",
                  reg_info->name);

  if (IsGPR(reg)) {
    s390_regs regs;
    Status error = DoReadGPR(&regs, sizeof(regs));
    if (error.Fail())
      return error;

    uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
    switch (reg_info->byte_size) {
    case 4:
      *(uint32_t *)dst = reg_value.GetAsUInt32();
      break;
    case 8:
      *(uint64_t *)dst = reg_value.GetAsUInt64();
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return DoWriteGPR(&regs, sizeof(regs));
  }

  if (IsFPR(reg)) {
    s390_fp_regs fp_regs;
    Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
    if (error.Fail())
      return error;

    // byte_offset is just the offset within fp_regs, not the whole user area.
    uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
    switch (reg_info->byte_size) {
    case 4:
      *(uint32_t *)dst = reg_value.GetAsUInt32();
      break;
    case 8:
      *(uint64_t *)dst = reg_value.GetAsUInt64();
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return DoWriteFPR(&fp_regs, sizeof(fp_regs));
  }

  if (reg == lldb_last_break_s390x) {
    return Status("The last break address is read-only");
  }

  if (reg == lldb_system_call_s390x) {
    uint32_t system_call = reg_value.GetAsUInt32();
    return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
  }

  return Status("failed - register wasn't recognized");
}
lldb_private::Error
NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
    Error error;

    assert (reg_info && "reg_info is null");

    const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];

    if (reg_index == LLDB_INVALID_REGNUM)
        return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");

    if (IsMSA(reg_index) && !IsMSAAvailable())
    {
        error.SetErrorString ("MSA not available on this processor");
        return error;
    }

    if (IsFPR(reg_index) || IsMSA(reg_index))
    {
        uint8_t *dst;
        uint64_t *src;

        // Initialise the FP and MSA buffers by reading all co-processor 1 registers
        ReadCP1();

        if (IsFPR(reg_index))
        {
            assert (reg_info->byte_offset < sizeof(UserArea));
            dst = (uint8_t *)&m_fpr + reg_info->byte_offset - (sizeof(m_gpr));
        }
        else
        {
            assert (reg_info->byte_offset < sizeof(UserArea));
            dst = (uint8_t *)&m_msa + reg_info->byte_offset - (sizeof(m_gpr) + sizeof(m_fpr));
        }
        switch (reg_info->byte_size)
        {
            case 4:
                *(uint32_t *)dst = reg_value.GetAsUInt32();
                break;
            case 8:
                *(uint64_t *)dst = reg_value.GetAsUInt64();
                break;
            case 16:
                src = (uint64_t *)reg_value.GetBytes();
                *(uint64_t *)dst = *src;
                *(uint64_t *)(dst + 8) = *(src + 1);
                break;
            default:
                assert(false && "Unhandled data size.");
                error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
                break;
        }
        error = WriteCP1();
        if (!error.Success())
        {
            error.SetErrorString ("failed to write co-processor 1 register");
            return error;
        }
    }
    else
    {
        error = WriteRegisterRaw(reg_index, reg_value);
    }

    return error;
}
bool
RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info,
                                           const RegisterValue &value)
{
    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);

    if (set == -1)
        return false;

    if (ReadRegisterSet(set, false) != 0)
        return false;

    switch (reg)
    {
    case gpr_rax:
    case gpr_rbx:
    case gpr_rcx:
    case gpr_rdx:
    case gpr_rdi:
    case gpr_rsi:
    case gpr_rbp:
    case gpr_rsp:
    case gpr_r8:
    case gpr_r9:
    case gpr_r10:
    case gpr_r11:
    case gpr_r12:
    case gpr_r13:
    case gpr_r14:
    case gpr_r15:
    case gpr_rip:
    case gpr_rflags:
    case gpr_cs:
    case gpr_fs:
    case gpr_gs:
        (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
        break;

    case fpu_fcw:
        fpu.fcw = value.GetAsUInt16();
        break;

    case fpu_fsw:
        fpu.fsw = value.GetAsUInt16();
        break;

    case fpu_ftw:
        fpu.ftw = value.GetAsUInt8();
        break;

    case fpu_fop:
        fpu.fop = value.GetAsUInt16();
        break;

    case fpu_ip:
        fpu.ip = value.GetAsUInt32();
        break;

    case fpu_cs:
        fpu.cs = value.GetAsUInt16();
        break;

    case fpu_dp:
        fpu.dp = value.GetAsUInt32();
        break;

    case fpu_ds:
        fpu.ds = value.GetAsUInt16();
        break;

    case fpu_mxcsr:
        fpu.mxcsr = value.GetAsUInt32();
        break;

    case fpu_mxcsrmask:
        fpu.mxcsrmask = value.GetAsUInt32();
        break;

    case fpu_stmm0:
    case fpu_stmm1:
    case fpu_stmm2:
    case fpu_stmm3:
    case fpu_stmm4:
    case fpu_stmm5:
    case fpu_stmm6:
    case fpu_stmm7:
        ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
        break;

    case fpu_xmm0:
    case fpu_xmm1:
    case fpu_xmm2:
    case fpu_xmm3:
    case fpu_xmm4:
    case fpu_xmm5:
    case fpu_xmm6:
    case fpu_xmm7:
    case fpu_xmm8:
    case fpu_xmm9:
    case fpu_xmm10:
    case fpu_xmm11:
    case fpu_xmm12:
    case fpu_xmm13:
    case fpu_xmm14:
    case fpu_xmm15:
        ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
        return false;

    case exc_trapno:
        exc.trapno = value.GetAsUInt32();
        break;

    case exc_err:
        exc.err = value.GetAsUInt32();
        break;

    case exc_faultvaddr:
        exc.faultvaddr = value.GetAsUInt64();
        break;

    default:
        return false;
    }
    return WriteRegisterSet(set) == 0;
}
bool
UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
                                            const EmulateInstruction::Context &context, 
                                            const RegisterInfo *reg_info,
                                            const RegisterValue &reg_value)
{
    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));

    if (log && log->GetVerbose ())
    {
        
        StreamString strm;
        strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name);
        reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
        strm.PutCString (", context = ");
        context.Dump(strm, instruction);
        log->PutCString(strm.GetData());
    }

    const bool must_replace = true;
    SetRegisterValue (*reg_info, reg_value);

    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::eContextPushRegisterOnStack:
//            {
//                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);
//                }
//            }
            break;

        case EmulateInstruction::eContextPopRegisterOffStack:
            {
                const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
                if (reg_num != LLDB_INVALID_REGNUM)
                {
                    m_curr_row.SetRegisterLocationToSame (reg_num, must_replace);
                }
            }
            break;

        case EmulateInstruction::eContextSetFramePointer:
            if (!m_fp_is_cfa)
            {
                m_fp_is_cfa = true;
                m_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_curr_row.SetCFARegister(cfa_reg_num);
                m_curr_row.SetCFAOffset(m_initial_sp - reg_value.GetAsUInt64());
            }
            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_fp_is_cfa)
            {
                m_curr_row.SetCFAOffset (m_initial_sp - reg_value.GetAsUInt64());
            }
            break;
    }
    return true;
}