예제 #1
0
ValueObjectSP
ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
                                            ClangASTType &return_clang_type) const
{
    ValueObjectSP return_valobj_sp;
    Value value;

    if (!return_clang_type)
        return return_valobj_sp;

    //value.SetContext (Value::eContextTypeClangType, return_value_type);
    value.SetClangType (return_clang_type);

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;

    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
    if (type_flags & eTypeIsScalar)
    {
        value.SetValueType(Value::eValueTypeScalar);

        bool success = false;
        if (type_flags & eTypeIsInteger)
        {
            // Extract the register context so we can read arguments from registers

            const size_t byte_size = return_clang_type.GetByteSize(nullptr);
            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
            const bool is_signed = (type_flags & eTypeIsSigned) != 0;
            switch (byte_size)
            {
            default:
                break;

            case sizeof(uint64_t):
                if (is_signed)
                    value.GetScalar() = (int64_t)(raw_value);
                else
                    value.GetScalar() = (uint64_t)(raw_value);
                success = true;
                break;

            case sizeof(uint32_t):
                if (is_signed)
                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
                else
                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
                success = true;
                break;

            case sizeof(uint16_t):
                if (is_signed)
                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
                else
                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
                success = true;
                break;

            case sizeof(uint8_t):
                if (is_signed)
                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
                else
                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
                success = true;
                break;
            }
        }
        else if (type_flags & eTypeIsFloat)
        {
            if (type_flags & eTypeIsComplex)
            {
                // Don't handle complex yet.
            }
            else
            {
                const size_t byte_size = return_clang_type.GetByteSize(nullptr);
                if (byte_size <= sizeof(long double))
                {
                    const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
                    RegisterValue f1_value;
                    if (reg_ctx->ReadRegister (f1_info, f1_value))
                    {
                        DataExtractor data;
                        if (f1_value.GetData(data))
                        {
                            lldb::offset_t offset = 0;
                            if (byte_size == sizeof(float))
                            {
                                value.GetScalar() = (float) data.GetFloat(&offset);
                                success = true;
                            }
                            else if (byte_size == sizeof(double))
                            {
                                value.GetScalar() = (double) data.GetDouble(&offset);
                                success = true;
                            }
                        }
                    }
                }
            }
        }

        if (success)
            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                               value,
                                                               ConstString(""));

    }
    else if (type_flags & eTypeIsPointer)
    {
        unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
        value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
        value.SetValueType(Value::eValueTypeScalar);
        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                           value,
                                                           ConstString(""));
    }
    else if (type_flags & eTypeIsVector)
    {
        const size_t byte_size = return_clang_type.GetByteSize(nullptr);
        if (byte_size > 0)
        {

            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
            if (altivec_reg)
            {
                if (byte_size <= altivec_reg->byte_size)
                {
                    ProcessSP process_sp (thread.GetProcess());
                    if (process_sp)
                    {
                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
                        const ByteOrder byte_order = process_sp->GetByteOrder();
                        RegisterValue reg_value;
                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
                        {
                            Error error;
                            if (reg_value.GetAsMemoryData (altivec_reg,
                                                           heap_data_ap->GetBytes(),
                                                           heap_data_ap->GetByteSize(),
                                                           byte_order,
                                                           error))
                            {
                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
                                                    byte_order,
                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
                                                                                   return_clang_type,
                                                                                   ConstString(""),
                                                                                   data);
                            }
                        }
                    }
                }
            }
        }
    }

    return return_valobj_sp;
}
예제 #2
0
ValueObjectSP
ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
{
    ValueObjectSP return_valobj_sp;
    Value value;

    ExecutionContext exe_ctx (thread.shared_from_this());
    if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
        return return_valobj_sp;

    value.SetClangType(return_clang_type);

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;

    const size_t byte_size = return_clang_type.GetByteSize(nullptr);
    const uint32_t type_flags = return_clang_type.GetTypeInfo (NULL);

    if (type_flags & eTypeIsScalar)
    {
        value.SetValueType(Value::eValueTypeScalar);

        bool success = false;
        if (type_flags & eTypeIsInteger)
        {
            // Extract the register context so we can read arguments from registers
            // In MIPS register "r2" (v0) holds the integer function return values

            uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);

            const bool is_signed = (type_flags & eTypeIsSigned) != 0;
            switch (byte_size)
            {
                default:
                    break;

                case sizeof(uint64_t):
                    if (is_signed)
                        value.GetScalar() = (int64_t)(raw_value);
                    else
                        value.GetScalar() = (uint64_t)(raw_value);
                    success = true;
                    break;

                case sizeof(uint32_t):
                    if (is_signed)
                        value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
                    else
                        value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
                    success = true;
                    break;

                case sizeof(uint16_t):
                    if (is_signed)
                        value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
                    else
                        value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
                    success = true;
                    break;

                case sizeof(uint8_t):
                    if (is_signed)
                        value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
                    else
                        value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
                    success = true;
                    break;
            }
        }

        if (success)
        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                           value,
                                                           ConstString(""));
    }
    else if (type_flags & eTypeIsPointer)
    {
        value.SetValueType(Value::eValueTypeScalar);
        uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0);
        value.GetScalar() = (uint64_t)(raw_value);

        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                           value,
                                                           ConstString(""));
    }
    else if (type_flags & eTypeIsVector)
    {
        // TODO: Handle vector types
    }
    return return_valobj_sp;
}