[Lldb-commits] [lldb] r175662 - Handle the case where the runtime uses class_getMethodImplementation for both scalar and structure

Jim Ingham jingham at apple.com
Wed Feb 20 12:35:39 PST 2013


Author: jingham
Date: Wed Feb 20 14:35:38 2013
New Revision: 175662

URL: http://llvm.org/viewvc/llvm-project?rev=175662&view=rev
Log:
Handle the case where the runtime uses class_getMethodImplementation for both scalar and structure
return methods.

rdar://problem/13238168

Modified:
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=175662&r1=175661&r2=175662&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Wed Feb 20 14:35:38 2013
@@ -43,7 +43,8 @@ using namespace lldb;
 using namespace lldb_private;
 
 const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = "                               \n\
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL;
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = "                               \n\
 extern \"C\"                                                                                                    \n\
 {                                                                                                               \n\
     extern void *class_getMethodImplementation(void *objc_class, void *sel);                                    \n\
@@ -152,6 +153,106 @@ extern \"C\" void * __lldb_objc_find_imp
     return return_struct.impl_addr;                                                                             \n\
 }                                                                                                               \n\
 ";
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = "                      \n\
+extern \"C\"                                                                                                    \n\
+{                                                                                                               \n\
+    extern void *class_getMethodImplementation(void *objc_class, void *sel);                                    \n\
+    extern void * sel_getUid(char *name);                                                                       \n\
+    extern int printf(const char *format, ...);                                                                 \n\
+}                                                                                                               \n\
+extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object,                                 \n\
+                                                    void *sel,                                                  \n\
+                                                    int is_stret,                                               \n\
+                                                    int is_super,                                               \n\
+                                                    int is_super2,                                              \n\
+                                                    int is_fixup,                                               \n\
+                                                    int is_fixed,                                               \n\
+                                                    int debug)                                                  \n\
+{                                                                                                               \n\
+    struct __lldb_imp_return_struct                                                                             \n\
+    {                                                                                                           \n\
+        void *class_addr;                                                                                       \n\
+        void *sel_addr;                                                                                         \n\
+        void *impl_addr;                                                                                        \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    struct __lldb_objc_class {                                                                                  \n\
+        void *isa;                                                                                              \n\
+        void *super_ptr;                                                                                        \n\
+    };                                                                                                          \n\
+    struct __lldb_objc_super {                                                                                  \n\
+        void *reciever;                                                                                         \n\
+        struct __lldb_objc_class *class_ptr;                                                                    \n\
+    };                                                                                                          \n\
+    struct __lldb_msg_ref {                                                                                     \n\
+        void *dont_know;                                                                                        \n\
+        void *sel;                                                                                              \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    struct __lldb_imp_return_struct return_struct;                                                              \n\
+                                                                                                                \n\
+    if (debug)                                                                                                  \n\
+        printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \"                          \n\
+                \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\",                                               \n\
+                 object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed);                               \n\
+    if (is_super)                                                                                               \n\
+    {                                                                                                           \n\
+        if (is_super2)                                                                                          \n\
+        {                                                                                                       \n\
+            return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr;                    \n\
+        }                                                                                                       \n\
+        else                                                                                                    \n\
+        {                                                                                                       \n\
+            return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr;                               \n\
+        }                                                                                                       \n\
+    }                                                                                                           \n\
+    else                                                                                                        \n\
+    {                                                                                                           \n\
+        void *class_ptr = (void *) [(id) object class];                                                         \n\
+        if (class_ptr == object)                                                                                \n\
+        {                                                                                                       \n\
+            struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr;           \n\
+            if (debug)                                                                                          \n\
+                printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\",                \n\
+                        class_ptr, class_as_class_struct->isa);                                                 \n\
+            return_struct.class_addr = class_as_class_struct->isa;                                              \n\
+        }                                                                                                       \n\
+        else                                                                                                    \n\
+        {                                                                                                       \n\
+            if (debug)                                                                                          \n\
+                printf (\"[object class] returned: 0x%p.\\n\", class_ptr);                                      \n\
+            return_struct.class_addr = class_ptr;                                                               \n\
+        }                                                                                                       \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    if (is_fixup)                                                                                               \n\
+    {                                                                                                           \n\
+        if (is_fixed)                                                                                           \n\
+        {                                                                                                       \n\
+            return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel;                                             \n\
+        }                                                                                                       \n\
+        else                                                                                                    \n\
+        {                                                                                                       \n\
+            char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel;                                            \n\
+            return_struct.sel_addr = sel_getUid (sel_name);                                                     \n\
+            if (debug)                                                                                          \n\
+                printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\",                                 \n\
+                        return_struct.sel_addr, sel_name);                                                      \n\
+        }                                                                                                       \n\
+    }                                                                                                           \n\
+    else                                                                                                        \n\
+    {                                                                                                           \n\
+        return_struct.sel_addr = sel;                                                                           \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr,                          \n\
+                                                             return_struct.sel_addr);                           \n\
+    if (debug)                                                                                                  \n\
+        printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr);                        \n\
+                                                                                                                \n\
+    return return_struct.impl_addr;                                                                             \n\
+}                                                                                                               \n\
+";
 
 AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) :
     m_valid (true),
@@ -556,8 +657,26 @@ AppleObjCTrampolineHandler::AppleObjCTra
         m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target);
     
     // FIXME: Do some kind of logging here.
-    if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+    if (m_impl_fn_addr == LLDB_INVALID_ADDRESS)
+    {
+        // If we can't even find the ordinary get method implementation function, then we aren't going to be able to
+        // step through any method dispatches.  Warn to that effect and get out of here.
+        process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\""
+                                                                      " step in through ObjC method dispatch will not work.\n",
+                                                                      get_impl_name.AsCString());
         return;
+    }
+    else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+    {
+        // It there is no stret return lookup function, assume that it is the same as the straight lookup:
+        m_impl_stret_fn_addr = m_impl_fn_addr;
+        // Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
+        g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
+    }
+    else
+    {
+        g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+    }
         
     // Look up the addresses for the objc dispatch functions and cache them.  For now I'm inspecting the symbol
     // names dynamically to figure out how to dispatch to them.  If it becomes more complicated than this we can 
@@ -629,15 +748,26 @@ AppleObjCTrampolineHandler::SetupDispatc
         }
         else if (!m_impl_code.get())
         {
-            m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
-                                                         g_lookup_implementation_function_name));
-            if (!m_impl_code->Install(errors, exe_ctx))
+            if (g_lookup_implementation_function_code != NULL)
+            {
+                m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
+                                                             g_lookup_implementation_function_name));
+                if (!m_impl_code->Install(errors, exe_ctx))
+                {
+                    if (log)
+                        log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                    m_impl_code.reset();
+                    return args_addr;
+                }
+            }
+            else
             {
                 if (log)
-                    log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
-                m_impl_code.reset();
-                return args_addr;
+                    log->Printf("No method lookup implementation code.");
+                errors.Printf ("No method lookup implementation code found.");
+                return LLDB_INVALID_ADDRESS;
             }
+            
             impl_code_address.Clear();
             impl_code_address.SetOffset(m_impl_code->StartAddress());
         }

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h?rev=175662&r1=175661&r2=175662&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h Wed Feb 20 14:35:38 2013
@@ -67,6 +67,8 @@ public:
 private:
     static const char *g_lookup_implementation_function_name;
     static const char *g_lookup_implementation_function_code;
+    static const char *g_lookup_implementation_with_stret_function_code;
+    static const char *g_lookup_implementation_no_stret_function_code;
 
     class AppleObjCVTables
     {





More information about the lldb-commits mailing list