AppleObjCRuntimeV2.cpp revision b344843f75ef893762c93fd0a22d2d45712ce74d
1//===-- AppleObjCRuntimeV2.cpp --------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "AppleObjCRuntimeV2.h"
11#include "AppleObjCTrampolineHandler.h"
12
13#include "llvm/Support/MachO.h"
14#include "clang/AST/Type.h"
15
16#include "lldb/Breakpoint/BreakpointLocation.h"
17#include "lldb/Core/ConstString.h"
18#include "lldb/Core/Error.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/Module.h"
21#include "lldb/Core/PluginManager.h"
22#include "lldb/Core/Scalar.h"
23#include "lldb/Core/StreamString.h"
24#include "lldb/Expression/ClangFunction.h"
25#include "lldb/Expression/ClangUtilityFunction.h"
26#include "lldb/Symbol/ClangASTContext.h"
27#include "lldb/Target/ExecutionContext.h"
28#include "lldb/Target/Process.h"
29#include "lldb/Target/RegisterContext.h"
30#include "lldb/Target/StopInfo.h"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33
34#include <vector>
35
36using namespace lldb;
37using namespace lldb_private;
38
39static const char *pluginName = "AppleObjCRuntimeV2";
40static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2";
41static const char *pluginShort = "language.apple.objc.v2";
42
43AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, ModuleSP &objc_module_sp) :
44    lldb_private::AppleObjCRuntime (process)
45{
46    m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(ConstString("gdb_object_getClass")) != NULL);
47}
48
49lldb::ValueObjectSP
50AppleObjCRuntimeV2::GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope)
51{
52    lldb::ValueObjectSP ret_sp;
53    return ret_sp;
54}
55
56//------------------------------------------------------------------
57// Static Functions
58//------------------------------------------------------------------
59lldb_private::LanguageRuntime *
60AppleObjCRuntimeV2::CreateInstance (Process *process, lldb::LanguageType language)
61{
62    // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make
63    // sure we aren't using the V1 runtime.
64    if (language == eLanguageTypeObjC)
65    {
66        ModuleSP objc_module_sp;
67
68        if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == eAppleObjC_V2)
69            return new AppleObjCRuntimeV2 (process, objc_module_sp);
70        else
71            return NULL;
72    }
73    else
74        return NULL;
75}
76
77void
78AppleObjCRuntimeV2::Initialize()
79{
80    PluginManager::RegisterPlugin (pluginName,
81                                   pluginDesc,
82                                   CreateInstance);
83}
84
85void
86AppleObjCRuntimeV2::Terminate()
87{
88    PluginManager::UnregisterPlugin (CreateInstance);
89}
90
91//------------------------------------------------------------------
92// PluginInterface protocol
93//------------------------------------------------------------------
94const char *
95AppleObjCRuntimeV2::GetPluginName()
96{
97    return pluginName;
98}
99
100const char *
101AppleObjCRuntimeV2::GetShortPluginName()
102{
103    return pluginShort;
104}
105
106uint32_t
107AppleObjCRuntimeV2::GetPluginVersion()
108{
109    return 1;
110}
111
112void
113AppleObjCRuntimeV2::SetExceptionBreakpoints ()
114{
115    if (!m_process)
116        return;
117
118    if (!m_objc_exception_bp_sp)
119    {
120        m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
121                                                                          "__cxa_throw",
122                                                                          eFunctionNameTypeBase,
123                                                                          true);
124    }
125}
126
127ClangUtilityFunction *
128AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
129{
130    char check_function_code[1024];
131
132    int len = 0;
133    if (m_has_object_getClass)
134    {
135        len = ::snprintf (check_function_code,
136                          sizeof(check_function_code),
137                          "extern \"C\" void *gdb_object_getClass(void *);    \n"
138                          "extern \"C\" void                                  \n"
139                          "%s(void *$__lldb_arg_obj)                          \n"
140                          "{                                                  \n"
141                          "   if ($__lldb_arg_obj == (void *)0)               \n"
142                          "       return; // nil is ok                        \n"
143                          "   if (!gdb_object_getClass($__lldb_arg_obj))      \n"
144                          "       *((volatile int *)0) = 'ocgc';              \n"
145                          "}                                                  \n",
146                          name);
147    }
148    else
149    {
150        len = ::snprintf (check_function_code,
151                          sizeof(check_function_code),
152                          "extern \"C\" void *gdb_class_getClass(void *);       \n"
153                          "extern \"C\" void                                    \n"
154                          "%s(void *$__lldb_arg_obj)                            \n"
155                          "{                                                    \n"
156                          "   if ($__lldb_arg_obj == (void *)0)                 \n"
157                          "       return; // nil is ok                          \n"
158                          "    void **$isa_ptr = (void **)$__lldb_arg_obj;      \n"
159                          "    if (*$isa_ptr == (void *)0 || !gdb_class_getClass(*$isa_ptr)) \n"
160                          "       *((volatile int *)0) = 'ocgc';                \n"
161                          "}                                                    \n",
162                          name);
163    }
164
165    assert (len < sizeof(check_function_code));
166
167    return new ClangUtilityFunction(check_function_code, name);
168}
169