bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
    if (!reg_info)
        return false;

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

    if (IsFPR(reg))
    {
        if (!ReadFPR())
            return false;
        uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
        value.SetUInt64(*(uint64_t*)src);
    }
    else if (IsGPR(reg))
    {
        bool success = ReadRegister(reg, value);

        if (success)
        {
            // If our return byte size was greater than the return value reg size, then
            // use the type specified by reg_info rather than the uint64_t default
            if (value.GetByteSize() > reg_info->byte_size)
                value.SetType(reg_info);
        }
        return success;
    }

    return false;
}
Ejemplo n.º 2
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;
}
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);
        if (error.Success())
        {
            // If our return byte size was greater than the return value reg size, then
            // use the type specified by reg_info rather than the uint64_t default
            if (reg_value.GetByteSize() > reg_info->byte_size)
                reg_value.SetType(reg_info);
        }
    }

    return error;
}