[Lldb-commits] [lldb] r131610 - in /lldb/trunk: include/lldb/Core/RegisterValue.h include/lldb/Core/Scalar.h source/Core/ConnectionFileDescriptor.cpp source/Core/Scalar.cpp source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp

Greg Clayton gclayton at apple.com
Wed May 18 17:17:27 PDT 2011


Author: gclayton
Date: Wed May 18 19:17:26 2011
New Revision: 131610

URL: http://llvm.org/viewvc/llvm-project?rev=131610&view=rev
Log:
Added the ability to sign extend a Scalar at any bit position for integer
types.

Added the abilty to set a RegisterValue type via accessor and enum.

Added the ability to read arguments for a function for ARM if you are on the
first instruction in ABIMacOSX_arm.

Fixed an issue where a file descriptor becoming invalid could cause an 
inifnite loop spin in the libedit thread.


Modified:
    lldb/trunk/include/lldb/Core/RegisterValue.h
    lldb/trunk/include/lldb/Core/Scalar.h
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/Scalar.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp

Modified: lldb/trunk/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegisterValue.h?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegisterValue.h (original)
+++ lldb/trunk/include/lldb/Core/RegisterValue.h Wed May 18 19:17:26 2011
@@ -123,6 +123,12 @@
         bool
         CopyValue (const RegisterValue &rhs);
 
+        void
+        SetType (RegisterValue::Type type)
+        {
+            m_type = type;
+        }
+
         RegisterValue::Type
         SetType (const RegisterInfo *reg_info);
         

Modified: lldb/trunk/include/lldb/Core/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Scalar.h?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Scalar.h (original)
+++ lldb/trunk/include/lldb/Core/Scalar.h Wed May 18 19:17:26 2011
@@ -54,6 +54,9 @@
     //Scalar(const RegisterValue& reg_value);
     virtual ~Scalar();
 
+    bool
+    SignExtend (uint32_t bit_pos);
+
     size_t
     GetByteSize() const;
 

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Wed May 18 19:17:26 2011
@@ -229,7 +229,6 @@
             status = eConnectionStatusSuccess;
             return 0;
 
-        case EBADF:     // fildes is not a valid file or socket descriptor open for reading.
         case EFAULT:    // Buf points outside the allocated address space.
         case EINTR:     // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
         case EINVAL:    // The pointer associated with fildes was negative.
@@ -246,6 +245,7 @@
             status = eConnectionStatusError;
             break;  // Break to close....
 
+        case EBADF:     // fildes is not a valid file or socket descriptor open for reading.
         case ENXIO:     // An action is requested of a device that does not exist..
                         // A requested action cannot be performed by the device.
         case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
@@ -391,6 +391,8 @@
             switch (error.GetError())
             {
             case EBADF:     // One of the descriptor sets specified an invalid descriptor.
+                return eConnectionStatusLostConnection;
+
             case EINVAL:    // The specified time limit is invalid. One of its components is negative or too large.
             default:        // Other unknown error
                 return eConnectionStatusError;

Modified: lldb/trunk/source/Core/Scalar.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Scalar.cpp?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Core/Scalar.cpp (original)
+++ lldb/trunk/source/Core/Scalar.cpp Wed May 18 19:17:26 2011
@@ -1922,6 +1922,74 @@
 }
 
 bool
+Scalar::SignExtend (uint32_t sign_bit_pos)
+{
+    const uint32_t max_bit_pos = GetByteSize() * 8;
+
+    if (sign_bit_pos < max_bit_pos)
+    {
+        switch (m_type)
+        {
+        default:
+        case Scalar::e_void:
+        case Scalar::e_float:
+        case Scalar::e_double:
+        case Scalar::e_long_double: 
+            return false;
+            
+        case Scalar::e_sint:            
+        case Scalar::e_uint:
+            if (max_bit_pos == sign_bit_pos)
+                return true;
+            else if (sign_bit_pos < (max_bit_pos-1))
+            {
+                unsigned int sign_bit = 1u << sign_bit_pos;
+                if (m_data.uint & sign_bit)
+                {
+                    const unsigned int mask = ~(sign_bit) + 1u;
+                    m_data.uint |= mask;
+                }
+                return true;
+            }
+            break;
+            
+        case Scalar::e_slong:
+        case Scalar::e_ulong:
+            if (max_bit_pos == sign_bit_pos)
+                return true;
+            else if (sign_bit_pos < (max_bit_pos-1))
+            {
+                unsigned long sign_bit = 1ul << sign_bit_pos;
+                if (m_data.uint & sign_bit)
+                {
+                    const unsigned long mask = ~(sign_bit) + 1ul;
+                    m_data.uint |= mask;
+                }
+                return true;
+            }
+            break;
+            
+        case Scalar::e_slonglong:
+        case Scalar::e_ulonglong:
+            if (max_bit_pos == sign_bit_pos)
+                return true;
+            else if (sign_bit_pos < (max_bit_pos-1))
+            {
+                unsigned long long sign_bit = 1ull << sign_bit_pos;
+                if (m_data.uint & sign_bit)
+                {
+                    const unsigned long long mask = ~(sign_bit) + 1ull;
+                    m_data.uint |= mask;
+                }
+                return true;
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+bool
 lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
 {
     // If either entry is void then we can just compare the types

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=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed May 18 19:17:26 2011
@@ -175,161 +175,118 @@
     return true;
 }
 
-
-static bool 
-ReadIntegerArgument (Scalar &scalar,
-                     unsigned int bit_width,
-                     bool is_signed,
-                     Process &process,
-                     addr_t &current_stack_argument)
-{
-//    if (bit_width > 64)
-//        return false; // Scalar can't hold large integer arguments
-//    
-//    uint64_t arg_contents;
-//    uint32_t read_data;
-//    Error error;
-//    
-//    if (bit_width > 32)
-//    {
-//        if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
-//            return false;
-//        
-//        arg_contents = read_data;
-//        
-//        if (process.ReadMemory(current_stack_argument + 4, &read_data, sizeof(read_data), error) != sizeof(read_data))
-//            return false;
-//        
-//        arg_contents |= ((uint64_t)read_data) << 32;
-//        
-//        current_stack_argument += 8;
-//    }
-//    else {
-//        if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
-//            return false;
-//        
-//        arg_contents = read_data;
-//        
-//        current_stack_argument += 4;
-//    }
-//    
-//    if (is_signed)
-//    {
-//        switch (bit_width)
-//        {
-//        default:
-//            return false;
-//        case 8:
-//            scalar = (int8_t)(arg_contents & 0xff);
-//            break;
-//        case 16:
-//            scalar = (int16_t)(arg_contents & 0xffff);
-//            break;
-//        case 32:
-//            scalar = (int32_t)(arg_contents & 0xffffffff);
-//            break;
-//        case 64:
-//            scalar = (int64_t)arg_contents;
-//            break;
-//        }
-//    }
-//    else
-//    {
-//        switch (bit_width)
-//        {
-//        default:
-//            return false;
-//        case 8:
-//            scalar = (uint8_t)(arg_contents & 0xff);
-//            break;
-//        case 16:
-//            scalar = (uint16_t)(arg_contents & 0xffff);
-//            break;
-//        case 32:
-//            scalar = (uint32_t)(arg_contents & 0xffffffff);
-//            break;
-//        case 64:
-//            scalar = (uint64_t)arg_contents;
-//            break;
-//        }
-//    }
-//    
-//    return true;
-    return false;
-}
-
 bool
 ABIMacOSX_arm::GetArgumentValues (Thread &thread,
                                   ValueList &values) const
 {
-//    unsigned int num_values = values.GetSize();
-//    unsigned int value_index;
-//    
-//    // Extract the Clang AST context from the PC so that we can figure out type
-//    // sizes
-//    
-//    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-//    
-//    // Get the pointer to the first stack argument so we have a place to start 
-//    // when reading data
-//    
-//    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-//    
-//    if (!reg_ctx)
-//        return false;
-//    
-//    addr_t sp = reg_ctx->GetSP(0);
-//    
-//    if (!sp)
-//        return false;
-//    
-//    addr_t current_stack_argument = sp + 4; // jump over return address
-//    
-//    for (value_index = 0;
-//         value_index < num_values;
-//         ++value_index)
-//    {
-//        Value *value = values.GetValueAtIndex(value_index);
-//        
-//        if (!value)
-//            return false;
-//        
-//        // We currently only support extracting values with Clang QualTypes.
-//        // Do we care about others?
-//        switch (value->GetContextType())
-//        {
-//            default:
-//                return false;
-//            case Value::eContextTypeClangType:
-//            {
-//                void *value_type = value->GetClangType();
-//                bool is_signed;
-//                
-//                if (ClangASTContext::IsIntegerType (value_type, is_signed))
-//                {
-//                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-//                    
-//                    ReadIntegerArgument(value->GetScalar(),
-//                                        bit_width, 
-//                                        is_signed,
-//                                        thread.GetProcess(), 
-//                                        current_stack_argument);
-//                }
-//                else if (ClangASTContext::IsPointerType (value_type))
-//                {
-//                    ReadIntegerArgument(value->GetScalar(),
-//                                        32,
-//                                        false,
-//                                        thread.GetProcess(),
-//                                        current_stack_argument);
-//                }
-//            }
-//                break;
-//        }
-//    }
-//    
-//    return true;
-    return false;
+    uint32_t num_values = values.GetSize();
+    
+    
+    // For now, assume that the types in the AST values come from the Target's 
+    // scratch AST.    
+    
+    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+    
+    // Extract the register context so we can read arguments from registers
+    
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    
+    if (!reg_ctx)
+        return false;
+        
+    bool arg_regs_exceeded = false;
+    
+    addr_t sp = reg_ctx->GetSP(0);
+    
+    if (!sp)
+        return false;
+
+    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
+    {
+        // We currently only support extracting values with Clang QualTypes.
+        // Do we care about others?
+        Value *value = values.GetValueAtIndex(value_idx);
+        
+        if (!value)
+            return false;
+        
+        void *value_type = value->GetClangType();
+        if (value_type)
+        {
+            bool is_signed = false;
+            size_t bit_width = 0;
+            if (ClangASTContext::IsIntegerType (value_type, is_signed))
+            {
+                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+            }
+            else if (ClangASTContext::IsPointerOrReferenceType (value_type))
+            {
+                bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+            }
+            else
+            {
+                // We only handle integer, pointer and reference types currently...
+                return false;
+            }
+            
+            if (bit_width <= (thread.GetProcess().GetAddressByteSize() * 8))
+            {
+                if (!arg_regs_exceeded)
+                {
+                    uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+                    if (arg_reg_num == LLDB_INVALID_REGNUM)
+                    {
+                        arg_regs_exceeded = true;
+                    }
+                    else
+                    {
+                        const RegisterInfo *arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+                        RegisterValue reg_value;
+                        
+                        if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
+                        {
+                            if (is_signed)
+                                reg_value.SignExtend(bit_width);
+                            if (!reg_value.GetScalarValue(value->GetScalar()))
+                                return false;
+                            continue;
+                        }
+                        else
+                        {
+                            return false;
+                        }
+                    }
+                }
+                
+                
+                const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
+                if (arg_byte_size <= sizeof(uint64_t))
+                {
+                    uint8_t arg_data[sizeof(uint64_t)];
+                    Error error;
+                    thread.GetProcess().ReadMemory(sp, arg_data, sizeof(arg_data), error);
+                    DataExtractor arg_data_extractor (arg_data, sizeof(arg_data), 
+                                                      thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(), 
+                                                      thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
+                    uint32_t offset = 0;
+                    if (arg_byte_size <= 4)
+                        value->GetScalar() = arg_data_extractor.GetMaxU32 (&offset, arg_byte_size);
+                    else if (arg_byte_size <= 8)
+                        value->GetScalar() = arg_data_extractor.GetMaxU64 (&offset, arg_byte_size);
+                    else
+                        return false;
+
+                    if (offset == 0 || offset == UINT32_MAX)
+                        return false;
+
+                    if (is_signed)
+                        value->GetScalar().SignExtend (bit_width);
+                    sp += arg_byte_size;
+                }
+            }
+        }
+    }
+    return true;
 }
 
 bool





More information about the lldb-commits mailing list