[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