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; 51552f792329be5db8e38961350589e97e8f2823acdGreg Clayton ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 51652f792329be5db8e38961350589e97e8f2823acdGreg Clayton 5174f385f181467701d2c5225f2c954ed5771e0763fJim Ingham input_value.SetValueType (Value::eValueTypeScalar); 51852f792329be5db8e38961350589e97e8f2823acdGreg Clayton //input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 51952f792329be5db8e38961350589e97e8f2823acdGreg Clayton input_value.SetClangType (clang_void_ptr_type); 5204f385f181467701d2c5225f2c954ed5771e0763fJim Ingham argument_values.PushValue(input_value); 5214f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 522f4124deeb9532044a38c0774ced872f2709347daGreg Clayton bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values); 5234f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!success) 5244f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5254f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5264f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Now get a pointer value from the zeroth argument. 5274f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Error error; 5284f385f181467701d2c5225f2c954ed5771e0763fJim Ingham DataExtractor data; 529f4124deeb9532044a38c0774ced872f2709347daGreg Clayton error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx, 530801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton data, 531801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton 0, 532801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton NULL); 53336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::offset_t offset = 0; 53436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton lldb::addr_t region_addr = data.GetPointer(&offset); 5354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (region_addr != 0) 5374f385f181467701d2c5225f2c954ed5771e0763fJim Ingham vtable_handler->ReadRegions(region_addr); 5384f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5394f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5404f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5414f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5424f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5434f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions () 5444f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5454f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // The no argument version reads the start region from the value of the gdb_regions_header, and 5464f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // gets started from there. 5474f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5484f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.clear(); 5494f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!InitializeVTableSymbols()) 5504f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5514f385f181467701d2c5225f2c954ed5771e0763fJim Ingham Error error; 552c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton lldb::addr_t region_addr = m_process_sp->ReadPointerFromMemory (m_trampoline_header, error); 553c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton if (error.Success()) 554c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton return ReadRegions (region_addr); 555c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton return false; 5564f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5574f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5584f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5594f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions (lldb::addr_t region_addr) 5604f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5614f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!m_process_sp) 5624f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5634f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 564952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 5654f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5664f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // We aren't starting at the trampoline symbol. 5674f385f181467701d2c5225f2c954ed5771e0763fJim Ingham InitializeVTableSymbols (); 5684f385f181467701d2c5225f2c954ed5771e0763fJim Ingham lldb::addr_t next_region = region_addr; 5694f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5704f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Read in the sizes of the headers. 5714f385f181467701d2c5225f2c954ed5771e0763fJim Ingham while (next_region != 0) 5724f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5734f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.push_back (VTableRegion(this, next_region)); 5744f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (!m_regions.back().IsValid()) 5754f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5764f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.clear(); 5774f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 5784f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5794f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (log) 5804f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5814f385f181467701d2c5225f2c954ed5771e0763fJim Ingham StreamString s; 5824f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_regions.back().Dump(s); 5834f385f181467701d2c5225f2c954ed5771e0763fJim Ingham log->Printf("Read vtable region: \n%s", s.GetData()); 5844f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5854f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5864f385f181467701d2c5225f2c954ed5771e0763fJim Ingham next_region = m_regions.back().GetNextRegionAddr(); 5874f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 5884f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5894f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 5904f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 5914f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 5924f385f181467701d2c5225f2c954ed5771e0763fJim Inghambool 5934f385f181467701d2c5225f2c954ed5771e0763fJim InghamAppleObjCTrampolineHandler::AppleObjCVTables::IsAddressInVTables (lldb::addr_t addr, uint32_t &flags) 5944f385f181467701d2c5225f2c954ed5771e0763fJim Ingham{ 5954f385f181467701d2c5225f2c954ed5771e0763fJim Ingham region_collection::iterator pos, end = m_regions.end(); 5964f385f181467701d2c5225f2c954ed5771e0763fJim Ingham for (pos = m_regions.begin(); pos != end; pos++) 5974f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 5984f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if ((*pos).AddressInRegion (addr, flags)) 5994f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return true; 6004f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 6014f385f181467701d2c5225f2c954ed5771e0763fJim Ingham return false; 6024f385f181467701d2c5225f2c954ed5771e0763fJim Ingham} 6034f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 604b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamconst AppleObjCTrampolineHandler::DispatchFunction 605b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamAppleObjCTrampolineHandler::g_dispatch_functions[] = 60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 6076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // NAME STRET SUPER SUPER2 FIXUP TYPE 6086507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend", false, false, false, DispatchFunction::eFixUpNone }, 6096507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fixup", false, false, false, DispatchFunction::eFixUpToFix }, 6106507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, 6116507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret", true, false, false, DispatchFunction::eFixUpNone }, 6126507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret_fixup", true, false, false, DispatchFunction::eFixUpToFix }, 6136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_stret_fixedup", true, false, false, DispatchFunction::eFixUpFixed }, 6146507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret", false, false, false, DispatchFunction::eFixUpNone }, 6156507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret_fixup", false, false, false, DispatchFunction::eFixUpToFix }, 6166507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fpret_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, 6176507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret", false, false, true, DispatchFunction::eFixUpNone }, 6186507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret_fixup", false, false, true, DispatchFunction::eFixUpToFix }, 6196507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSend_fp2ret_fixedup", false, false, true, DispatchFunction::eFixUpFixed }, 6206507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper", false, true, false, DispatchFunction::eFixUpNone }, 6216507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper_stret", true, true, false, DispatchFunction::eFixUpNone }, 6226507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2", false, true, true, DispatchFunction::eFixUpNone }, 6236507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_fixup", false, true, true, DispatchFunction::eFixUpToFix }, 6246507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_fixedup", false, true, true, DispatchFunction::eFixUpFixed }, 6256507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret", true, true, true, DispatchFunction::eFixUpNone }, 6266507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret_fixup", true, true, true, DispatchFunction::eFixUpToFix }, 6276507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham {"objc_msgSendSuper2_stret_fixedup", true, true, true, DispatchFunction::eFixUpFixed }, 62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6306e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonAppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process_sp, 6316e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton const ModuleSP &objc_module_sp) : 63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_process_sp (process_sp), 6334f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_objc_module_sp (objc_module_sp), 63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_impl_fn_addr (LLDB_INVALID_ADDRESS), 6356507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS), 6366507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham m_msg_forward_addr (LLDB_INVALID_ADDRESS) 63724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Look up the known resolution functions: 63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString get_impl_name("class_getMethodImplementation"); 64124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString get_impl_stret_name("class_getMethodImplementation_stret"); 6426507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ConstString msg_forward_name("_objc_msgForward"); 6436507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ConstString msg_forward_stret_name("_objc_msgForward_stret"); 64424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 645eea264007bc5fb42c8f3239726a9d28ae42e1b7bGreg Clayton Target *target = m_process_sp ? &m_process_sp->GetTarget() : NULL; 64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *class_getMethodImplementation = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_name, eSymbolTypeCode); 64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *class_getMethodImplementation_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_stret_name, eSymbolTypeCode); 6486507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham const Symbol *msg_forward = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_name, eSymbolTypeCode); 6496507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham const Symbol *msg_forward_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_stret_name, eSymbolTypeCode); 65024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (class_getMethodImplementation) 6520c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_impl_fn_addr = class_getMethodImplementation->GetAddress().GetOpcodeLoadAddress (target); 65324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (class_getMethodImplementation_stret) 6540c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetAddress().GetOpcodeLoadAddress (target); 6556507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (msg_forward) 6560c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_msg_forward_addr = msg_forward->GetAddress().GetOpcodeLoadAddress(target); 6576507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (msg_forward_stret) 6580c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target); 65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // FIXME: Do some kind of logging here. 66112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (m_impl_fn_addr == LLDB_INVALID_ADDRESS) 66212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 66312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // If we can't even find the ordinary get method implementation function, then we aren't going to be able to 66412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // step through any method dispatches. Warn to that effect and get out of here. 665ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda if (process_sp->CanJIT()) 666ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda { 667ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\"" 668ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda " step in through ObjC method dispatch will not work.\n", 669ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda get_impl_name.AsCString()); 670ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molenda } 67124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 67212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 67312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) 67412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 67512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // It there is no stret return lookup function, assume that it is the same as the straight lookup: 67612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_stret_fn_addr = m_impl_fn_addr; 67712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham // Also we will use the version of the lookup code that doesn't rely on the stret version of the function. 67812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code; 67912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 68012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else 68112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 68212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code; 68312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol 68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can 68724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // turn the g_dispatch_functions char * array into a template table, and populate the DispatchFunction map 68824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // from there. 68924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6903e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (size_t i = 0; i != llvm::array_lengthof(g_dispatch_functions); i++) 69124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 69224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ConstString name_const_str(g_dispatch_functions[i].name); 69324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Symbol *msgSend_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (name_const_str, eSymbolTypeCode); 69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (msgSend_symbol) 69524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6965d187e5495ee17f6763337a6ae28c2a7b07e4945Greg Clayton // FixMe: Make g_dispatch_functions static table of DispatchFunctions, and have the map be address->index. 69724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Problem is we also need to lookup the dispatch function. For now we could have a side table of stret & non-stret 69824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // dispatch functions. If that's as complex as it gets, we're fine. 69924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7000c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton lldb::addr_t sym_addr = msgSend_symbol->GetAddress().GetOpcodeLoadAddress(target); 70124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i)); 70324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7054f385f181467701d2c5225f2c954ed5771e0763fJim Ingham 7064f385f181467701d2c5225f2c954ed5771e0763fJim Ingham // Build our vtable dispatch handler here: 7074f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_vtables_ap.reset(new AppleObjCVTables(process_sp, m_objc_module_sp)); 7084f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (m_vtables_ap.get()) 7094f385f181467701d2c5225f2c954ed5771e0763fJim Ingham m_vtables_ap->ReadRegions(); 71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 71124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7121831e78a6253392fca1c99e555e7adaa3f372647Jim Inghamlldb::addr_t 7131831e78a6253392fca1c99e555e7adaa3f372647Jim InghamAppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values) 7141831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham{ 7151831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ExecutionContext exe_ctx (thread.shared_from_this()); 7161831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham Address impl_code_address; 7171831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham StreamString errors; 718952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 7191831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham lldb::addr_t args_addr = LLDB_INVALID_ADDRESS; 7201831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7211831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // Scope for mutex locker: 7221831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7231831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham Mutex::Locker locker(m_impl_function_mutex); 7241831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7251831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // First stage is to make the ClangUtility to hold our injected function: 7261831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7271831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham #define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target. 7281831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // This is useful for debugging additions to the get_impl function 'cause you don't have 7291831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // to bother with string-ifying the code into g_lookup_implementation_function_code. 7301831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7311831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (USE_BUILTIN_FUNCTION) 7321831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7331831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector"); 7341831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham SymbolContextList sc_list; 7351831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7361831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list); 7371831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (sc_list.GetSize() == 1) 7381831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7391831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham SymbolContext sc; 7401831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham sc_list.GetContextAtIndex(0, sc); 7411831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (sc.symbol != NULL) 7421831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address = sc.symbol->GetAddress(); 7431831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7441831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr()); 7455f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr); 7461831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7471831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else 7481831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7491831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham //printf ("Could not find implementation function address.\n"); 7501831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham return args_addr; 7511831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7521831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7531831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else if (!m_impl_code.get()) 7541831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 75512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (g_lookup_implementation_function_code != NULL) 75612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 75712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code, 75812f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham g_lookup_implementation_function_name)); 75912f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (!m_impl_code->Install(errors, exe_ctx)) 76012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham { 76112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham if (log) 76212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham log->Printf ("Failed to install implementation lookup: %s.", errors.GetData()); 76312f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham m_impl_code.reset(); 76412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return args_addr; 76512f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 76612f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham } 76712f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham else 7681831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7691831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (log) 77012f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham log->Printf("No method lookup implementation code."); 77112f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham errors.Printf ("No method lookup implementation code found."); 77212f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham return LLDB_INVALID_ADDRESS; 7731831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 77412f564b9273ec6c53ac118d5d66e4185ae423e8cJim Ingham 7751831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.Clear(); 7761831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.SetOffset(m_impl_code->StartAddress()); 7771831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7781831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham else 7791831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 7801831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.Clear(); 7811831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham impl_code_address.SetOffset(m_impl_code->StartAddress()); 7821831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham } 7831831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham 7841831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham // Next make the runner function for our implementation utility function. 7851831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham if (!m_impl_function.get()) 7861831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham { 78752f792329be5db8e38961350589e97e8f2823acdGreg Clayton ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext(); 78852f792329be5db8e38961350589e97e8f2823acdGreg Clayton ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 78952f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_impl_function.reset(new ClangFunction (thread, 79052f792329be5db8e38961350589e97e8f2823acdGreg Clayton clang_void_ptr_type, 79152f792329be5db8e38961350589e97e8f2823acdGreg Clayton impl_code_address, 79252f792329be5db8e38961350589e97e8f2823acdGreg Clayton 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; 89052f792329be5db8e38961350589e97e8f2823acdGreg Clayton ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); 8916507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham void_ptr_value.SetValueType (Value::eValueTypeScalar); 89252f792329be5db8e38961350589e97e8f2823acdGreg Clayton //void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); 89352f792329be5db8e38961350589e97e8f2823acdGreg Clayton void_ptr_value.SetClangType (clang_void_ptr_type); 89424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 89524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int obj_index; 89624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int sel_index; 89724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 89824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If this is a struct return dispatch, then the first argument is the 89924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // return struct pointer, and the object is the second, and the selector is the third. 90024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Otherwise the object is the first and the selector the second. 9014f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (this_dispatch.stret_return) 90224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 90324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner obj_index = 1; 90424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sel_index = 2; 9056507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9066507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 90824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 90924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 91024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 91124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner obj_index = 0; 91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner sel_index = 1; 9136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 9146507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham argument_values.PushValue(void_ptr_value); 91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool success = abi->GetArgumentValues (thread, argument_values); 91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!success) 92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ret_plan_sp; 92123a3f0262fa997146184080a9433ff7566e23610Jim Ingham 92223a3f0262fa997146184080a9433ff7566e23610Jim Ingham lldb::addr_t obj_addr = argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong(); 92323a3f0262fa997146184080a9433ff7566e23610Jim Ingham if (obj_addr == 0x0) 92423a3f0262fa997146184080a9433ff7566e23610Jim Ingham { 92523a3f0262fa997146184080a9433ff7566e23610Jim Ingham if (log) 92623a3f0262fa997146184080a9433ff7566e23610Jim Ingham log->Printf("Asked to step to dispatch to nil object, returning empty plan."); 92723a3f0262fa997146184080a9433ff7566e23610Jim Ingham return ret_plan_sp; 92823a3f0262fa997146184080a9433ff7566e23610Jim Ingham } 929008f3dc79c762b7d240b5ad6d4fb148c5cb039caJim Ingham 930289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton ExecutionContext exe_ctx (thread.shared_from_this()); 931289afcb5e26c2527a0d2e71f84e780b86bbcf90aGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 932e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // isa_addr will store the class pointer that the method is being dispatched to - so either the class 933e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // directly or the super class if this is one of the objc_msgSendSuper flavors. That's mostly used to 934e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // look up the class/selector pair in our cache. 935e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 936e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham lldb::addr_t isa_addr = LLDB_INVALID_ADDRESS; 9376507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham lldb::addr_t sel_addr = argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong(); 938e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 939e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Figure out the class this is being dispatched to and see if we've already cached this method call, 940e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // If so we can push a run-to-address plan directly. Otherwise we have to figure out where 941e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the implementation lives. 9426507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 943e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (this_dispatch.is_super) 94424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 945e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (this_dispatch.is_super2) 946e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 947e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the objc_msgSendSuper2 case, we don't get the object directly, we get a structure containing 948e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the object and the class to which the super message is being sent. So we need to dig the super 949e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // out of the class and use that. 950e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 951e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value super_value(*(argument_values.GetValueAtIndex(obj_index))); 952e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 95352f792329be5db8e38961350589e97e8f2823acdGreg Clayton super_value.ResolveValue (&exe_ctx); 954e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 955e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 956e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 957e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 958e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // isa_value now holds the class pointer. The second word of the class pointer is the super-class pointer: 959e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 96052f792329be5db8e38961350589e97e8f2823acdGreg Clayton super_value.ResolveValue (&exe_ctx); 961e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 962e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = super_value.GetScalar().ULongLong(); 963e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 964e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 965e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 966e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the super class value from the class in objc_super."); 967e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 968e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 969e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 970e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 971e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 972e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the class value from objc_super."); 973e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 974e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 975e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 976e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 977e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the objc_msgSendSuper case, we don't get the object directly, we get a two element structure containing 978e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the object and the super class to which the super message is being sent. So the class we want is 979e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the second element of this structure. 980e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 981e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value super_value(*(argument_values.GetValueAtIndex(obj_index))); 982e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham super_value.GetScalar() += process->GetAddressByteSize(); 98352f792329be5db8e38961350589e97e8f2823acdGreg Clayton super_value.ResolveValue (&exe_ctx); 984e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 985e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (super_value.GetScalar().IsValid()) 986e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 987e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = super_value.GetScalar().ULongLong(); 988e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 989e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 990e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 991e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 992e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the class value from objc_super."); 993e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 994e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 99524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 996e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 997e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 998e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // In the direct dispatch case, the object->isa is the class pointer we want. 999e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1000e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // This is a little cheesy, but since object->isa is the first field, 1001e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // making the object value a load address value and resolving it will get 1002e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // the pointer sized data pointed to by that value... 1003e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1004e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Note, it isn't a fatal error not to be able to get the address from the object, since this might 1005e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // be a "tagged pointer" which isn't a real object, but rather some word length encoded dingus. 1006e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1007e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); 1008e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1009e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_value.SetValueType(Value::eValueTypeLoadAddress); 101052f792329be5db8e38961350589e97e8f2823acdGreg Clayton isa_value.ResolveValue(&exe_ctx); 1011e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (isa_value.GetScalar().IsValid()) 1012e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1013e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr = isa_value.GetScalar().ULongLong(); 1014e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1015e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 1016e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1017e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 1018e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham log->Printf("Failed to extract the isa value from object."); 1019e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1020e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1021e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 10226507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 1023e258440978dce75cd921fe7bf9b8174c17004763Jim 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: 1024e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham lldb::addr_t impl_addr = LLDB_INVALID_ADDRESS; 1025e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1026e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (isa_addr != LLDB_INVALID_ADDRESS) 1027e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1028e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 1029e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 10305f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Resolving call for class - 0x%" PRIx64 " and selector - 0x%" PRIx64, 1031e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham isa_addr, sel_addr); 1032e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1033e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham ObjCLanguageRuntime *objc_runtime = m_process_sp->GetObjCLanguageRuntime (); 1034e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham assert(objc_runtime != NULL); 1035e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1036e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham impl_addr = objc_runtime->LookupInMethodCache (isa_addr, sel_addr); 1037e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1038e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1039e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (impl_addr != LLDB_INVALID_ADDRESS) 1040e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 1041e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham // Yup, it was in the cache, so we can run to that address directly. 1042e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1043e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham if (log) 10445f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf ("Found implementation address in cache: 0x%" PRIx64, impl_addr); 1045e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham 1046e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham ret_plan_sp.reset (new ThreadPlanRunToAddress (thread, impl_addr, stop_others)); 1047e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham } 1048e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham else 1049e258440978dce75cd921fe7bf9b8174c17004763Jim Ingham { 10506507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // We haven't seen this class/selector pair yet. Look it up. 105124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StreamString errors; 10526507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham Address impl_code_address; 10536507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10546507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham ValueList dispatch_values; 10556507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10566507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // We've will inject a little function in the target that takes the object, selector and some flags, 10576507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // and figures out the implementation. Looks like: 10586507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // void *__lldb_objc_find_implementation_for_selector (void *object, 10596507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // void *sel, 10606507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_stret, 10616507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_super, 10626507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_super2, 10636507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_fixup, 10646507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int is_fixed, 10656507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // int debug) 10666507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham // So set up the arguments for that call. 10676507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10686507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (*(argument_values.GetValueAtIndex(obj_index))); 10696507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index))); 10706507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10716507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham Value flag_value; 107252f792329be5db8e38961350589e97e8f2823acdGreg Clayton ClangASTType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); 10736507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.SetValueType (Value::eValueTypeScalar); 107452f792329be5db8e38961350589e97e8f2823acdGreg Clayton //flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); 107552f792329be5db8e38961350589e97e8f2823acdGreg Clayton flag_value.SetClangType (clang_int_type); 10766507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10776507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.stret_return) 10786507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10796507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10806507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10816507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10826507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10836507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.is_super) 10846507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10856507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10866507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10876507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10886507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10896507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham if (this_dispatch.is_super2) 10906507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 10916507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 10926507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10936507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 10946507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham 10956507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham switch (this_dispatch.fixedup) 10966507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham { 10976507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpNone: 10986507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 10996507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11006507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11016507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 11026507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpFixed: 11036507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11046507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11056507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11066507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11076507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 11086507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham case DispatchFunction::eFixUpToFix: 11096507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11106507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11116507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; 11126507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham dispatch_values.PushValue (flag_value); 11136507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham break; 11146507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham } 111520c37084dbfb8d704b3dabcd978a0afc060cd87dJim Ingham if (log && log->GetVerbose()) 11166507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 1; 11176507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham else 11186507dd90b5d27662537caee49a3a3cc236f85a53Jim Ingham flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done. 11195a26910ed231503d2a7a71365a44e379a994f4e6Greg Clayton dispatch_values.PushValue (flag_value); 112024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1121b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham 1122b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham // The step through code might have to fill in the cache, so it is not safe to run only one thread. 1123b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham // So we override the stop_others value passed in to us here: 1124b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham const bool trampoline_stop_others = false; 11251831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, 11261831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham this, 11271831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham dispatch_values, 11281831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham isa_addr, 11291831e78a6253392fca1c99e555e7adaa3f372647Jim Ingham sel_addr, 1130b6b7f3e32208a9cce03aace3e05eabefd2693c2cJim Ingham trampoline_stop_others)); 11314f385f181467701d2c5225f2c954ed5771e0763fJim Ingham if (log) 11324f385f181467701d2c5225f2c954ed5771e0763fJim Ingham { 11334f385f181467701d2c5225f2c954ed5771e0763fJim Ingham StreamString s; 11344f385f181467701d2c5225f2c954ed5771e0763fJim Ingham ret_plan_sp->GetDescription(&s, eDescriptionLevelFull); 11354f385f181467701d2c5225f2c954ed5771e0763fJim Ingham log->Printf("Using ObjC step plan: %s.\n", s.GetData()); 11364f385f181467701d2c5225f2c954ed5771e0763fJim Ingham } 113724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 113824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 113924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 114024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ret_plan_sp; 114124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 114224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 114324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerClangFunction * 1144b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamAppleObjCTrampolineHandler::GetLookupImplementationWrapperFunction () 114524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 114624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return m_impl_function.get(); 114724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 1148