Error ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp) { Error error; if (!new_value_sp) { error.SetErrorString("Empty value object for return value."); return error; } CompilerType clang_type = new_value_sp->GetCompilerType(); if (!clang_type) { error.SetErrorString ("Null clang type for return value."); return error; } Thread *thread = frame_sp->GetThread().get(); bool is_signed; uint32_t count; bool is_complex; RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType()) { DataExtractor data; Error data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); if (data_error.Fail()) { error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString()); return error; } lldb::offset_t offset = 0; if (num_bytes <= 8) { const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); if (num_bytes <= 4) { uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value)) set_it_simple = true; } else { uint32_t raw_value = data.GetMaxU32(&offset, 4); if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value)) { const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); if (reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value)) set_it_simple = true; } } } else { error.SetErrorString("We don't support returning longer than 64 bit integer values at present."); } } else if (clang_type.IsFloatingPointType (count, is_complex)) { if (is_complex) error.SetErrorString ("We don't support returning complex values at present"); else error.SetErrorString ("We don't support returning float values at present"); } if (!set_it_simple) error.SetErrorString ("We only support setting simple integer return types at present."); return error; }
Error RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok) { Error error; if (src.GetByteSize() == 0) { error.SetErrorString ("empty data."); return error; } if (reg_info->byte_size == 0) { error.SetErrorString ("invalid register info."); return error; } uint32_t src_len = src.GetByteSize() - src_offset; if (!partial_data_ok && (src_len < reg_info->byte_size)) { error.SetErrorString ("not enough data."); return error; } // Cap the data length if there is more than enough bytes for this register // value if (src_len > reg_info->byte_size) src_len = reg_info->byte_size; // Zero out the value in case we get partial data... memset (m_data.buffer.bytes, 0, sizeof (m_data.buffer.bytes)); switch (SetType (reg_info)) { case eTypeInvalid: error.SetErrorString(""); break; case eTypeUInt8: SetUInt8 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break; #if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: { __uint128_t data1 = src.GetU64 (&src_offset); __uint128_t data2 = src.GetU64 (&src_offset); if (src.GetByteSize() == eByteOrderBig) SetUInt128 (data1 << 64 + data2); else SetUInt128 (data2 << 64 + data1); } break; #endif case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break; case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break; case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break; case eTypeBytes: { m_data.buffer.length = reg_info->byte_size; m_data.buffer.byte_order = src.GetByteOrder(); assert (m_data.buffer.length <= kMaxRegisterByteSize); if (m_data.buffer.length > kMaxRegisterByteSize) m_data.buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData (src_offset, // offset within "src" to start extracting data src_len, // src length m_data.buffer.bytes, // dst buffer m_data.buffer.length, // dst length m_data.buffer.byte_order) == 0)// dst byte order { error.SetErrorString ("data copy failed data."); return error; } } } return error; }
Error ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp) { Error error; if (!new_value_sp) { error.SetErrorString("Empty value object for return value."); return error; } clang_type_t value_type = new_value_sp->GetClangType(); if (!value_type) { error.SetErrorString ("Null clang type for return value."); return error; } clang::ASTContext *ast_context = new_value_sp->GetClangAST(); if (!ast_context) { error.SetErrorString ("Null clang AST for return value."); return error; } Thread *thread = frame_sp->GetThread().get(); bool is_signed; uint32_t count; bool is_complex; RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type)) { DataExtractor data; size_t num_bytes = new_value_sp->GetData(data); uint32_t offset = 0; if (num_bytes <= 8) { const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0); if (num_bytes <= 4) { uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value)) set_it_simple = true; } else { uint32_t raw_value = data.GetMaxU32(&offset, 4); if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value)) { const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0); uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value)) set_it_simple = true; } } } else { error.SetErrorString("We don't support returning longer than 64 bit integer values at present."); } } else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex)) { if (is_complex) error.SetErrorString ("We don't support returning complex values at present"); else error.SetErrorString ("We don't support returning float values at present"); } if (!set_it_simple) error.SetErrorString ("We only support setting simple integer return types at present."); return error; }
Error RegisterValue::SetValueFromData(const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok) { Error error; if (src.GetByteSize() == 0) { error.SetErrorString("empty data."); return error; } if (reg_info->byte_size == 0) { error.SetErrorString("invalid register info."); return error; } uint32_t src_len = src.GetByteSize() - src_offset; if (!partial_data_ok && (src_len < reg_info->byte_size)) { error.SetErrorString("not enough data."); return error; } // Cap the data length if there is more than enough bytes for this register // value if (src_len > reg_info->byte_size) src_len = reg_info->byte_size; // Zero out the value in case we get partial data... memset(buffer.bytes, 0, sizeof(buffer.bytes)); type128 int128; m_type = eTypeInvalid; switch (reg_info->encoding) { case eEncodingInvalid: break; case eEncodingUint: case eEncodingSint: if (reg_info->byte_size == 1) SetUInt8(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 2) SetUInt16(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 4) SetUInt32(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 8) SetUInt64(src.GetMaxU64(&src_offset, src_len)); else if (reg_info->byte_size <= 16) { uint64_t data1 = src.GetU64(&src_offset); uint64_t data2 = src.GetU64(&src_offset); if (src.GetByteSize() == eByteOrderBig) { int128.x[0] = data1; int128.x[1] = data2; } else { int128.x[0] = data2; int128.x[1] = data1; } SetUInt128(llvm::APInt(128, 2, int128.x)); } break; case eEncodingIEEE754: if (reg_info->byte_size == sizeof(float)) SetFloat(src.GetFloat(&src_offset)); else if (reg_info->byte_size == sizeof(double)) SetDouble(src.GetDouble(&src_offset)); else if (reg_info->byte_size == sizeof(long double)) SetLongDouble(src.GetLongDouble(&src_offset)); break; case eEncodingVector: { m_type = eTypeBytes; buffer.length = reg_info->byte_size; buffer.byte_order = src.GetByteOrder(); assert(buffer.length <= kMaxRegisterByteSize); if (buffer.length > kMaxRegisterByteSize) buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData( src_offset, // offset within "src" to start extracting data src_len, // src length buffer.bytes, // dst buffer buffer.length, // dst length buffer.byte_order) == 0) // dst byte order { error.SetErrorStringWithFormat( "failed to copy data for register write of %s", reg_info->name); return error; } } } if (m_type == eTypeInvalid) error.SetErrorStringWithFormat( "invalid register value type for register %s", reg_info->name); return error; }