bool RegisterContextCorePOSIX_powerpc::ReadRegister(
    const RegisterInfo *reg_info, RegisterValue &value) {
  lldb::offset_t offset = reg_info->byte_offset;
  if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
    uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
    if (offset == reg_info->byte_offset + reg_info->byte_size) {
      value = v;
      return true;
    }
  } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
    uint32_t v[4];
    offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
    if (offset == reg_info->byte_size) {
      value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
      return true;
    }
  } else {
    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
    if (offset == reg_info->byte_offset + reg_info->byte_size) {
      if (reg_info->byte_size < sizeof(v))
        value = (uint32_t)v;
      else
        value = v;
      return true;
    }
  }
  return false;
}
bool
RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
    const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
    lldb::offset_t offset = reg_info->byte_offset;
    if (reg == syn_pc_mips64)
    {
        // Synthetic PC is the sum of:
        // (a) GP reg PC
        assert(reg_info->kinds[lldb::eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC);
        const RegisterInfo *pc_reg_info = GetRegisterInfoAtIndex(gpr_pc_mips64);
        RegisterValue reg_value;
        if (!ReadRegister(pc_reg_info, reg_value))
            return false;
        uint64_t v = reg_value.GetAsUInt64();

        // (b) Cap reg PCC base
        const RegisterInfo *pcc_reg_info = GetRegisterInfoAtIndex(cap_pcc_mips64);
        assert(pcc_reg_info->byte_size == 32);
        offset = pcc_reg_info->byte_offset + 16;
        uint64_t pcc_base = m_cr.GetMaxU64(&offset, 8);
        if (offset == pcc_reg_info->byte_offset + 24)
            v += pcc_base;

        // (c) Offset if Cause indicates exception occurred in branch delay slot
        if (m_in_bd == lldb_private::eLazyBoolCalculate)
            m_in_bd = CauseBD() ? lldb_private::eLazyBoolYes : lldb_private::eLazyBoolNo;
        if (m_in_bd == lldb_private::eLazyBoolYes)
            v += 4;

        value = v;
        return true;
    }
    else if (reg <= gpr_dummy_mips64)
    {
        uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
        if (offset == reg_info->byte_offset + reg_info->byte_size)
        {
            value = v;
            return true;
        }
    }
    else
    {
        uint8_t buf[32];
        assert(reg_info->byte_size == 32);
        if (m_cr.CopyData(offset, 32, buf) == reg_info->byte_size)
        {
            value.SetBytes(buf, 32, m_cr.GetByteOrder());
            return true;
        }
    }
    return false;
}
Error
NativeRegisterContextLinux_mips64::DoReadRegisterValue(uint32_t offset,
                                                       const char* reg_name,
                                                       uint32_t size,
                                                       RegisterValue &value)
{
    GPR_linux_mips regs;
    ::memset(&regs, 0, sizeof(GPR_linux_mips));

    // Clear all bits in RegisterValue before writing actual value read from ptrace to avoid garbage value in 32-bit MSB 
    value.SetBytes((void *)(((unsigned char *)&regs) + offset), 8, GetByteOrder());
    Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
    if (error.Success())
    {
        lldb_private::ArchSpec arch;
        if (m_thread.GetProcess()->GetArchitecture(arch))
            value.SetBytes((void *)(((unsigned char *)&regs) + offset + 4 * (arch.GetMachine() == llvm::Triple::mips)), arch.GetFlags() & lldb_private::ArchSpec::eMIPSABI_O32 ? 4 : 8, arch.GetByteOrder());
        else
            error.SetErrorString("failed to get architecture");
    }
    return error;
}
Error
NativeRegisterContextLinux_mips64::DoReadRegisterValue(uint32_t offset,
                                                       const char* reg_name,
                                                       uint32_t size,
                                                       RegisterValue &value)
{
    GPR_linux_mips regs;
    ::memset(&regs, 0, sizeof(GPR_linux_mips));
    Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
    if (error.Success())
    {
        lldb_private::ArchSpec arch;
        if (m_thread.GetProcess()->GetArchitecture(arch))
            value.SetBytes((void *)(((unsigned char *)&regs) + offset + 4 * (arch.GetMachine() == llvm::Triple::mips)), arch.GetAddressByteSize(), arch.GetByteOrder());
        else
            error.SetErrorString("failed to get architecture");
    }
    return error;
}
Example #5
0
bool
RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
    if (!reg_info)
        return false;

    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];

    if (IsFPR(reg, GetFPRType()))
    {
        if (!ReadFPR())
            return false;
    }
    else
    {
        bool success = ReadRegister(reg, value);

        // If an i386 register should be parsed from an x86_64 register...
        if (success && reg >= k_first_i386 && reg <= k_last_i386)
            if (value.GetByteSize() > reg_info->byte_size)
                value.SetType(reg_info); // ...use the type specified by reg_info rather than the uint64_t default
        return success; 
    }

    if (reg_info->encoding == eEncodingVector)
    {
        ByteOrder byte_order = GetByteOrder();

        if (byte_order != ByteOrder::eByteOrderInvalid)
        {
            if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
               value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, byte_order);
            if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
                value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, byte_order);
            if (reg >= fpu_ymm0 && reg <= fpu_ymm15)
            {
                // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
                if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
                    value.SetBytes(m_ymm_set.ymm[reg - fpu_ymm0].bytes, reg_info->byte_size, byte_order);
                else
                    return false;
            }
            return value.GetType() == RegisterValue::eTypeBytes;
        }
        return false;
    }

    // Note that lldb uses slightly different naming conventions from sys/user.h
    switch (reg)
    {
    default:
        return false;
    case fpu_dp:
        value = m_fpr.xstate.fxsave.dp;
        break;
    case fpu_fcw:
        value = m_fpr.xstate.fxsave.fcw;
        break;
    case fpu_fsw:
        value = m_fpr.xstate.fxsave.fsw;
        break;
    case fpu_ip:
        value = m_fpr.xstate.fxsave.ip;
        break;
    case fpu_fop:
        value = m_fpr.xstate.fxsave.fop;
        break;
    case fpu_ftw:
        value = m_fpr.xstate.fxsave.ftw;
        break;
    case fpu_mxcsr:
        value = m_fpr.xstate.fxsave.mxcsr;
        break;
    case fpu_mxcsrmask:
        value = m_fpr.xstate.fxsave.mxcsrmask;
        break;
    }
    return true;
}
bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
                                               RegisterValue &value) {
  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
  int set = RegisterContextDarwin_arm64::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:
    value.SetUInt64(gpr.x[reg - gpr_x0]);
    break;

  case gpr_w0:
  case gpr_w1:
  case gpr_w2:
  case gpr_w3:
  case gpr_w4:
  case gpr_w5:
  case gpr_w6:
  case gpr_w7:
  case gpr_w8:
  case gpr_w9:
  case gpr_w10:
  case gpr_w11:
  case gpr_w12:
  case gpr_w13:
  case gpr_w14:
  case gpr_w15:
  case gpr_w16:
  case gpr_w17:
  case gpr_w18:
  case gpr_w19:
  case gpr_w20:
  case gpr_w21:
  case gpr_w22:
  case gpr_w23:
  case gpr_w24:
  case gpr_w25:
  case gpr_w26:
  case gpr_w27:
  case gpr_w28: {
    ProcessSP process_sp(m_thread.GetProcess());
    if (process_sp.get()) {
      DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(),
                            process_sp->GetAddressByteSize());
      offset_t offset = 0;
      uint64_t retval = regdata.GetMaxU64(&offset, 8);
      uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff);
      value.SetUInt32(retval_lower32);
    }
  } 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:
    value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size,
                   endian::InlHostByteOrder());
    break;

  case fpu_s0:
  case fpu_s1:
  case fpu_s2:
  case fpu_s3:
  case fpu_s4:
  case fpu_s5:
  case fpu_s6:
  case fpu_s7:
  case fpu_s8:
  case fpu_s9:
  case fpu_s10:
  case fpu_s11:
  case fpu_s12:
  case fpu_s13:
  case fpu_s14:
  case fpu_s15:
  case fpu_s16:
  case fpu_s17:
  case fpu_s18:
  case fpu_s19:
  case fpu_s20:
  case fpu_s21:
  case fpu_s22:
  case fpu_s23:
  case fpu_s24:
  case fpu_s25:
  case fpu_s26:
  case fpu_s27:
  case fpu_s28:
  case fpu_s29:
  case fpu_s30:
  case fpu_s31: {
    ProcessSP process_sp(m_thread.GetProcess());
    if (process_sp.get()) {
      DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(),
                            process_sp->GetAddressByteSize());
      offset_t offset = 0;
      value.SetFloat(regdata.GetFloat(&offset));
    }
  } break;

  case fpu_d0:
  case fpu_d1:
  case fpu_d2:
  case fpu_d3:
  case fpu_d4:
  case fpu_d5:
  case fpu_d6:
  case fpu_d7:
  case fpu_d8:
  case fpu_d9:
  case fpu_d10:
  case fpu_d11:
  case fpu_d12:
  case fpu_d13:
  case fpu_d14:
  case fpu_d15:
  case fpu_d16:
  case fpu_d17:
  case fpu_d18:
  case fpu_d19:
  case fpu_d20:
  case fpu_d21:
  case fpu_d22:
  case fpu_d23:
  case fpu_d24:
  case fpu_d25:
  case fpu_d26:
  case fpu_d27:
  case fpu_d28:
  case fpu_d29:
  case fpu_d30:
  case fpu_d31: {
    ProcessSP process_sp(m_thread.GetProcess());
    if (process_sp.get()) {
      DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(),
                            process_sp->GetAddressByteSize());
      offset_t offset = 0;
      value.SetDouble(regdata.GetDouble(&offset));
    }
  } break;

  case fpu_fpsr:
    value.SetUInt32(fpu.fpsr);
    break;

  case fpu_fpcr:
    value.SetUInt32(fpu.fpcr);
    break;

  case exc_exception:
    value.SetUInt32(exc.exception);
    break;
  case exc_esr:
    value.SetUInt32(exc.esr);
    break;
  case exc_far:
    value.SetUInt64(exc.far);
    break;

  default:
    value.SetValueToInvalid();
    return false;
  }
  return true;
}
bool
RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
{
    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    int set = RegisterContextDarwin_arm64::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:
        value.SetUInt64 (gpr.x[reg - gpr_x0]);
        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:
        value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_fpsr:
        value.SetUInt32 (fpu.fpsr);
        break;

    case fpu_fpcr:
        value.SetUInt32 (fpu.fpcr);
        break;

    case exc_exception:
        value.SetUInt32 (exc.exception);
        break;
    case exc_esr:
        value.SetUInt32 (exc.esr);
        break;
    case exc_far:
        value.SetUInt64 (exc.far);
        break;

    default:
        value.SetValueToInvalid();
        return false;

    }
    return true;
}
lldb_private::Error
NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
{
    Error error;

    if (!reg_info)
    {
        error.SetErrorString ("reg_info NULL");
        return error;
    }

    const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
    if (reg == LLDB_INVALID_REGNUM)
    {
        // This is likely an internal register for lldb use only and should not be directly queried.
        error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
        return error;
    }

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

    if (IsMSA(reg) || IsFPR(reg))
    {
        uint8_t *src;

        error = ReadCP1();

        if (!error.Success())
        {
            error.SetErrorString ("failed to read co-processor 1 register");
            return error;
        }

        if (IsFPR(reg))
        {
            assert (reg_info->byte_offset < sizeof(UserArea));
            src = (uint8_t *)&m_fpr + reg_info->byte_offset - (sizeof(m_gpr));
        }
        else
        {
            assert (reg_info->byte_offset < sizeof(UserArea));
            src = (uint8_t *)&m_msa + reg_info->byte_offset - (sizeof(m_gpr) + sizeof(m_fpr));
        }
        switch (reg_info->byte_size)
        {
            case 4:
                reg_value.SetUInt32(*(uint32_t *)src);
                break;
            case 8:
                reg_value.SetUInt64(*(uint64_t *)src);
                break;
            case 16:
                reg_value.SetBytes((const void *)src, 16, GetByteOrder());
                break;
            default:
                assert(false && "Unhandled data size.");
                error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
                break;
        }
    }
    else
    {
        error = ReadRegisterRaw(reg, reg_value);
    }

    return error;
}
bool
RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info,
                                          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:
        value = (&gpr.rax)[reg - gpr_rax];
        break;

    case fpu_fcw:
        value = fpu.fcw;
        break;

    case fpu_fsw:
        value = fpu.fsw;
        break;

    case fpu_ftw:
        value = fpu.ftw;
        break;

    case fpu_fop:
        value = fpu.fop;
        break;

    case fpu_ip:
        value = fpu.ip;
        break;

    case fpu_cs:
        value = fpu.cs;
        break;

    case fpu_dp:
        value = fpu.dp;
        break;

    case fpu_ds:
        value = fpu.ds;
        break;

    case fpu_mxcsr:
        value = fpu.mxcsr;
        break;

    case fpu_mxcsrmask:
        value = fpu.mxcsrmask;
        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:
        value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        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:
        value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case exc_trapno:
        value = exc.trapno;
        break;

    case exc_err:
        value = exc.err;
        break;

    case exc_faultvaddr:
        value = exc.faultvaddr;
        break;

    default:
        return false;
    }
    return true;
}