[Lldb-commits] [lldb] r169924 - in /lldb/trunk: source/Expression/IRInterpreter.cpp test/lang/objc/objc-optimized/TestObjcOptimized.py

Sean Callanan scallanan at apple.com
Tue Dec 11 14:39:36 PST 2012


Author: spyffe
Date: Tue Dec 11 16:39:36 2012
New Revision: 169924

URL: http://llvm.org/viewvc/llvm-project?rev=169924&view=rev
Log:
Fixed the IRInterpreter's handling of "this" and
"self" when those pointers are in registers.
Previously in this case the IRInterpreter would
handle them just as if the user had typed in
"$rdi", which isn't safe because $rdi is passed
in through the argument struct.

Now we correctly break out all three cases (i.e.,
normal variables in registers, $reg, and this/self),
and handle them in a way that's a little bit easier
to read and change.

This results in more accurate printing of "this" and
"self" pointers all around.  I have strengthened the
optimized-code test case for Objective-C to ensure
that we catch regressions in this area reliably in
the future.

<rdar://problem/12693963>

Modified:
    lldb/trunk/source/Expression/IRInterpreter.cpp
    lldb/trunk/test/lang/objc/objc-optimized/TestObjcOptimized.py

Modified: lldb/trunk/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRInterpreter.cpp?rev=169924&r1=169923&r2=169924&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRInterpreter.cpp (original)
+++ lldb/trunk/source/Expression/IRInterpreter.cpp Tue Dec 11 16:39:36 2012
@@ -619,7 +619,7 @@
         // array then we need to build an extra level of indirection
         // for it.  This is the default; only magic arguments like
         // "this", "self", and "_cmd" are direct.
-        bool indirect_variable = true; 
+        bool variable_is_this = false;
         
         // Attempt to resolve the value using the program's data.
         // If it is, the values to be created are:
@@ -664,69 +664,121 @@
                     name_str == "_cmd")
                     resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
                 
-                indirect_variable = false;
+                variable_is_this = true;
             }
             
             if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
             {
                 if (resolved_value.GetContextType() == lldb_private::Value::eContextTypeRegisterInfo)
                 {
-                    bool bare_register = (flags & lldb_private::ClangExpressionVariable::EVBareRegister);
-
-                    if (bare_register)
-                        indirect_variable = false;
-                    
-                    lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
-                    Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
+                    if (variable_is_this)
+                    {
+                        Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
+                        
+                        lldb_private::Value origin;
+                        
+                        origin.SetValueType(lldb_private::Value::eValueTypeLoadAddress);
+                        origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
+                        origin.GetScalar() = resolved_value.GetScalar();
+                        
+                        data_region.m_allocation->m_origin = origin;
+                        
+                        Memory::Region ref_region = m_memory.Malloc(value->getType());
+                         
+                        if (ref_region.IsInvalid())
+                            return Memory::Region();
+                        
+                        DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+                        
+                        if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+                            return Memory::Region();
+                        
+                        if (log)
+                        {
+                            log->Printf("Made an allocation for \"this\" register variable %s", PrintValue(value).c_str());
+                            log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
+                            log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
+                        }
+                        
+                        m_values[value] = ref_region;
+                        return ref_region;
+                    }
+                    else if (flags & lldb_private::ClangExpressionVariable::EVBareRegister)
+                    {                        
+                        lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
+                        Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
                         m_memory.Malloc(reg_info->byte_size, m_target_data.getPrefTypeAlignment(value->getType())) :
                         m_memory.Malloc(value->getType());
-
-                    data_region.m_allocation->m_origin = resolved_value;
-                    Memory::Region ref_region = m_memory.Malloc(value->getType());
-                    Memory::Region pointer_region;
-                    
-                    if (indirect_variable)
+                        
+                        data_region.m_allocation->m_origin = resolved_value;
+                        Memory::Region ref_region = m_memory.Malloc(value->getType());
+                        
+                        if (!Cache(data_region.m_allocation, value->getType()))
+                            return Memory::Region();
+                        
+                        if (ref_region.IsInvalid())
+                            return Memory::Region();
+                        
+                        DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+                        
+                        if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+                            return Memory::Region();
+                        
+                        if (log)
+                        {
+                            log->Printf("Made an allocation for bare register variable %s", PrintValue(value).c_str());
+                            log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
+                            log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
+                            log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
+                        }
+                        
+                        m_values[value] = ref_region;
+                        return ref_region;
+                    }
+                    else
+                    {                        
+                        lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
+                        Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
+                        m_memory.Malloc(reg_info->byte_size, m_target_data.getPrefTypeAlignment(value->getType())) :
+                        m_memory.Malloc(value->getType());
+                        
+                        data_region.m_allocation->m_origin = resolved_value;
+                        Memory::Region ref_region = m_memory.Malloc(value->getType());
+                        Memory::Region pointer_region;
+                        
                         pointer_region = m_memory.Malloc(value->getType());
-                    
-                    if (!Cache(data_region.m_allocation, value->getType()))
-                        return Memory::Region();
-
-                    if (ref_region.IsInvalid())
-                        return Memory::Region();
-                    
-                    if (pointer_region.IsInvalid() && indirect_variable)
-                        return Memory::Region();
-                    
-                    DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
-                    
-                    if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
-                        return Memory::Region();
-                    
-                    if (log)
-                    {
-                        log->Printf("Made an allocation for register variable %s", PrintValue(value).c_str());
-                        log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
-                        log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
-                        log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
-                        if (indirect_variable)
+                        
+                        if (!Cache(data_region.m_allocation, value->getType()))
+                            return Memory::Region();
+                        
+                        if (ref_region.IsInvalid())
+                            return Memory::Region();
+                        
+                        if (pointer_region.IsInvalid())
+                            return Memory::Region();
+                        
+                        DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+                        
+                        if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+                            return Memory::Region();
+                        
+                        if (log)
+                        {
+                            log->Printf("Made an allocation for ordinary register variable %s", PrintValue(value).c_str());
+                            log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
+                            log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
+                            log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
                             log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
-                    }
-                    
-                    if (indirect_variable)
-                    {
-                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+                        }
                         
+                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+                            
                         if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
                             return Memory::Region();
                         
                         m_values[value] = pointer_region;
                         return pointer_region;
                     }
-                    else
-                    {
-                        m_values[value] = ref_region;
-                        return ref_region;
-                    }
                 }
                 else
                 {
@@ -734,13 +786,13 @@
                     Memory::Region ref_region = m_memory.Malloc(value->getType());
                     Memory::Region pointer_region;
                     
-                    if (indirect_variable)
+                    if (!variable_is_this)
                         pointer_region = m_memory.Malloc(value->getType());
                            
                     if (ref_region.IsInvalid())
                         return Memory::Region();
                     
-                    if (pointer_region.IsInvalid() && indirect_variable)
+                    if (pointer_region.IsInvalid() && !variable_is_this)
                         return Memory::Region();
                     
                     DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -748,7 +800,7 @@
                     if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
                         return Memory::Region();
                     
-                    if (indirect_variable)
+                    if (!variable_is_this)
                     {
                         DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
                     
@@ -764,14 +816,14 @@
                         log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
                         log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
                         log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
-                        if (indirect_variable)
+                        if (!variable_is_this)
                             log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
                     }
                     
-                    if (indirect_variable)
-                        return pointer_region;
-                    else 
+                    if (variable_is_this)
                         return ref_region;
+                    else
+                        return pointer_region;
                 }
             }
         }

Modified: lldb/trunk/test/lang/objc/objc-optimized/TestObjcOptimized.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/objc-optimized/TestObjcOptimized.py?rev=169924&r1=169923&r2=169924&view=diff
==============================================================================
--- lldb/trunk/test/lang/objc/objc-optimized/TestObjcOptimized.py (original)
+++ lldb/trunk/test/lang/objc/objc-optimized/TestObjcOptimized.py Tue Dec 11 16:39:36 2012
@@ -12,6 +12,7 @@
 import lldb
 from lldbtest import *
 import lldbutil
+import re
 
 # rdar://problem/9087739
 # test failure: objc_optimized does not work for "-C clang -A i386"
@@ -50,8 +51,21 @@
         self.expect('expression member',
             startstr = "(int) $0 = 5")
 
-        self.expect('expression self',
-            startstr = "(%s *) $1 = " % self.myclass)
+        # <rdar://problem/12693963>
+        interp = self.dbg.GetCommandInterpreter()
+        result = lldb.SBCommandReturnObject()
+        interp.HandleCommand('frame variable self', result)
+        output = result.GetOutput()
+
+        desired_pointer = "0x0"
+
+        mo = re.search("0x[0-9a-f]+", output)
+
+        if mo:
+            desired_pointer = mo.group(0)
+
+        self.expect('expression (self)',
+            substrs = [("(%s *) $1 = " % self.myclass), desired_pointer])
 
         self.expect('expression self->non_member', error=True,
             substrs = ["does not have a member named 'non_member'"])





More information about the lldb-commits mailing list