[Lldb-commits] [lldb] r164741 - in /lldb/trunk/source: Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h Target/Thread.cpp
Jim Ingham
jingham at apple.com
Wed Sep 26 18:15:29 PDT 2012
Author: jingham
Date: Wed Sep 26 20:15:29 2012
New Revision: 164741
URL: http://llvm.org/viewvc/llvm-project?rev=164741&view=rev
Log:
Implement returning integer values in "thread return" for arm, x86_64 and i386. Also returns
floats & doubles on x86_64.
<rdar://problem/8356523>
Modified:
lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
lldb/trunk/source/Target/Thread.cpp
Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=164741&r1=164740&r2=164741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed Sep 26 20:15:29 2012
@@ -508,10 +508,83 @@
}
Error
-ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value)
+ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
{
- Error return_error("I can't do that yet Jim.");
- return return_error;
+ 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;
}
bool
Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=164741&r1=164740&r2=164741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Wed Sep 26 20:15:29 2012
@@ -687,6 +687,86 @@
return true;
}
+Error
+ABIMacOSX_i386::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 *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+ if (num_bytes <= 4)
+ {
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
+ set_it_simple = true;
+ }
+ else
+ {
+ uint32_t raw_value = data.GetMaxU32(&offset, 4);
+
+ if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
+ {
+ const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
+ uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+
+ if (reg_ctx->WriteRegisterFromUnsigned (edx_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;
+}
+
ValueObjectSP
ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
ClangASTType &ast_type) const
@@ -774,13 +854,6 @@
return return_valobj_sp;
}
-Error
-ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value)
-{
- Error return_error("I can't do that yet Jim.");
- return return_error;
-}
-
bool
ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=164741&r1=164740&r2=164741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Wed Sep 26 20:15:29 2012
@@ -550,6 +550,100 @@
return true;
}
+Error
+ABISysV_x86_64::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))
+ {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
+
+ DataExtractor data;
+ size_t num_bytes = new_value_sp->GetData(data);
+ uint32_t offset = 0;
+ if (num_bytes <= 64)
+ {
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ if (reg_ctx->WriteRegisterFromUnsigned (reg_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
+ {
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ if (bit_width <= 64)
+ {
+ const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ DataExtractor data;
+ size_t num_bytes = new_value_sp->GetData(data);
+
+ unsigned char buffer[16];
+ ByteOrder byte_order = data.GetByteOrder();
+ uint32_t return_bytes;
+
+ return_bytes = data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
+ xmm0_value.SetBytes(buffer, 16, byte_order);
+ reg_ctx->WriteRegister(xmm0_info, xmm0_value);
+ set_it_simple = true;
+ }
+ else
+ {
+ // FIXME - don't know how to do 80 bit long doubles yet.
+ error.SetErrorString ("We don't support returning float values > 64 bits at present");
+ }
+ }
+ }
+
+ if (!set_it_simple)
+ {
+ // Okay we've got a structure or something that doesn't fit in a simple register.
+ // We should figure out where it really goes, but we don't support this yet.
+ error.SetErrorString ("We only support setting simple integer and float return types at present.");
+ }
+
+ return error;
+}
+
+
ValueObjectSP
ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
ClangASTType &ast_type) const
@@ -584,7 +678,7 @@
// Extract the register context so we can read arguments from registers
size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
- unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
switch (bit_width)
{
@@ -594,27 +688,27 @@
return return_valobj_sp;
case 64:
if (is_signed)
- value.GetScalar() = (int64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
+ value.GetScalar() = (int64_t)(raw_value);
else
- value.GetScalar() = (uint64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
+ value.GetScalar() = (uint64_t)(raw_value);
break;
case 32:
if (is_signed)
- value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
+ value.GetScalar() = (int32_t)(raw_value & 0xffffffff);
else
- value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
+ value.GetScalar() = (uint32_t)(raw_value & 0xffffffff);
break;
case 16:
if (is_signed)
- value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
+ value.GetScalar() = (int16_t)(raw_value & 0xffff);
else
- value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
+ value.GetScalar() = (uint16_t)(raw_value & 0xffff);
break;
case 8:
if (is_signed)
- value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
+ value.GetScalar() = (int8_t)(raw_value & 0xff);
else
- value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
+ value.GetScalar() = (uint8_t)(raw_value & 0xff);
break;
}
}
@@ -959,13 +1053,6 @@
return return_valobj_sp;
}
-Error
-ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value)
-{
- Error return_error("I can't do that yet Jim.");
- return return_error;
-}
-
bool
ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h?rev=164741&r1=164740&r2=164741&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h Wed Sep 26 20:15:29 2012
@@ -52,6 +52,7 @@
lldb::ValueObjectSP
GetReturnValueObjectSimple (lldb_private::Thread &thread,
lldb_private::ClangASTType &ast_type) const;
+
public:
virtual lldb::ValueObjectSP
GetReturnValueObjectImpl (lldb_private::Thread &thread,
Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=164741&r1=164740&r2=164741&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Wed Sep 26 20:15:29 2012
@@ -15,6 +15,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Host/Host.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -1313,14 +1314,37 @@
StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
if (return_value_sp)
- {
- // TODO: coerce the return_value_sp to the type of the function in frame_sp.
-
+ {
lldb::ABISP abi = thread->GetProcess()->GetABI();
if (!abi)
{
return_error.SetErrorString("Could not find ABI to set return value.");
}
+ SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextFunction);
+
+ // FIXME: ValueObject::Cast doesn't currently work correctly, at least not for scalars.
+ // Turn that back on when that works.
+ if (0 && sc.function != NULL)
+ {
+ Type *function_type = sc.function->GetType();
+ if (function_type)
+ {
+ clang_type_t return_type = sc.function->GetReturnClangType();
+ if (return_type)
+ {
+ ClangASTType ast_type (function_type->GetClangAST(), return_type);
+ StreamString s;
+ ast_type.DumpTypeDescription(&s);
+ ValueObjectSP cast_value_sp = return_value_sp->Cast(ast_type);
+ if (cast_value_sp)
+ {
+ cast_value_sp->SetFormat(eFormatHex);
+ return_value_sp = cast_value_sp;
+ }
+ }
+ }
+ }
+
return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp);
if (!return_error.Success())
return return_error;
More information about the lldb-commits
mailing list