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