bool
RegisterContextWindows_x86::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_eax_i386:
            m_context.Eax = reg_value.GetAsUInt32();
            break;
        case lldb_ebx_i386:
            m_context.Ebx = reg_value.GetAsUInt32();
            break;
        case lldb_ecx_i386:
            m_context.Ecx = reg_value.GetAsUInt32();
            break;
        case lldb_edx_i386:
            m_context.Edx = reg_value.GetAsUInt32();
            break;
        case lldb_edi_i386:
            m_context.Edi = reg_value.GetAsUInt32();
            break;
        case lldb_esi_i386:
            m_context.Esi = reg_value.GetAsUInt32();
            break;
        case lldb_ebp_i386:
            m_context.Ebp = reg_value.GetAsUInt32();
            break;
        case lldb_esp_i386:
            m_context.Esp = reg_value.GetAsUInt32();
            break;
        case lldb_eip_i386:
            m_context.Eip = reg_value.GetAsUInt32();
            break;
        case lldb_eflags_i386:
            m_context.EFlags = reg_value.GetAsUInt32();
            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;
}
Example #3
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;
}
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
RegisterContextWindows_x86::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;

    uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    switch (reg)
    {
        case lldb_eax_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX", reg_value.GetAsUInt32());
            m_context.Eax = reg_value.GetAsUInt32();
            break;
        case lldb_ebx_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX", reg_value.GetAsUInt32());
            m_context.Ebx = reg_value.GetAsUInt32();
            break;
        case lldb_ecx_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX", reg_value.GetAsUInt32());
            m_context.Ecx = reg_value.GetAsUInt32();
            break;
        case lldb_edx_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX", reg_value.GetAsUInt32());
            m_context.Edx = reg_value.GetAsUInt32();
            break;
        case lldb_edi_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI", reg_value.GetAsUInt32());
            m_context.Edi = reg_value.GetAsUInt32();
            break;
        case lldb_esi_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI", reg_value.GetAsUInt32());
            m_context.Esi = reg_value.GetAsUInt32();
            break;
        case lldb_ebp_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP", reg_value.GetAsUInt32());
            m_context.Ebp = reg_value.GetAsUInt32();
            break;
        case lldb_esp_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP", reg_value.GetAsUInt32());
            m_context.Esp = reg_value.GetAsUInt32();
            break;
        case lldb_eip_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP", reg_value.GetAsUInt32());
            m_context.Eip = reg_value.GetAsUInt32();
            break;
        case lldb_eflags_i386:
            WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS", reg_value.GetAsUInt32());
            m_context.EFlags = reg_value.GetAsUInt32();
            break;
        default:
            WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to unknown register %u", reg_value.GetAsUInt32(),
                          reg);
    }

    // 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_i386::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) != 0)
        return false;

    switch (reg)
    {
    case gpr_eax:
    case gpr_ebx:
    case gpr_ecx:
    case gpr_edx:
    case gpr_edi:
    case gpr_esi:
    case gpr_ebp:
    case gpr_esp:
    case gpr_ss:
    case gpr_eflags:
    case gpr_eip:
    case gpr_cs:
    case gpr_ds:
    case gpr_es:
    case gpr_fs:
    case gpr_gs:
        (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
        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:
        // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
        // must be used for these registers
        ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
        return false;

    case fpu_xmm0:
    case fpu_xmm1:
    case fpu_xmm2:
    case fpu_xmm3:
    case fpu_xmm4:
    case fpu_xmm5:
    case fpu_xmm6:
    case fpu_xmm7:
        // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
        // must be used for these registers
        ::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.GetAsUInt32();
        break;

    default:
        return false;
    }
    return WriteRegisterSet(set) == 0;
}