AppleObjCTrampolineHandler.cpp revision 3e11c7ec050648ba865f1d451f8cb46fd39072a8
1b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h" 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea 12b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "AppleObjCTrampolineHandler.h" 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 18b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "AppleThreadPlanStepThroughObjCTrampoline.h" 19b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham 204f385f181467701d2c5225f2c954ed5771e0763fJim Ingham#include "lldb/Breakpoint/StoppointCallbackContext.h" 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ConstString.h" 224f385f181467701d2c5225f2c954ed5771e0763fJim Ingham#include "lldb/Core/Debugger.h" 23b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/Log.h" 24b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/Module.h" 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Value.h" 266e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton#include "lldb/Expression/ClangExpression.h" 276e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton#include "lldb/Expression/ClangFunction.h" 286e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton#include "lldb/Expression/ClangUtilityFunction.h" 2973844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton#include "lldb/Host/FileSpec.h" 30b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Symbol/ClangASTContext.h" 3149ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/Symbol.h" 32b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/ObjCLanguageRuntime.h" 33b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/Process.h" 34b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/RegisterContext.h" 35b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/Target.h" 36b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/Thread.h" 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ExecutionContext.h" 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanRunToAddress.h" 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40ce0575750c7180a2fdf06220d0d75c1d7dc9608bDaniel Dunbar#include "llvm/ADT/STLExtras.h" 41ce0575750c7180a2fdf06220d0d75c1d7dc9608bDaniel Dunbar 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb; 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private; 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 456507dd90b5d27662537caee49a3a3cc236f85a53Jim Inghamconst char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector"; 4612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Inghamconst char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL; 4712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Inghamconst char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\ 486507dd90b5d27662537caee49a3a3cc236f85a53Jim Inghamextern \"C\" \n\ 496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham{ \n\ 506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\ 516507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham extern void *class_getMethodImplementation_stret(void *objc_class, void *sel); \n\ 526507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham extern void * sel_getUid(char *name); \n\ 536507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham extern int printf(const char *format, ...); \n\ 546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham} \n\ 556507dd90b5d27662537caee49a3a3cc236f85a53Jim Inghamextern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\ 566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *sel, \n\ 576507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int is_stret, \n\ 586507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int is_super, \n\ 596507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int is_super2, \n\ 606507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int is_fixup, \n\ 616507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int is_fixed, \n\ 626507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham int debug) \n\ 636507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham{ \n\ 646507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_imp_return_struct \n\ 656507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 666507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *class_addr; \n\ 676507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *sel_addr; \n\ 686507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *impl_addr; \n\ 696507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham }; \n\ 706507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 716507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_objc_class { \n\ 726507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *isa; \n\ 736507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *super_ptr; \n\ 746507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham }; \n\ 756507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_objc_super { \n\ 766507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *reciever; \n\ 776507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_objc_class *class_ptr; \n\ 786507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham }; \n\ 796507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_msg_ref { \n\ 806507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *dont_know; \n\ 816507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *sel; \n\ 826507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham }; \n\ 836507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 846507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_imp_return_struct return_struct; \n\ 856507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 866507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (debug) \n\ 876507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\ 886507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\ 896507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\ 906507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (is_super) \n\ 916507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 926507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (is_super2) \n\ 936507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 946507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\ 956507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 966507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 976507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 986507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\ 996507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1006507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1016507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 1026507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1036507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void *class_ptr = (void *) [(id) object class]; \n\ 1046507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (class_ptr == object) \n\ 1056507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1066507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr; \n\ 1076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (debug) \n\ 1086507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\", \n\ 1096507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham class_ptr, class_as_class_struct->isa); \n\ 1106507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.class_addr = class_as_class_struct->isa; \n\ 1116507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1126507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 1136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1146507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (debug) \n\ 1156507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham printf (\"[object class] returned: 0x%p.\\n\", class_ptr); \n\ 1166507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.class_addr = class_ptr; \n\ 1176507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1186507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1196507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 1206507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (is_fixup) \n\ 1216507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1226507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (is_fixed) \n\ 1236507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1246507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\ 1256507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1266507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 1276507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1286507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\ 1296507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr = sel_getUid (sel_name); \n\ 1306507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (debug) \n\ 1316507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\", \n\ 1326507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr, sel_name); \n\ 1336507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1346507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1356507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 1366507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1376507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr = sel; \n\ 1386507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1396507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 1406507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (is_stret) \n\ 1416507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1426507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.impl_addr = class_getMethodImplementation_stret (return_struct.class_addr, \n\ 1436507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr); \n\ 1446507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1456507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else \n\ 1466507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { \n\ 1476507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\ 1486507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return_struct.sel_addr); \n\ 1496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } \n\ 1506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (debug) \n\ 1516507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\ 1526507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham \n\ 1536507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham return return_struct.impl_addr; \n\ 1546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham} \n\ 1556507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham"; 15612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Inghamconst char *AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = " \n\ 15712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Inghamextern \"C\" \n\ 15812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham{ \n\ 15912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\ 16012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham extern void * sel_getUid(char *name); \n\ 16112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham extern int printf(const char *format, ...); \n\ 16212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham} \n\ 16312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Inghamextern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\ 16412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *sel, \n\ 16512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int is_stret, \n\ 16612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int is_super, \n\ 16712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int is_super2, \n\ 16812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int is_fixup, \n\ 16912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int is_fixed, \n\ 17012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham int debug) \n\ 17112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham{ \n\ 17212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_imp_return_struct \n\ 17312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 17412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *class_addr; \n\ 17512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *sel_addr; \n\ 17612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *impl_addr; \n\ 17712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham }; \n\ 17812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 17912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_objc_class { \n\ 18012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *isa; \n\ 18112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *super_ptr; \n\ 18212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham }; \n\ 18312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_objc_super { \n\ 18412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *reciever; \n\ 18512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_objc_class *class_ptr; \n\ 18612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham }; \n\ 18712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_msg_ref { \n\ 18812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *dont_know; \n\ 18912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *sel; \n\ 19012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham }; \n\ 19112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 19212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_imp_return_struct return_struct; \n\ 19312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 19412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (debug) \n\ 19512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\ 19612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\ 19712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\ 19812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (is_super) \n\ 19912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 20012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (is_super2) \n\ 20112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 20212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\ 20312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 20412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else \n\ 20512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 20612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\ 20712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 20812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 20912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else \n\ 21012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 21112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham void *class_ptr = (void *) [(id) object class]; \n\ 21212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (class_ptr == object) \n\ 21312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 21412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr; \n\ 21512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (debug) \n\ 21612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\", \n\ 21712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham class_ptr, class_as_class_struct->isa); \n\ 21812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.class_addr = class_as_class_struct->isa; \n\ 21912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 22012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else \n\ 22112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 22212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (debug) \n\ 22312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham printf (\"[object class] returned: 0x%p.\\n\", class_ptr); \n\ 22412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.class_addr = class_ptr; \n\ 22512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 22612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 22712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 22812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (is_fixup) \n\ 22912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 23012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (is_fixed) \n\ 23112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 23212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\ 23312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 23412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else \n\ 23512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 23612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\ 23712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.sel_addr = sel_getUid (sel_name); \n\ 23812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (debug) \n\ 23912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\", \n\ 24012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.sel_addr, sel_name); \n\ 24112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 24212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 24312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else \n\ 24412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { \n\ 24512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.sel_addr = sel; \n\ 24612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } \n\ 24712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 24812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\ 24912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return_struct.sel_addr); \n\ 25012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (debug) \n\ 25112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\ 25212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham \n\ 25312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return return_struct.impl_addr; \n\ 25412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham} \n\ 25512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham"; 2566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 2574f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) : 2584f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_valid (true), 2594f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_owner(owner), 2604f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_header_addr (header_addr), 2614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_start_addr(0), 2624f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_end_addr (0), 2634f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_next_region (0) 2644f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 2654f385f181467701d2c5225f2c954ed5771e0763fJim Ingham SetUpRegion (); 2664f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 2674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 2686e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonAppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() 2696e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{ 2706e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton} 2716e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton 2724f385f181467701d2c5225f2c954ed5771e0763fJim Inghamvoid 2734f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() 2744f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 2754f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The header looks like: 2764f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // 2774f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // uint16_t headerSize 2784f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // uint16_t descSize 2794f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // uint32_t descCount 2804f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // void * next 2814f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // 2824f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // First read in the header: 2834f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 2844f385f181467701d2c5225f2c954ed5771e0763fJim Ingham char memory_buffer[16]; 2854f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Process *process = m_owner->GetProcess(); 2864f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DataExtractor data(memory_buffer, sizeof(memory_buffer), 2874f385f181467701d2c5225f2c954ed5771e0763fJim Ingham process->GetByteOrder(), 2884f385f181467701d2c5225f2c954ed5771e0763fJim Ingham process->GetAddressByteSize()); 2894f385f181467701d2c5225f2c954ed5771e0763fJim Ingham size_t actual_size = 8 + process->GetAddressByteSize(); 2904f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Error error; 2914f385f181467701d2c5225f2c954ed5771e0763fJim Ingham size_t bytes_read = process->ReadMemory (m_header_addr, memory_buffer, actual_size, error); 2924f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (bytes_read != actual_size) 2934f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 2944f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_valid = false; 2954f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return; 2964f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 2974f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 29836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t offset = 0; 29936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const uint16_t header_size = data.GetU16(&offset); 30036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const uint16_t descriptor_size = data.GetU16(&offset); 30136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton const size_t num_descriptors = data.GetU32(&offset); 3024f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 30336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton m_next_region = data.GetPointer(&offset); 3044f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3054f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // If the header size is 0, that means we've come in too early before this data is set up. 3064f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Set ourselves as not valid, and continue. 3076916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton if (header_size == 0 || num_descriptors == 0) 3084f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3094f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_valid = false; 3104f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return; 3114f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 3124f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3134f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Now read in all the descriptors: 3144f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The descriptor looks like: 3154f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // 3164f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // uint32_t offset 3174f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // uint32_t flags 3184f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // 3194f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Where offset is either 0 - in which case it is unused, or 3204f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // it is the offset of the vtable code from the beginning of the descriptor record. 3214f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Below, we'll convert that into an absolute code address, since I don't want to have 3224f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // to compute it over and over. 3234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3244f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Ingest the whole descriptor array: 3256916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton const lldb::addr_t desc_ptr = m_header_addr + header_size; 3266916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton const size_t desc_array_size = num_descriptors * descriptor_size; 3274f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DataBufferSP data_sp(new DataBufferHeap (desc_array_size, '\0')); 3284f385f181467701d2c5225f2c954ed5771e0763fJim Ingham uint8_t* dst = (uint8_t*)data_sp->GetBytes(); 3294f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3304f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DataExtractor desc_extractor (dst, desc_array_size, 3314f385f181467701d2c5225f2c954ed5771e0763fJim Ingham process->GetByteOrder(), 3324f385f181467701d2c5225f2c954ed5771e0763fJim Ingham process->GetAddressByteSize()); 3334f385f181467701d2c5225f2c954ed5771e0763fJim Ingham bytes_read = process->ReadMemory(desc_ptr, dst, desc_array_size, error); 3344f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (bytes_read != desc_array_size) 3354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_valid = false; 3374f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return; 3384f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 3394f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3404f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The actual code for the vtables will be laid out consecutively, so I also 3414f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // compute the start and end of the whole code block. 3424f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 34336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton offset = 0; 3444f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_start_addr = 0; 3454f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_end_addr = 0; 3464f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3473e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (size_t i = 0; i < num_descriptors; i++) 3484f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 34936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::addr_t start_offset = offset; 35036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton uint32_t voffset = desc_extractor.GetU32 (&offset); 35136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton uint32_t flags = desc_extractor.GetU32 (&offset); 35236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::addr_t code_addr = desc_ptr + start_offset + voffset; 3534f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_descriptors.push_back (VTableDescriptor(flags, code_addr)); 3544f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3554f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_code_start_addr == 0 || code_addr < m_code_start_addr) 3564f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_start_addr = code_addr; 3574f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (code_addr > m_code_end_addr) 3584f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_end_addr = code_addr; 3594f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 36036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton offset = start_offset + descriptor_size; 3614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 3624f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Finally, a little bird told me that all the vtable code blocks are the same size. 3634f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Let's compute the blocks and if they are all the same add the size to the code end address: 3644f385f181467701d2c5225f2c954ed5771e0763fJim Ingham lldb::addr_t code_size = 0; 3654f385f181467701d2c5225f2c954ed5771e0763fJim Ingham bool all_the_same = true; 3663e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (size_t i = 0; i < num_descriptors - 1; i++) 3674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3684f385f181467701d2c5225f2c954ed5771e0763fJim Ingham lldb::addr_t this_size = m_descriptors[i + 1].code_start - m_descriptors[i].code_start; 3694f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (code_size == 0) 3704f385f181467701d2c5225f2c954ed5771e0763fJim Ingham code_size = this_size; 3714f385f181467701d2c5225f2c954ed5771e0763fJim Ingham else 3724f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3734f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (this_size != code_size) 3744f385f181467701d2c5225f2c954ed5771e0763fJim Ingham all_the_same = false; 3754f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (this_size > code_size) 3764f385f181467701d2c5225f2c954ed5771e0763fJim Ingham code_size = this_size; 3774f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 3784f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 3794f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (all_the_same) 3804f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_code_end_addr += code_size; 3814f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 3824f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3834f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 3844f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::AddressInRegion (lldb::addr_t addr, uint32_t &flags) 3854f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 3864f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!IsValid()) 3874f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 3884f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3894f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (addr < m_code_start_addr || addr > m_code_end_addr) 3904f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 3914f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 3924f385f181467701d2c5225f2c954ed5771e0763fJim Ingham std::vector<VTableDescriptor>::iterator pos, end = m_descriptors.end(); 3934f385f181467701d2c5225f2c954ed5771e0763fJim Ingham for (pos = m_descriptors.begin(); pos != end; pos++) 3944f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3954f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (addr <= (*pos).code_start) 3964f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 3974f385f181467701d2c5225f2c954ed5771e0763fJim Ingham flags = (*pos).flags; 3984f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 3994f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4004f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4014f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 4024f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 4034f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4044f385f181467701d2c5225f2c954ed5771e0763fJim Inghamvoid 4054f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::Dump (Stream &s) 4064f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 4075f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea s.Printf ("Header addr: 0x%" PRIx64 " Code start: 0x%" PRIx64 " Code End: 0x%" PRIx64 " Next: 0x%" PRIx64 "\n", 4084f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_header_addr, m_code_start_addr, m_code_end_addr, m_next_region); 4094f385f181467701d2c5225f2c954ed5771e0763fJim Ingham size_t num_elements = m_descriptors.size(); 4104f385f181467701d2c5225f2c954ed5771e0763fJim Ingham for (size_t i = 0; i < num_elements; i++) 4114f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4124f385f181467701d2c5225f2c954ed5771e0763fJim Ingham s.Indent(); 4135f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea s.Printf ("Code start: 0x%" PRIx64 " Flags: %d\n", m_descriptors[i].code_start, m_descriptors[i].flags); 4144f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4154f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 4164f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4176e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonAppleObjCTrampolineHandler::AppleObjCVTables::AppleObjCVTables (const ProcessSP &process_sp, 4186e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton const ModuleSP &objc_module_sp) : 4196e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton m_process_sp (process_sp), 4206e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton m_trampoline_header (LLDB_INVALID_ADDRESS), 4216e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton m_trampolines_changed_bp_id (LLDB_INVALID_BREAK_ID), 4226e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton m_objc_module_sp (objc_module_sp) 4234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 4244f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4254f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 4264f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4274f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::~AppleObjCVTables() 4284f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 4294f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_trampolines_changed_bp_id != LLDB_INVALID_BREAK_ID) 4304f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_process_sp->GetTarget().RemoveBreakpointByID (m_trampolines_changed_bp_id); 4314f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 4324f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4334f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 4344f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols () 4354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 4364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_trampoline_header != LLDB_INVALID_ADDRESS) 4374f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 4384f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Target &target = m_process_sp->GetTarget(); 4394f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 440146d9522c95c0c8c5409539813b55e08b99196eeEnrico Granata const ModuleList &target_modules = target.GetImages(); 4419336790a758b8f8b87d95e6658bb8fdb34766c2fJim Ingham Mutex::Locker modules_locker(target_modules.GetMutex()); 4429336790a758b8f8b87d95e6658bb8fdb34766c2fJim Ingham size_t num_modules = target_modules.GetSize(); 4434f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!m_objc_module_sp) 4444f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4454f385f181467701d2c5225f2c954ed5771e0763fJim Ingham for (size_t i = 0; i < num_modules; i++) 4464f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4479336790a758b8f8b87d95e6658bb8fdb34766c2fJim Ingham if (m_process_sp->GetObjCLanguageRuntime()->IsModuleObjCLibrary (target_modules.GetModuleAtIndexUnlocked(i))) 4484f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4499336790a758b8f8b87d95e6658bb8fdb34766c2fJim Ingham m_objc_module_sp = target_modules.GetModuleAtIndexUnlocked(i); 4504f385f181467701d2c5225f2c954ed5771e0763fJim Ingham break; 4514f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4524f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4534f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4544f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4554f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_objc_module_sp) 4564f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4574f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ConstString trampoline_name ("gdb_objc_trampolines"); 458c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton const Symbol *trampoline_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (trampoline_name, 459c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton eSymbolTypeData); 4604f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (trampoline_symbol != NULL) 4614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4620c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton if (!trampoline_symbol->GetAddress().IsValid()) 4634f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 4644f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4650c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_trampoline_header = trampoline_symbol->GetAddress().GetLoadAddress(&target); 4664f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_trampoline_header == LLDB_INVALID_ADDRESS) 4674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 4684f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4694f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Next look up the "changed" symbol and set a breakpoint on that... 4704f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ConstString changed_name ("gdb_objc_trampolines_changed"); 471c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton const Symbol *changed_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (changed_name, 472c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton eSymbolTypeCode); 4734f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (changed_symbol != NULL) 4744f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4750c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton if (!changed_symbol->GetAddress().IsValid()) 4764f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 4774f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4780c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton lldb::addr_t changed_addr = changed_symbol->GetAddress().GetOpcodeLoadAddress (&target); 4794f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (changed_addr != LLDB_INVALID_ADDRESS) 4804f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 481c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton BreakpointSP trampolines_changed_bp_sp = target.CreateBreakpoint (changed_addr, true); 482987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton if (trampolines_changed_bp_sp) 4834f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 4844f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID(); 4854f385f181467701d2c5225f2c954ed5771e0763fJim Ingham trampolines_changed_bp_sp->SetCallback (RefreshTrampolines, this, true); 486090f83176695d86197b0e86b67dee4160ec5003dJim Ingham trampolines_changed_bp_sp->SetBreakpointKind ("objc-trampolines-changed"); 4874f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 4884f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4894f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4904f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4914f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4924f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 4934f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4944f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 4954f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 4964f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 4974f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 4984f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton, 4992f085c6ca2895663687dca704589478ff040b849Greg Clayton StoppointCallbackContext *context, 5002f085c6ca2895663687dca704589478ff040b849Greg Clayton lldb::user_id_t break_id, 5012f085c6ca2895663687dca704589478ff040b849Greg Clayton lldb::user_id_t break_loc_id) 5024f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5034f385f181467701d2c5225f2c954ed5771e0763fJim Ingham AppleObjCVTables *vtable_handler = (AppleObjCVTables *) baton; 5044f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (vtable_handler->InitializeVTableSymbols()) 5054f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5064f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The Update function is called with the address of an added region. So we grab that address, and 5074f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // feed it into ReadRegions. Of course, our friend the ABI will get the values for us. 508f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ExecutionContext exe_ctx (context->exe_ctx_ref); 509f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 51075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton const ABI *abi = process->GetABI().get(); 5114f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5124f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); 5134f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ValueList argument_values; 5144f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Value input_value; 5154f385f181467701d2c5225f2c954ed5771e0763fJim Ingham void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); 5164f385f181467701d2c5225f2c954ed5771e0763fJim Ingham input_value.SetValueType (Value::eValueTypeScalar); 5176916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 5184f385f181467701d2c5225f2c954ed5771e0763fJim Ingham argument_values.PushValue(input_value); 5194f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 520f4124deeb9532044a38c0774ced872f2709347daGreg Clayton bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values); 5214f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!success) 5224f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5244f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Now get a pointer value from the zeroth argument. 5254f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Error error; 5264f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DataExtractor data; 527f4124deeb9532044a38c0774ced872f2709347daGreg Clayton error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx, 528801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton clang_ast_context->getASTContext(), 529801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton data, 530801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton 0, 531801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton NULL); 53236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t offset = 0; 53336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::addr_t region_addr = data.GetPointer(&offset); 5344f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (region_addr != 0) 5364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham vtable_handler->ReadRegions(region_addr); 5374f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5384f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5394f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5404f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5414f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5424f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions () 5434f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5444f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The no argument version reads the start region from the value of the gdb_regions_header, and 5454f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // gets started from there. 5464f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5474f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.clear(); 5484f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!InitializeVTableSymbols()) 5494f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5504f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Error error; 551c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton lldb::addr_t region_addr = m_process_sp->ReadPointerFromMemory (m_trampoline_header, error); 552c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton if (error.Success()) 553c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton return ReadRegions (region_addr); 554c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton return false; 5554f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5564f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5574f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5584f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions (lldb::addr_t region_addr) 5594f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5604f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!m_process_sp) 5614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5624f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 563952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 5644f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5654f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // We aren't starting at the trampoline symbol. 5664f385f181467701d2c5225f2c954ed5771e0763fJim Ingham InitializeVTableSymbols (); 5674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham lldb::addr_t next_region = region_addr; 5684f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5694f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Read in the sizes of the headers. 5704f385f181467701d2c5225f2c954ed5771e0763fJim Ingham while (next_region != 0) 5714f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5724f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.push_back (VTableRegion(this, next_region)); 5734f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!m_regions.back().IsValid()) 5744f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5754f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.clear(); 5764f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5774f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5784f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (log) 5794f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5804f385f181467701d2c5225f2c954ed5771e0763fJim Ingham StreamString s; 5814f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.back().Dump(s); 5824f385f181467701d2c5225f2c954ed5771e0763fJim Ingham log->Printf("Read vtable region: \n%s", s.GetData()); 5834f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5844f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5854f385f181467701d2c5225f2c954ed5771e0763fJim Ingham next_region = m_regions.back().GetNextRegionAddr(); 5864f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5874f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5884f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 5894f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5904f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5914f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5924f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::IsAddressInVTables (lldb::addr_t addr, uint32_t &flags) 5934f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5944f385f181467701d2c5225f2c954ed5771e0763fJim Ingham region_collection::iterator pos, end = m_regions.end(); 5954f385f181467701d2c5225f2c954ed5771e0763fJim Ingham for (pos = m_regions.begin(); pos != end; pos++) 5964f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5974f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if ((*pos).AddressInRegion (addr, flags)) 5984f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 5994f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 6004f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 6014f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 6024f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 603b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamconst AppleObjCTrampolineHandler::DispatchFunction 604b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamAppleObjCTrampolineHandler::g_dispatch_functions[] = 60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6066507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // NAME STRET SUPER SUPER2 FIXUP TYPE 6076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend", false, false, false, DispatchFunction::eFixUpNone }, 6086507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fixup", false, false, false, DispatchFunction::eFixUpToFix }, 6096507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, 6106507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret", true, false, false, DispatchFunction::eFixUpNone }, 6116507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret_fixup", true, false, false, DispatchFunction::eFixUpToFix }, 6126507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret_fixedup", true, false, false, DispatchFunction::eFixUpFixed }, 6136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret", false, false, false, DispatchFunction::eFixUpNone }, 6146507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret_fixup", false, false, false, DispatchFunction::eFixUpToFix }, 6156507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, 6166507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret", false, false, true, DispatchFunction::eFixUpNone }, 6176507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret_fixup", false, false, true, DispatchFunction::eFixUpToFix }, 6186507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret_fixedup", false, false, true, DispatchFunction::eFixUpFixed }, 6196507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper", false, true, false, DispatchFunction::eFixUpNone }, 6206507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper_stret", true, true, false, DispatchFunction::eFixUpNone }, 6216507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2", false, true, true, DispatchFunction::eFixUpNone }, 6226507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_fixup", false, true, true, DispatchFunction::eFixUpToFix }, 6236507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_fixedup", false, true, true, DispatchFunction::eFixUpFixed }, 6246507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret", true, true, true, DispatchFunction::eFixUpNone }, 6256507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret_fixup", true, true, true, DispatchFunction::eFixUpToFix }, 6266507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret_fixedup", true, true, true, DispatchFunction::eFixUpFixed }, 62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6296e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonAppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process_sp, 6306e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton const ModuleSP &objc_module_sp) : 63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_process_sp (process_sp), 6324f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_objc_module_sp (objc_module_sp), 63324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_impl_fn_addr (LLDB_INVALID_ADDRESS), 6346507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS), 6356507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham m_msg_forward_addr (LLDB_INVALID_ADDRESS) 63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 63724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Look up the known resolution functions: 63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString get_impl_name("class_getMethodImplementation"); 64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString get_impl_stret_name("class_getMethodImplementation_stret"); 6416507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ConstString msg_forward_name("_objc_msgForward"); 6426507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ConstString msg_forward_stret_name("_objc_msgForward_stret"); 64324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 644eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton Target *target = m_process_sp ? &m_process_sp->GetTarget() : NULL; 64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *class_getMethodImplementation = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_name, eSymbolTypeCode); 64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *class_getMethodImplementation_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_stret_name, eSymbolTypeCode); 6476507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham const Symbol *msg_forward = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_name, eSymbolTypeCode); 6486507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham const Symbol *msg_forward_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_stret_name, eSymbolTypeCode); 64924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (class_getMethodImplementation) 6510c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_impl_fn_addr = class_getMethodImplementation->GetAddress().GetOpcodeLoadAddress (target); 65224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (class_getMethodImplementation_stret) 6530c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetAddress().GetOpcodeLoadAddress (target); 6546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (msg_forward) 6550c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_msg_forward_addr = msg_forward->GetAddress().GetOpcodeLoadAddress(target); 6566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (msg_forward_stret) 6570c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target); 65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // FIXME: Do some kind of logging here. 66012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (m_impl_fn_addr == LLDB_INVALID_ADDRESS) 66112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 66212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // If we can't even find the ordinary get method implementation function, then we aren't going to be able to 66312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // step through any method dispatches. Warn to that effect and get out of here. 664ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda if (process_sp->CanJIT()) 665ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda { 666ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\"" 667ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda " step in through ObjC method dispatch will not work.\n", 668ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda get_impl_name.AsCString()); 669ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda } 67024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 67112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 67212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) 67312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 67412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // It there is no stret return lookup function, assume that it is the same as the straight lookup: 67512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_stret_fn_addr = m_impl_fn_addr; 67612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // Also we will use the version of the lookup code that doesn't rely on the stret version of the function. 67712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code; 67812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 67912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else 68012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 68112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code; 68212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 68324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol 68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can 68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // turn the g_dispatch_functions char * array into a template table, and populate the DispatchFunction map 68724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // from there. 68824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6893e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (size_t i = 0; i != llvm::array_lengthof(g_dispatch_functions); i++) 69024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 69124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString name_const_str(g_dispatch_functions[i].name); 69224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *msgSend_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (name_const_str, eSymbolTypeCode); 69324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (msgSend_symbol) 69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6955d187e5495ee17f6763337a6ae28c2a7b07e4945Greg Clayton // FixMe: Make g_dispatch_functions static table of DispatchFunctions, and have the map be address->index. 69624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Problem is we also need to lookup the dispatch function. For now we could have a side table of stret & non-stret 69724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // dispatch functions. If that's as complex as it gets, we're fine. 69824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6990c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton lldb::addr_t sym_addr = msgSend_symbol->GetAddress().GetOpcodeLoadAddress(target); 70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 70124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i)); 70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 70324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7044f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 7054f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Build our vtable dispatch handler here: 7064f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_vtables_ap.reset(new AppleObjCVTables(process_sp, m_objc_module_sp)); 7074f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_vtables_ap.get()) 7084f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_vtables_ap->ReadRegions(); 70924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7111831e78a6253392fca1c99e555e7adaa3f372647Jim Inghamlldb::addr_t 7121831e78a6253392fca1c99e555e7adaa3f372647Jim InghamAppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values) 7131831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham{ 7141831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ExecutionContext exe_ctx (thread.shared_from_this()); 7151831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham Address impl_code_address; 7161831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham StreamString errors; 717952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 7181831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham lldb::addr_t args_addr = LLDB_INVALID_ADDRESS; 7191831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7201831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // Scope for mutex locker: 7211831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7221831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham Mutex::Locker locker(m_impl_function_mutex); 7231831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7241831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // First stage is to make the ClangUtility to hold our injected function: 7251831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7261831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham #define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target. 7271831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // This is useful for debugging additions to the get_impl function 'cause you don't have 7281831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // to bother with string-ifying the code into g_lookup_implementation_function_code. 7291831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7301831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (USE_BUILTIN_FUNCTION) 7311831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7321831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector"); 7331831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham SymbolContextList sc_list; 7341831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7351831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list); 7361831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (sc_list.GetSize() == 1) 7371831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7381831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham SymbolContext sc; 7391831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham sc_list.GetContextAtIndex(0, sc); 7401831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (sc.symbol != NULL) 7411831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address = sc.symbol->GetAddress(); 7421831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7431831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr()); 7445f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr); 7451831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7461831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else 7471831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7481831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham //printf ("Could not find implementation function address.\n"); 7491831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 7501831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7511831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7521831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else if (!m_impl_code.get()) 7531831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 75412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (g_lookup_implementation_function_code != NULL) 75512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 75612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code, 75712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_name)); 75812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (!m_impl_code->Install(errors, exe_ctx)) 75912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 76012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (log) 76112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham log->Printf ("Failed to install implementation lookup: %s.", errors.GetData()); 76212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_code.reset(); 76312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return args_addr; 76412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 76512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 76612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else 7671831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7681831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (log) 76912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham log->Printf("No method lookup implementation code."); 77012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham errors.Printf ("No method lookup implementation code found."); 77112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return LLDB_INVALID_ADDRESS; 7721831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 77312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham 7741831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.Clear(); 7751831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.SetOffset(m_impl_code->StartAddress()); 7761831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7771831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else 7781831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7791831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.Clear(); 7801831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.SetOffset(m_impl_code->StartAddress()); 7811831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7821831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7831831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // Next make the runner function for our implementation utility function. 7841831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (!m_impl_function.get()) 7851831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7861831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext(); 7871831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); 7881831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham m_impl_function.reset(new ClangFunction (thread, 7891831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham clang_ast_context, 7901831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham clang_void_ptr_type, 7911831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address, 7921831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham dispatch_values)); 7931831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7941831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham errors.Clear(); 7951831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham unsigned num_errors = m_impl_function->CompileFunction(errors); 7961831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (num_errors) 7971831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7981831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (log) 7991831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham log->Printf ("Error compiling function: \"%s\".", errors.GetData()); 8001831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 8011831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 8021831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 8031831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham errors.Clear(); 8041831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors)) 8051831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 8061831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (log) 8071831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham log->Printf ("Error Inserting function: \"%s\".", errors.GetData()); 8081831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 8091831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 8101831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 8111831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 8121831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 8131831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham errors.Clear(); 8141831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 8151831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // Now write down the argument values for this particular call. This looks like it might be a race condition 8161831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // if other threads were calling into here, but actually it isn't because we allocate a new args structure for 8171831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // this call by passing args_addr = LLDB_INVALID_ADDRESS... 8181831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 8191831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors)) 8201831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 8211831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (log) 8221831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham log->Printf ("Error writing function arguments: \"%s\".", errors.GetData()); 8231831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 8241831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 8251831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 8261831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 8271831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham} 8281831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 82924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanSP 830b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamAppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others) 83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 83224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlanSP ret_plan_sp; 83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); 83424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DispatchFunction this_dispatch; 8364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham bool found_it = false; 8374f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 8386507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // First step is to look and see if we are in one of the known ObjC dispatch functions. We've already compiled 8396507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // a table of same, so consult it. 8406507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MsgsendMap::iterator pos; 84224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner pos = m_msgSend_map.find (curr_pc); 84324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (pos != m_msgSend_map.end()) 84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8454f385f181467701d2c5225f2c954ed5771e0763fJim Ingham this_dispatch = g_dispatch_functions[(*pos).second]; 8464f385f181467701d2c5225f2c954ed5771e0763fJim Ingham found_it = true; 8474f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 8484f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 8496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // Next check to see if we are in a vtable region: 8506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 8514f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!found_it) 8524f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 8534f385f181467701d2c5225f2c954ed5771e0763fJim Ingham uint32_t flags; 8544f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_vtables_ap.get()) 8554f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 8564f385f181467701d2c5225f2c954ed5771e0763fJim Ingham found_it = m_vtables_ap->IsAddressInVTables (curr_pc, flags); 8574f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (found_it) 8584f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 8594f385f181467701d2c5225f2c954ed5771e0763fJim Ingham this_dispatch.name = "vtable"; 8604f385f181467701d2c5225f2c954ed5771e0763fJim Ingham this_dispatch.stret_return 8614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham = (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == AppleObjCVTables::eOBJC_TRAMPOLINE_STRET; 8624f385f181467701d2c5225f2c954ed5771e0763fJim Ingham this_dispatch.is_super = false; 8630984687e72f77f5e2278ed30597cc17a2e2afb62Jim Ingham this_dispatch.is_super2 = false; 8644f385f181467701d2c5225f2c954ed5771e0763fJim Ingham this_dispatch.fixedup = DispatchFunction::eFixUpFixed; 8654f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 8664f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 8674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 8684f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 8694f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (found_it) 8704f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 871952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 87224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8736507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // We are decoding a method dispatch. 8746507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // First job is to pull the arguments out: 87524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 87624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); 87724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 878289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton const ABI *abi = NULL; 879289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton ProcessSP process_sp (thread.CalculateProcess()); 880289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton if (process_sp) 881289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton abi = process_sp->GetABI().get(); 88224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (abi == NULL) 88324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ret_plan_sp; 88424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 885289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton TargetSP target_sp (thread.CalculateTarget()); 88624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 887289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext(); 88824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ValueList argument_values; 8896507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham Value void_ptr_value; 8906507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); 8916507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void_ptr_value.SetValueType (Value::eValueTypeScalar); 8926507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 89324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 89424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int obj_index; 89524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int sel_index; 89624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 89724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If this is a struct return dispatch, then the first argument is the 89824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // return struct pointer, and the object is the second, and the selector is the third. 89924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Otherwise the object is the first and the selector the second. 9004f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (this_dispatch.stret_return) 90124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 90224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner obj_index = 1; 90324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sel_index = 2; 9046507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9056507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9066507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 90724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 90824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 90924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 91024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner obj_index = 0; 91124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sel_index = 1; 9126507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool success = abi->GetArgumentValues (thread, argument_values); 91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!success) 91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ret_plan_sp; 9206507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 921289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton ExecutionContext exe_ctx (thread.shared_from_this()); 922289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 923e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // isa_addr will store the class pointer that the method is being dispatched to - so either the class 924e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // directly or the super class if this is one of the objc_msgSendSuper flavors. That's mostly used to 925e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // look up the class/selector pair in our cache. 926e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 927e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS; 9286507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham lldb::addr_t sel_addr = argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong(); 929e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 930e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Figure out the class this is being dispatched to and see if we've already cached this method call, 931e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // If so we can push a run-to-address plan directly. Otherwise we have to figure out where 932e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the implementation lives. 9336507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 934e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (this_dispatch.is_super) 93524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 936e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (this_dispatch.is_super2) 937e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 938e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the objc_msgSendSuper2 case, we don't get the object directly, we get a structure containing 939e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the object and the class to which the super message is being sent. So we need to dig the super 940e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // out of the class and use that. 941e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 942e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value super_value(*(argument_values.GetValueAtIndex(obj_index))); 943e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 944e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); 945e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 946e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 947e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 948e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 949e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // isa_value now holds the class pointer. The second word of the class pointer is the super-class pointer: 950e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 951e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); 952e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 953e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = super_value.GetScalar().ULongLong(); 954e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 955e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 956e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 957e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the super class value from the class in objc_super."); 958e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 959e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 960e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 961e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 962e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 963e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the class value from objc_super."); 964e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 965e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 966e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 967e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 968e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the objc_msgSendSuper case, we don't get the object directly, we get a two element structure containing 969e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the object and the super class to which the super message is being sent. So the class we want is 970e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the second element of this structure. 971e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 972e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value super_value(*(argument_values.GetValueAtIndex(obj_index))); 973e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 974e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext()); 975e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 976e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 977e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 978e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = super_value.GetScalar().ULongLong(); 979e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 980e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 981e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 982e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 983e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the class value from objc_super."); 984e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 985e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 98624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 987e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 988e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 989e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the direct dispatch case, the object->isa is the class pointer we want. 990e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 991e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // This is a little cheesy, but since object->isa is the first field, 992e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // making the object value a load address value and resolving it will get 993e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the pointer sized data pointed to by that value... 994e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 995e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Note, it isn't a fatal error not to be able to get the address from the object, since this might 996e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // be a "tagged pointer" which isn't a real object, but rather some word length encoded dingus. 997e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 998e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); 999e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1000e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_value.SetValueType(Value::eValueTypeLoadAddress); 1001e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_value.ResolveValue(&exe_ctx, clang_ast_context->getASTContext()); 1002e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (isa_value.GetScalar().IsValid()) 1003e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1004e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = isa_value.GetScalar().ULongLong(); 1005e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1006e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 1007e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1008e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 1009e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the isa value from object."); 1010e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1011e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1012e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 10136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 1014e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Okay, we've got the address of the class for which we're resolving this, let's see if it's in our cache: 1015e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham lldb::addr_t impl_addr = LLDB_INVALID_ADDRESS; 1016e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1017e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (isa_addr != LLDB_INVALID_ADDRESS) 1018e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1019e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 1020e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 10215f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Resolving call for class - 0x%" PRIx64 " and selector - 0x%" PRIx64, 1022e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr, sel_addr); 1023e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1024e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham ObjCLanguageRuntime *objc_runtime = m_process_sp->GetObjCLanguageRuntime (); 1025e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham assert(objc_runtime != NULL); 1026e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1027e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham impl_addr = objc_runtime->LookupInMethodCache (isa_addr, sel_addr); 1028e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1029e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1030e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (impl_addr != LLDB_INVALID_ADDRESS) 1031e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1032e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Yup, it was in the cache, so we can run to that address directly. 1033e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1034e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 10355f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf ("Found implementation address in cache: 0x%" PRIx64, impl_addr); 1036e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1037e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham ret_plan_sp.reset (new ThreadPlanRunToAddress (thread, impl_addr, stop_others)); 1038e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1039e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 1040e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 10416507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // We haven't seen this class/selector pair yet. Look it up. 104224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StreamString errors; 10436507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham Address impl_code_address; 10446507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10456507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ValueList dispatch_values; 10466507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10476507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // We've will inject a little function in the target that takes the object, selector and some flags, 10486507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // and figures out the implementation. Looks like: 10496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // void *__lldb_objc_find_implementation_for_selector (void *object, 10506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // void *sel, 10516507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_stret, 10526507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_super, 10536507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_super2, 10546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_fixup, 10556507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_fixed, 10566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int debug) 10576507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // So set up the arguments for that call. 10586507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10596507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (*(argument_values.GetValueAtIndex(obj_index))); 10606507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index))); 10616507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10626507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham Value flag_value; 106310de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham lldb::clang_type_t clang_int_type 106410de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); 10656507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.SetValueType (Value::eValueTypeScalar); 10666507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); 10676507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10686507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.stret_return) 10696507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10706507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10716507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10726507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10736507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10746507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.is_super) 10756507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10766507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10776507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10786507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10796507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10806507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.is_super2) 10816507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10826507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10836507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10846507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10856507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10866507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham switch (this_dispatch.fixedup) 10876507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { 10886507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpNone: 10896507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10906507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10916507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10926507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 10936507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpFixed: 10946507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10956507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10966507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10976507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10986507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 10996507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpToFix: 11006507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11016507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11026507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 11036507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11046507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 11056507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } 110620c37084dbfb8d704b3dabcd978a0afc060cd87dJim Ingham if (log && log->GetVerbose()) 11076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11086507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 11096507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done. 11105a26910ed231503d2a7a71365a44e379a994f4e6Greg Clayton dispatch_values.PushValue (flag_value); 111124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1112b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham 1113b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham // The step through code might have to fill in the cache, so it is not safe to run only one thread. 1114b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham // So we override the stop_others value passed in to us here: 1115b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham const bool trampoline_stop_others = false; 11161831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, 11171831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham this, 11181831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham dispatch_values, 11191831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham isa_addr, 11201831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham sel_addr, 1121b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham trampoline_stop_others)); 11224f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (log) 11234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 11244f385f181467701d2c5225f2c954ed5771e0763fJim Ingham StreamString s; 11254f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ret_plan_sp->GetDescription(&s, eDescriptionLevelFull); 11264f385f181467701d2c5225f2c954ed5771e0763fJim Ingham log->Printf("Using ObjC step plan: %s.\n", s.GetData()); 11274f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 112824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 112924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 113024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 113124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ret_plan_sp; 113224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 113324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 113424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerClangFunction * 1135b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamAppleObjCTrampolineHandler::GetLookupImplementationWrapperFunction () 113624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 113724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_impl_function.get(); 113824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 1139