this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ObjC trampolines initial work

+118 -17
+45 -9
src/dyld/Trampoline.cpp
··· 28 28 #include <sstream> 29 29 #include <stack> 30 30 #include <cxxabi.h> 31 + #include <dlfcn.h> 31 32 #include "../util/log.h" 33 + #include "../util/stlutils.h" 32 34 33 35 TrampolineMgr* TrampolineMgr::m_pInstance = 0; 34 36 std::map<std::string, TrampolineMgr::FunctionInfo> TrampolineMgr::m_functionInfo; 35 37 struct timeval TrampolineMgr::m_startup; 38 + void* TrampolineMgr::m_objcDarwin = 0; 36 39 37 40 static __thread std::stack<TrampolineMgr::ReturnInfo>* g_returnInfo = 0; 38 41 static std::ofstream* g_logger = 0; 39 42 static pid_t g_loggerForPid = 0; 43 + static const char* LIB_OBJCDARWIN = "libobjc.A.dylib.so"; 44 + static std::string (*objc_helper)(const std::string& /*invoker*/, void* /*arg1*/, void* /*arg2*/, std::string& /*searchable*/) = 0; 40 45 41 46 extern "C" void reg_saveall(); 42 47 extern "C" void reg_restoreall(); ··· 279 284 } 280 285 } 281 286 287 + bool TrampolineMgr::loadObjCHelper() 288 + { 289 + m_objcDarwin = ::dlopen(LIB_OBJCDARWIN, RTLD_NOW | RTLD_NOLOAD); 290 + if (!m_objcDarwin) 291 + return false; 292 + *((void**)&objc_helper) = ::dlsym(m_objcDarwin, "trampoline_objcMsgInfo"); 293 + if (!objc_helper) 294 + return false; 295 + return true; 296 + } 297 + 282 298 void* TrampolineMgr::printInfo(uint32_t index, CallStack* stack) 283 299 { 284 300 FunctionInfo* info = 0; 285 301 const AddrEntry& e = m_pInstance->m_entries[index]; 286 - auto it = m_functionInfo.find(e.name); 302 + std::map<std::string, FunctionInfo>::iterator it; 303 + std::string stamp; 287 304 std::ostream* out; 288 305 ReturnInfo retInfo; 306 + ArgumentWalker w(stack); 307 + std::string searchable = e.name; 289 308 309 + stamp = timeStamp(); 290 310 out = m_pInstance->getLogger(); 291 311 292 312 if (!g_returnInfo) 293 313 g_returnInfo = new std::stack<TrampolineMgr::ReturnInfo>; 294 314 295 - std::string stamp = timeStamp(); 296 315 (*out) << std::string(20 - stamp.size(), ' '); 297 316 (*out) << '[' << stamp << "] "; 298 317 (*out) << std::string(g_returnInfo->size(), ' '); 299 318 319 + // Special handling for Objective-C 320 + if (string_startsWith(e.name, "objc_msgSend")) 321 + { 322 + if (!objc_helper) 323 + { 324 + if (!loadObjCHelper()) 325 + goto no_objc; 326 + } 327 + 328 + if (string_endsWith(e.name, "ret")) 329 + w.nextPointer(); // skip the fpret/stret argument 330 + 331 + (*out) << objc_helper(e.name, w.nextPointer(), w.nextPointer(), searchable); 332 + } 333 + else no_objc: 334 + (*out) << e.printName; 335 + (*out) << '('; 336 + 337 + it = m_functionInfo.find(searchable); 338 + 300 339 if (it != m_functionInfo.end()) 301 340 { 302 - ArgumentWalker w(stack); 303 341 bool first = true; 304 - 305 - (*out) << e.printName << '('; 306 342 307 343 for (char c : it->second.arguments) 308 344 { ··· 316 352 (*out) << ") "; 317 353 } 318 354 else 319 - (*out) << e.printName << "(?) "; 355 + (*out) << "?) "; 320 356 (*out) << "ret_ip=" << stack->retAddr /*<< '(' << m_pInstance->inFile(stack->retAddr) << ')'*/ << std::endl << std::flush; 321 357 322 358 retInfo.retAddr = stack->retAddr; 359 + retInfo.it = it; 323 360 gettimeofday(&retInfo.callTime, 0); 324 361 325 362 g_returnInfo->push(retInfo); ··· 334 371 335 372 out = m_pInstance->getLogger(); 336 373 337 - const std::string& name = m_pInstance->m_entries[index].name; 338 - auto it = m_functionInfo.find(name); 374 + auto it = g_returnInfo->top().it; 339 375 340 376 std::string stamp = timeStamp(); 341 377 (*out) << std::string(20 - stamp.size(), ' '); ··· 408 444 else if (m_indexInt == 5) 409 445 rv = m_stack->r9; 410 446 else 411 - throw std::out_of_range("7th int argument not supported"); 447 + rv = m_stack->moreArguments[m_indexInt-6]; 412 448 413 449 m_indexInt++; 414 450 return rv;
+14 -6
src/dyld/Trampoline.h
··· 49 49 long double xmm[8]; // xmm7-xmm0 50 50 uint64_t r15, r14, r13, r12, r9, r8, rcx, rdx, rsi, rdi, rbx, rax; 51 51 void* retAddr; 52 + uint64_t moreArguments[]; 52 53 }; 53 54 #else 54 55 struct CallStack ··· 70 71 static std::string formatTime(double ms); 71 72 static void* printInfo(uint32_t index, CallStack* stack); 72 73 static void* printInfoR(uint32_t index, CallStack* stack); 74 + static bool loadObjCHelper(); 73 75 public: 74 76 typedef std::vector<std::pair<char,void*> > OutputArguments; 75 - struct ReturnInfo 76 - { 77 - void* retAddr; 78 - OutputArguments pointers; 79 - struct timeval callTime; 80 - }; 77 + 81 78 private: 82 79 struct AddrEntry 83 80 { ··· 99 96 char retType; 100 97 std::string arguments; 101 98 }; 99 + 102 100 class ArgumentWalker 103 101 { 104 102 public: ··· 127 125 #endif 128 126 OutputArguments m_pointers; 129 127 }; 128 + public: 129 + struct ReturnInfo 130 + { 131 + void* retAddr; 132 + OutputArguments pointers; 133 + struct timeval callTime; 134 + std::map<std::string, FunctionInfo>::iterator it; 135 + }; 136 + private: 130 137 131 138 static TrampolineMgr* m_pInstance; 132 139 ··· 138 145 std::string m_wd; 139 146 static struct timeval m_startup; 140 147 static std::map<std::string, FunctionInfo> m_functionInfo; 148 + static void* m_objcDarwin; 141 149 }; 142 150 143 151 #pragma pack(1)
+1
src/libobjcdarwin/CMakeLists.txt
··· 25 25 objc_msgSend.nasm 26 26 NameTranslate.cpp 27 27 ClassRegister.cpp 28 + TrampolineHelper.cpp 28 29 29 30 common/attribute.cpp 30 31 common/property.cpp
+56
src/libobjcdarwin/TrampolineHelper.cpp
··· 1 + #include <string> 2 + #include <objc/runtime.h> 3 + #include <cstring> 4 + #include <sstream> 5 + #include "visibility.h" 6 + #include "../util/stlutils.h" 7 + 8 + DARLING_VISIBLE std::string trampoline_objcMsgInfo(const std::string& invoker, void* arg1, SEL sel, std::string& searchable) asm("trampoline_objcMsgInfo"); 9 + 10 + std::string trampoline_objcMsgInfo(const std::string& invoker, void* arg1, SEL sel, std::string& searchable) 11 + { 12 + id obj; 13 + Class type; 14 + std::stringstream ret; 15 + 16 + if (string_startsWith(invoker, "objc_msgSendSuper2")) 17 + { 18 + const objc_super* s = static_cast<objc_super*>(arg1); 19 + obj = (id) class_getSuperclass(Class(s->super_class)); 20 + } 21 + else if (string_startsWith(invoker, "objc_msgSendSuper")) 22 + { 23 + const objc_super* s = static_cast<objc_super*>(arg1); 24 + obj = (id) s->super_class; 25 + } 26 + else 27 + obj = id(arg1); 28 + 29 + if (obj) 30 + { 31 + type = object_getClass(obj); 32 + 33 + if (class_isMetaClass(type)) 34 + ret << "+["; 35 + else 36 + ret << "-["; 37 + 38 + ret << class_getName(type); 39 + searchable = ret.str(); 40 + 41 + ret << '('; 42 + ret << obj << ") "; 43 + 44 + searchable += ' '; 45 + searchable += sel_getName(sel); 46 + searchable += ']'; 47 + } 48 + else 49 + ret << "?[nil(0x0) "; 50 + 51 + ret << sel_getName(sel); 52 + ret << ']'; 53 + 54 + return ret.str(); 55 + } 56 +
+2 -2
src/libobjcdarwin/objc_msgSendSuper.nasm
··· 1 - global __darwin_objc_msgSendSuper ; TODO: requires extracting superclass from Class 2 - global __darwin_objc_msgSendSuper2 1 + global __darwin_objc_msgSendSuper 2 + global __darwin_objc_msgSendSuper2 ; requires extracting superclass from Class 3 3 global __darwin_objc_msgSendSuper2_stret 4 4 extern objc_msg_lookup_super 5 5