this repo has no description
1
fork

Configure Feed

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

Remove libobjcdarwin, the relevant code will go into the libobjc2 submodule

-3032
-74
src/libobjcdarwin/CMakeLists.txt
··· 1 - project(libobjc) 2 - 3 - cmake_minimum_required(VERSION 2.4.0) 4 - if(COMMAND cmake_policy) 5 - cmake_policy(SET CMP0003 NEW) 6 - endif(COMMAND cmake_policy) 7 - 8 - enable_language(ASM_NASM) 9 - 10 - #if (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 11 - # message(FATAL_ERROR "Clang is the only supported compiler.") 12 - #endif (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 13 - 14 - if (BITS EQUAL 64) # Would need to be extended for ARM 15 - set(OBJC_ABI_2 TRUE) 16 - add_definitions(-DOBJC_ABI_2=1) 17 - message(STATUS "Building ObjC ABI 2") 18 - endif(BITS EQUAL 64) 19 - 20 - include_directories(${CMAKE_CURRENT_BINARY_DIR}) 21 - 22 - add_definitions(-D__STDC_LIMIT_MACROS) 23 - 24 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC -fvisibility=hidden -fconstant-string-class=NSConstantString -ggdb") 25 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -fPIC -fvisibility=hidden -ggdb") 26 - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fPIC") 27 - 28 - set(objcdarwin_SRCS 29 - objc_msgSend_fixup.nasm 30 - objc_msgSendSuper.nasm 31 - objc_msgSend.nasm 32 - 33 - NameTranslate.cpp 34 - ClassRegister.cpp 35 - TrampolineHelper.mm 36 - 37 - common/attribute.cpp 38 - common/property.cpp 39 - common/selector.cpp 40 - common/cfstring.cpp 41 - 42 - NSDarwinFramework.mm 43 - misc.mm 44 - ) 45 - 46 - if(NOT OBJC_ABI_2) 47 - set(objcdarwin_SRCS 48 - ${objcdarwin_SRCS} 49 - 50 - old/exceptions.cpp 51 - old/category.cpp 52 - old/class.cpp 53 - old/ivar.mm 54 - old/protocol.cpp 55 - ) 56 - else(NOT OBJC_ABI_2) 57 - set(objcdarwin_SRCS 58 - ${objcdarwin_SRCS} 59 - 60 - new/exceptions.cpp 61 - new/category.cpp 62 - new/class.cpp 63 - new/ivar.cpp 64 - new/protocol.cpp 65 - 66 - new/return.nasm 67 - ) 68 - endif(NOT OBJC_ABI_2) 69 - 70 - add_library(objcdarwin SHARED ${objcdarwin_SRCS}) 71 - target_link_libraries(objcdarwin Foundation util ${GNUSTEP_OBJC_CFLAGS}) 72 - 73 - install(TARGETS objcdarwin DESTINATION "lib${SUFFIX}/darling") 74 -
-120
src/libobjcdarwin/ClassRegister.cpp
··· 1 - #include "ClassRegister.h" 2 - #include <libdyld/dyld_public.h> 3 - #include <util/debug.h> 4 - 5 - #ifndef OBJC_ABI_2 6 - # include "old/protocol.h" 7 - # include "old/class.h" 8 - # include "old/category.h" 9 - #else 10 - # include "new/protocol.h" 11 - # include "new/class.h" 12 - # include "new/category.h" 13 - #endif 14 - #include "common/selector.h" 15 - #include <map> 16 - #include <queue> 17 - #include <cassert> 18 - #include "NSDarwinFramework.h" 19 - 20 - // Superclass references in Mach-O don't use classref 21 - // Neither do category class references 22 - std::map<const void*,Class> g_classPointers; 23 - std::queue<std::pair<Class,IMP>> g_pendingInitClasses; 24 - 25 - static void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) 26 - { 27 - size_t pos = 0; 28 - while ((pos = subject.find(search, pos)) != std::string::npos) 29 - { 30 - subject.replace(pos, search.length(), replace); 31 - pos += replace.length(); 32 - } 33 - } 34 - 35 - // Here we process Mach-O files that have been loaded before this native library 36 - // Then we register a handler to process all images loaded in the future 37 - __attribute__((constructor)) 38 - void RegisterAlreadyLoadedClasses() 39 - { 40 - //for (uint32_t i = 0; i < _dyld_image_count(); i++) 41 - //{ 42 - // const struct mach_header* hdr = _dyld_get_image_header(i); 43 - // ProcessImageLoad(hdr, 0); 44 - //} 45 - 46 - _dyld_register_func_for_add_image(ProcessImageLoad); 47 - _dyld_register_func_for_remove_image(ProcessImageUnload); 48 - 49 - //std::cout << "Done registering\n"; 50 - } 51 - 52 - __attribute__((destructor)) 53 - void DeregisterHooks() 54 - { 55 - _dyld_deregister_func_for_add_image(ProcessImageLoad); 56 - _dyld_deregister_func_for_remove_image(ProcessImageUnload); 57 - } 58 - 59 - void ProcessImageLoad(const struct mach_header* mh, intptr_t slide) 60 - { 61 - unsigned long size; 62 - std::vector<const char*> classNames; 63 - void* dataPtr = nullptr; 64 - 65 - #ifdef OBJC_ABI_2 66 - const class_t** classes; 67 - ProcessProtocolsNew(mh, slide); 68 - 69 - classes = reinterpret_cast<const class_t**>( 70 - getsectdata(mh, SEG_OBJC_CLASSLIST_NEW, SECT_OBJC_CLASSLIST_NEW, &size) 71 - ); 72 - if (classes) 73 - { 74 - classNames = ProcessClassesNew(mh, slide, classes, size); 75 - dataPtr = (void*)*classes; 76 - } 77 - 78 - ProcessCategoriesNew(mh, slide); 79 - #else 80 - module_info* modinfo; 81 - ProcessProtocolsOld(mh, slide); 82 - 83 - modinfo = reinterpret_cast<module_info*>( 84 - getsectdata(mh, SEG_OBJC_MODINFO_OLD, SECT_OBJC_MODINFO_OLD, &size) 85 - ); 86 - 87 - if (modinfo && modinfo->symtab) 88 - { 89 - classNames = ProcessClassesOld(mh, slide, modinfo); 90 - dataPtr = modinfo; 91 - ProcessCategoriesOld(mh, slide, modinfo); 92 - } 93 - #endif 94 - 95 - UpdateClassRefs(mh); 96 - UpdateSelectors(mh, slide); 97 - 98 - // Do this only for dynamic libs (slide > 0) 99 - if (!classNames.empty() && slide > 0) 100 - { 101 - // Generate a NSFramework_XXXX class for GNUstep's NSBundle 102 - const char* path = dyld_image_path_containing_address(dataPtr); 103 - assert(path != nullptr); 104 - RegisterFramework(&classNames[0], classNames.size(), path); 105 - } 106 - 107 - static SEL selInit = sel_getUid("load"); 108 - while (!g_pendingInitClasses.empty()) 109 - { 110 - auto pair = g_pendingInitClasses.front(); 111 - g_pendingInitClasses.pop(); 112 - pair.second(reinterpret_cast<objc_object*>(pair.first), selInit); 113 - } 114 - } 115 - 116 - void ProcessImageUnload(const struct mach_header* mh, intptr_t) 117 - { 118 - // TODO 119 - } 120 -
-16
src/libobjcdarwin/ClassRegister.h
··· 1 - #ifndef CLASSREGISTER_H 2 - #define CLASSREGISTER_H 3 - #ifndef __STDC_LIMIT_MACROS 4 - # define __STDC_LIMIT_MACROS 5 - #endif 6 - #include <stdint.h> 7 - #include <cstddef> 8 - #include <algorithm> 9 - #include <objc/runtime.h> 10 - #include "../util/log.h" 11 - 12 - void ProcessImageLoad(const struct mach_header* mh, intptr_t slide); 13 - void ProcessImageUnload(const struct mach_header* mh, intptr_t); 14 - 15 - #endif 16 -
-44
src/libobjcdarwin/NSDarwinFramework.h
··· 1 - #ifndef NSDARWINFRAMEWORK_H 2 - #define NSDARWINFRAMEWORK_H 3 - #include <cstddef> 4 - 5 - #ifdef __OBJC__ 6 - #import <Foundation/NSObject.h> 7 - #import <Foundation/NSString.h> 8 - #import <Foundation/NSBundle.h> 9 - 10 - // This is a class gnustep-base expect to find in every framework 11 - 12 - @interface NSDarwinFramework : NSObject { 13 - NSString* _frameworkVersion; 14 - NSString** _frameworkClasses; 15 - } 16 - 17 - + (void) initialize; 18 - 19 - // Darling's API 20 - - (id) initWithVersion: (NSString*)version 21 - classes: (NSString**)classes; 22 - - (void) dealloc; 23 - 24 - - (NSString*) thisFrameworkVersion; 25 - - (NSString**) thisFrameworkClasses; 26 - 27 - // GNUstep's API 28 - + (NSString*) frameworkVersion; 29 - + (NSString**) frameworkClasses; 30 - @end 31 - 32 - 33 - // NSBundle private implementation details 34 - @interface NSBundle (Private) 35 - + (NSBundle*) _addFrameworkFromClass: (Class)frameworkClass 36 - withPath:(NSString*)path; 37 - @end 38 - 39 - #endif // __OBJC__ 40 - 41 - void RegisterFramework(const char** classNames, size_t count, const char* path); 42 - 43 - #endif 44 -
-136
src/libobjcdarwin/NSDarwinFramework.mm
··· 1 - #include "NSDarwinFramework.h" 2 - #import <Foundation/NSDictionary.h> 3 - #include <map> 4 - #include <string> 5 - #include <objc/runtime.h> 6 - #include "../util/log.h" 7 - 8 - static NSMutableDictionary* _frameworks; 9 - 10 - @implementation NSDarwinFramework 11 - - (id) initWithVersion: (NSString*)version 12 - classes: (NSString**)classes 13 - { 14 - _frameworkVersion = version; 15 - _frameworkClasses = classes; 16 - 17 - [_frameworks setObject: self 18 - forKey: NSStringFromClass([self class])]; 19 - 20 - return [super init]; 21 - } 22 - 23 - + (void) initialize 24 - { 25 - if (self == [NSDarwinFramework class]) 26 - { 27 - _frameworks = [[NSMutableDictionary alloc] init]; 28 - } 29 - } 30 - 31 - - (void) dealloc 32 - { 33 - if (_frameworkVersion != nil) 34 - [_frameworkVersion release]; 35 - [super dealloc]; 36 - } 37 - 38 - - (NSString*) thisFrameworkVersion 39 - { 40 - return _frameworkVersion; 41 - } 42 - 43 - - (NSString**) thisFrameworkClasses 44 - { 45 - return _frameworkClasses; 46 - } 47 - 48 - + (NSString*) frameworkVersion 49 - { 50 - NSDarwinFramework* instance; 51 - 52 - instance = [_frameworks objectForKey: NSStringFromClass(self)]; 53 - if (instance == nil) 54 - return nil; 55 - else 56 - return [instance thisFrameworkVersion]; 57 - } 58 - 59 - + (NSString**) frameworkClasses 60 - { 61 - NSDarwinFramework* instance; 62 - static NSString* emptyList[] = { nil }; 63 - 64 - instance = [_frameworks objectForKey: NSStringFromClass(self)]; 65 - if (instance == nil) 66 - return emptyList; 67 - else 68 - return [instance thisFrameworkClasses]; 69 - } 70 - 71 - @end 72 - 73 - void RegisterFramework(const char** classNames, size_t count, const char* path) 74 - { 75 - NSString* bundlePath = [NSString stringWithUTF8String: path]; 76 - NSString *bundleName, *bundleVersion = nil; 77 - NSString* className; 78 - Class synthetizedClass; 79 - NSDarwinFramework* fwInstance; 80 - NSString** nsClassNames; 81 - 82 - while (![bundlePath isEqual: @"/"]) 83 - { 84 - NSString* cur = [bundlePath lastPathComponent]; 85 - NSString* ext = [bundlePath pathExtension]; 86 - 87 - if ([ext isEqual: @"framework"] || [ext isEqual: @"bundle"] || [ext isEqual: @"app"]) 88 - { 89 - break; 90 - } 91 - 92 - bundlePath = [bundlePath stringByDeletingLastPathComponent]; 93 - if ([[bundlePath lastPathComponent] isEqual: @"Versions"]) 94 - bundleVersion = cur; 95 - } 96 - 97 - if ([bundlePath isEqual: @"/"]) 98 - { 99 - LOG << "Invalid bundle lib path: " << path << std::endl; 100 - return; 101 - } 102 - 103 - bundleName = [[bundlePath lastPathComponent] stringByDeletingPathExtension]; 104 - 105 - // Needed to have a valid class name 106 - bundleName = [bundleName stringByReplacingString: @"_" withString: @"__"]; 107 - bundleName = [bundleName stringByReplacingString: @"-" withString: @"_0"]; 108 - bundleName = [bundleName stringByReplacingString: @"+" withString: @"_1"]; 109 - 110 - className = [@"NSFramework_" stringByAppendingString: bundleName]; 111 - 112 - synthetizedClass = objc_allocateClassPair([NSDarwinFramework class], [className UTF8String], 0); 113 - objc_registerClassPair(synthetizedClass); 114 - 115 - nsClassNames = new NSString*[count+1]; 116 - for (size_t i = 0; i < count; i++) 117 - nsClassNames[i] = [[NSString alloc] initWithUTF8String: classNames[i]]; 118 - 119 - nsClassNames[count] = nil; 120 - 121 - fwInstance = [[synthetizedClass alloc] initWithVersion: bundleVersion 122 - classes: nsClassNames]; 123 - 124 - LOG << "Created NSDarwinFramework instance named " << ([className UTF8String]) << 125 - "; version: " << ([bundleVersion UTF8String]) << std::endl; 126 - 127 - if ([NSBundle respondsToSelector: @selector(_addFrameworkFromClass:withPath:)]) 128 - { 129 - [NSBundle _addFrameworkFromClass: synthetizedClass 130 - withPath: [NSString stringWithUTF8String: path]]; 131 - } 132 - else 133 - LOG << "NSFramework_* not registered, _addFrameworkFromClass:withPath: not supported by runtime\n"; 134 - 135 - } 136 -
-78
src/libobjcdarwin/NameTranslate.cpp
··· 1 - #include <cstring> 2 - #include <memory> 3 - #include <dlfcn.h> 4 - #include <cstdio> 5 - #include "visibility.h" 6 - 7 - DARLING_VISIBLE extern "C" void* _objc_empty_cache = 0; 8 - DARLING_VISIBLE extern "C" void* _objc_empty_vtable = 0; 9 - 10 - #ifdef __x86_64__ 11 - DARLING_VISIBLE extern "C" void* _objc_dummy_ehtype = 0; 12 - #endif 13 - 14 - namespace Darling 15 - { 16 - typedef bool (*DlsymHookFunc)(char* symName); 17 - void registerDlsymHook(DlsymHookFunc func); 18 - void deregisterDlsymHook(DlsymHookFunc func); 19 - }; 20 - 21 - static bool ClassTranslator(char* symName); 22 - 23 - __attribute__((constructor)) 24 - static void initTranslation() 25 - { 26 - Darling::registerDlsymHook(ClassTranslator); 27 - } 28 - 29 - __attribute__((destructor)) 30 - static void exitTranslation() 31 - { 32 - Darling::deregisterDlsymHook(ClassTranslator); 33 - } 34 - 35 - static bool ClassTranslator(char* name) 36 - { 37 - #ifdef __x86_64__ 38 - if (strncmp(name, "OBJC_EHTYPE_$_", 14) == 0 || strcmp(name, "OBJC_EHTYPE_id") == 0) 39 - { 40 - strcpy(name, "_objc_dummy_ehtype"); 41 - return true; 42 - } 43 - else 44 - #endif 45 - 46 - if (char* off = strstr(name, "_$_")) 47 - { 48 - size_t offset = off - name; 49 - 50 - memmove(name+1, name, strlen(name)+1); 51 - *name = '_'; // prefix with an underscore 52 - offset++; 53 - // remove $_ 54 - memmove(name + offset, name + offset + 2, strlen(name + offset + 2)+1); 55 - 56 - return true; 57 - } 58 - #ifdef __x86_64__ 59 - else if (strcmp(name, "__objc_personality_v0") == 0) 60 - { 61 - strcpy(name, "__gnu_objc_personality_v0"); 62 - return true; 63 - } 64 - #endif 65 - else if (*name == 'k') 66 - { 67 - // TODO: this may be worth doing differently 68 - char* pos = strstr(name, "Key"); 69 - if (pos == name + strlen(name) - 3) 70 - { 71 - *pos = 0; 72 - return true; 73 - } 74 - } 75 - 76 - return false; 77 - } 78 -
-45
src/libobjcdarwin/TopologySort.h
··· 1 - #ifndef TOPOLOGYSORT_H 2 - #define TOPOLOGYSORT_H 3 - #include <map> 4 - #include <set> 5 - #include <vector> 6 - #include <cassert> 7 - 8 - // GNUStep ObjC runtime doesn't have "future classes", hence we need a TopologySort 9 - 10 - template <typename T, typename GetDepCb> 11 - void topology_visit(T* t, std::vector<T*>& elems, GetDepCb getDependency, std::set<T*>& visited) 12 - { 13 - if (!visited.count(t)) 14 - { 15 - visited.insert(t); 16 - auto deps = getDependency(t); 17 - 18 - for (T* d : deps) 19 - topology_visit(d, elems, getDependency, visited); 20 - 21 - elems.push_back(t); 22 - } 23 - } 24 - 25 - template <typename T, typename GetDepCb> 26 - void topology_sort(std::vector<T*>& elems, GetDepCb getDependency) 27 - { 28 - std::set<T*> visited; 29 - std::vector<T*> input = std::move(elems); 30 - 31 - elems.clear(); 32 - 33 - for (T* t : input) 34 - topology_visit(t, elems, getDependency, visited); 35 - } 36 - 37 - template <typename T, typename GetDepCb> 38 - void topology_sort(const std::set<T*>& elems, std::vector<T*>& sorted, GetDepCb getDependency) 39 - { 40 - std::set<T*> visited; 41 - for (T* t : elems) 42 - topology_visit(t, sorted, getDependency, visited); 43 - } 44 - 45 - #endif
-39
src/libobjcdarwin/TopologySortTest.cpp
··· 1 - #include "TopologySort.h" 2 - #include <iostream> 3 - #include <cassert> 4 - 5 - using namespace std; 6 - 7 - struct Obj 8 - { 9 - Obj(int n) : num(n), done(false) {} 10 - int num; 11 - bool done; 12 - set<Obj*> deps; 13 - }; 14 - 15 - int main() 16 - { 17 - vector<Obj*> objs; 18 - 19 - for (size_t i = 0; i < 5; i++) 20 - objs.push_back(new Obj(i)); 21 - 22 - objs[1]->deps.insert(objs[0]); 23 - objs[1]->deps.insert(objs[2]); 24 - objs[0]->deps.insert(objs[3]); 25 - objs[4]->deps.insert(objs[1]); 26 - 27 - topology_sort<Obj>(objs, [](Obj* o) { return o->deps; }); 28 - 29 - for (Obj* o : objs) 30 - { 31 - o->done = true; 32 - for (Obj* d : o->deps) 33 - assert(d->done); 34 - std::cout << o->num << std::endl; 35 - } 36 - 37 - return 0; 38 - } 39 -
-89
src/libobjcdarwin/TrampolineHelper.mm
··· 1 - #include <string> 2 - #include <objc/runtime.h> 3 - #include <cstring> 4 - #include <sstream> 5 - #include <iostream> 6 - #include <Foundation/NSObject.h> 7 - #include "visibility.h" 8 - #include "../util/stlutils.h" 9 - 10 - DARLING_VISIBLE std::string trampoline_objcMsgInfo(const std::string& invoker, void* arg1, SEL sel, std::string& searchable) asm("trampoline_objcMsgInfo"); 11 - 12 - std::string trampoline_objcMsgInfo(const std::string& invoker, void* arg1, SEL sel, std::string& searchable) 13 - { 14 - id obj; 15 - Class type; 16 - std::stringstream ret; 17 - bool superCall = false; 18 - 19 - if (string_startsWith(invoker, "objc_msgSendSuper2")) 20 - { 21 - const objc_super* s = static_cast<objc_super*>(arg1); 22 - obj = (id) class_getSuperclass(Class(s->super_class)); 23 - superCall = true; 24 - } 25 - else if (string_startsWith(invoker, "objc_msgSendSuper")) 26 - { 27 - const objc_super* s = static_cast<objc_super*>(arg1); 28 - obj = (id) s->super_class; 29 - superCall = true; 30 - } 31 - else 32 - obj = id(arg1); 33 - 34 - if (string_endsWith(invoker, "_fixup")) 35 - { 36 - struct fixable 37 - { 38 - void* pfn; 39 - SEL sel; 40 - }; 41 - const fixable* f = (fixable*) sel; 42 - sel = f->sel; 43 - } 44 - 45 - const char* selname = sel_getName(sel); 46 - if (obj) 47 - { 48 - const char* clsname; 49 - bool isMeta; 50 - 51 - type = object_getClass(obj); 52 - clsname = class_getName(type); 53 - 54 - isMeta = class_isMetaClass(type) == YES; 55 - if (isMeta && !superCall) 56 - ret << "+["; 57 - else 58 - ret << "-["; 59 - 60 - // std::cout << "Resp: " << bool([[NSObject class] instancesRespondToSelector:@selector(description)]) << std::endl; 61 - 62 - searchable = ret.str(); 63 - if ( (!isMeta && [NSObject instancesRespondToSelector:sel]) || 64 - (isMeta && ([[NSObject class] instancesRespondToSelector:sel] || !strcmp(selname, "alloc"))) 65 - ) 66 - { 67 - searchable += "NSObject"; 68 - } 69 - else 70 - searchable += clsname; 71 - 72 - ret << clsname; 73 - 74 - ret << '('; 75 - ret << obj << ") "; 76 - 77 - searchable += ' '; 78 - searchable += selname; 79 - searchable += ']'; 80 - } 81 - else 82 - ret << "?[nil(0x0) "; 83 - 84 - ret << selname; 85 - ret << ']'; 86 - 87 - return ret.str(); 88 - } 89 -
-16
src/libobjcdarwin/common/AppleLayout.h
··· 1 - #ifndef COMMON_APPLELAYOUT_H 2 - #define COMMON_APPLELAYOUT_H 3 - #include <objc/runtime.h> 4 - 5 - union selref 6 - { 7 - const char* selName; 8 - SEL sel; 9 - }; 10 - struct msgref 11 - { 12 - void* objc_msgSend_fixup; // function pointer 13 - selref sel; 14 - }; 15 - 16 - #endif
-46
src/libobjcdarwin/common/attribute.cpp
··· 1 - #include "attribute.h" 2 - #include "../../util/log.h" 3 - #include <cassert> 4 - 5 - bool nextAttribute(objc_property_attribute_t& next, const char*& pos, std::vector<std::string>& strings) 6 - { 7 - if (!*pos) 8 - return false; 9 - else if (*pos == ',') 10 - pos++; 11 - 12 - if (*pos == '"') 13 - { 14 - const char* start = ++pos; 15 - while (*pos != '"' && *pos) 16 - pos++; 17 - 18 - assert(*pos != '\0'); 19 - 20 - strings.push_back(std::string(start, pos-start)); 21 - next.name = strings.back().c_str(); 22 - 23 - start = ++pos; 24 - while (*pos != ',' && *pos) 25 - pos++; 26 - 27 - strings.push_back(std::string(start, pos-start)); 28 - next.value = strings.back().c_str(); 29 - } 30 - else 31 - { 32 - strings.push_back(std::string(1, *pos)); 33 - next.name = strings.back().c_str(); 34 - const char* start = ++pos; 35 - 36 - while (*pos != ',' && *pos) 37 - pos++; 38 - 39 - strings.push_back(std::string(start, pos-start)); 40 - next.value = strings.back().c_str(); 41 - } 42 - 43 - LOG << "Attr: name: " << next.name << "; value: " << next.value << std::endl; 44 - 45 - return true; 46 - }
-11
src/libobjcdarwin/common/attribute.h
··· 1 - #ifndef COMMON_ATTRIBUTE_H 2 - #define COMMON_ATTRIBUTE_H 3 - #include <objc/runtime.h> 4 - #include <stdint.h> 5 - #include <string> 6 - #include "./AppleLayout.h" 7 - #include <vector> 8 - 9 - bool nextAttribute(objc_property_attribute_t& next, const char*& pos, std::vector<std::string>& strings); 10 - 11 - #endif
-89
src/libobjcdarwin/common/cfstring.cpp
··· 1 - #include <libdyld/dyld_public.h> 2 - #include <stdint.h> 3 - #include <cstring> 4 - #include <algorithm> 5 - 6 - #pragma pack(1) 7 - struct apple_cfstring 8 - { 9 - void* isa; 10 - uint8_t flags; 11 - uint8_t typeID; 12 - uint8_t unused[2]; 13 - #ifdef __x86_64__ 14 - uint32_t extraFlags; 15 - #endif 16 - void* data; 17 - unsigned long length; 18 - }; 19 - // 32bit: 16 bytes 20 - // 64bit: 28 bytes -> 32! 21 - #pragma pack() 22 - 23 - // gnustep-corebase 24 - struct gnustep_cfstring 25 - { 26 - void* isa; 27 - int16_t typeID; 28 - struct 29 - { 30 - int16_t ro:1; 31 - int16_t reserved:7; 32 - int16_t info:8; 33 - } _flags; 34 - void* data; 35 - uint32_t length; 36 - uintptr_t hashCode; 37 - }; 38 - // 32bit: ? bytes 39 - // 64bit: 36 bytes 40 - // -> FIXME: hashes are broken! 41 - 42 - enum { apple_immutable = 0x80, apple_notinline = 0x40, apple_unicode = 0x20, apple_hasnull = 0x10, apple_haslength = 8 }; 43 - enum { gnustep_mutable = 1, gnustep_inline = 2, gnustep_unicode = 4, gnustep_haslength = 8, gnustep_hasnull = 0x10 }; 44 - 45 - static const int TYPEID_STRING_APPLE = 7; 46 - static const int TYPEID_STRING_GNUSTEP = 24; 47 - 48 - static void FixupCFStrings(apple_cfstring* strings, size_t count); 49 - 50 - void UpdateCFStrings(const struct mach_header* mh) 51 - { 52 - unsigned long size; 53 - apple_cfstring* strings = reinterpret_cast<apple_cfstring*>( 54 - getsectdata(mh, "__DATA", "__cfstring", &size) 55 - ); 56 - 57 - if (strings) 58 - FixupCFStrings(strings, size / sizeof(apple_cfstring)); 59 - 60 - strings = reinterpret_cast<apple_cfstring*>( 61 - getsectdata(mh, "__DATA", "__ustring", &size) 62 - ); 63 - 64 - if (strings) 65 - FixupCFStrings(strings, size / sizeof(apple_cfstring)); 66 - } 67 - 68 - void FixupCFStrings(apple_cfstring* strings, size_t count) 69 - { 70 - for (size_t i = 0; i < count; i++) 71 - { 72 - gnustep_cfstring fixed; 73 - 74 - memset(&fixed, 0, sizeof(fixed)); 75 - 76 - fixed.isa = strings[i].isa; // This has already been "fixed" during linking 77 - fixed.length = strings[i].length; 78 - fixed.data = strings[i].data; 79 - fixed._flags.ro = 1; 80 - fixed.typeID = TYPEID_STRING_GNUSTEP; 81 - fixed._flags.info = gnustep_haslength | gnustep_hasnull; 82 - 83 - if (strings[i].flags & apple_unicode) 84 - fixed._flags.info |= gnustep_unicode; 85 - 86 - memcpy((void*) (strings+i), &fixed, std::min(sizeof(gnustep_cfstring), sizeof(apple_cfstring))); 87 - } 88 - } 89 -
-8
src/libobjcdarwin/common/cfstring.h
··· 1 - #ifndef COMMON_CFSTRING_H 2 - #define COMMON_CFSTRING_H 3 - 4 - // Updates compiled constant CFStrings 5 - void UpdateCFStrings(const struct mach_header* mh); 6 - 7 - #endif 8 -
-40
src/libobjcdarwin/common/method.h
··· 1 - #ifndef COMMON_METHOD_H 2 - #define COMMON_METHOD_H 3 - #include <queue> 4 - #include <cstring> 5 - #include <string> 6 - #include <objc/runtime.h> 7 - #include <util/debug.h> 8 - #include <cassert> 9 - #include "selector.h" 10 - 11 - extern std::queue<std::pair<Class, IMP>> g_pendingInitClasses; 12 - 13 - template<typename ListType> void ConvertMethodListGen(Class c, const ListType* list) 14 - { 15 - LOG << list->count << " methods within\n"; 16 - 17 - const bool isMeta = class_isMetaClass(c) == YES; 18 - 19 - for (size_t i = 0; i < list->count; i++) 20 - { 21 - auto* m = &list->method_list[i]; 22 - IMP imp = reinterpret_cast<IMP>(m->impl); 23 - 24 - LOG << "Method: selName: " << m->selName << "; types: " << m->types << "; impl: " << m->impl << std::endl; 25 - 26 - SEL sel; 27 - std::string selType = m->types; 28 - 29 - ConvertSelectorType(selType); 30 - 31 - sel = sel_registerTypedName_np(m->selName, selType.c_str()); 32 - 33 - class_addMethod(c, sel, imp, selType.c_str()); 34 - 35 - if (isMeta && strcmp(m->selName, "load") == 0) 36 - g_pendingInitClasses.push(std::make_pair<objc_class*,IMP>((Class)c, *imp)); 37 - } 38 - } 39 - 40 - #endif
-10
src/libobjcdarwin/common/property.cpp
··· 1 - #include "property.h" 2 - #include "../libobjc/class.h" // For a bug workaround only 3 - #include "../libobjc/properties.h" // ditto 4 - 5 - // Fixed in GNUstep r35658 6 - void bug_gnustepFixPropertyCount(Class c) 7 - { 8 - if (c->properties->count == 0) 9 - c->properties->count = 1; 10 - }
-51
src/libobjcdarwin/common/property.h
··· 1 - #ifndef COMMON_PROPERTY_H 2 - #define COMMON_PROPERTY_H 3 - #include <objc/runtime.h> 4 - #include <stdint.h> 5 - #include "./AppleLayout.h" 6 - #include "../../util/log.h" 7 - #include "attribute.h" 8 - #include <vector> 9 - #include <cstring> 10 - 11 - template<typename PropList, typename Func> 12 - void ConvertProperties(const PropList* props, Func f) 13 - { 14 - LOG << "Registering " << props->count << " properties\n"; 15 - 16 - for (uint32_t i = 0; i < props->count; i++) 17 - { 18 - auto* prop = &props->list[i]; 19 - std::vector<objc_property_attribute_t> attribs; 20 - std::vector<std::string> strings; 21 - objc_property_attribute_t next; 22 - const char* pos = prop->attributes; 23 - bool hadName = false; 24 - 25 - LOG << "Converting " << prop->attributes << std::endl; 26 - 27 - while (nextAttribute(next, pos, strings)) 28 - { 29 - // THIS IS VERY WRONG 30 - // But needed as a workaround for a serious mistake made in libobjc2's design! 31 - if (strcmp(next.name, "V") == 0) 32 - { 33 - next.value = prop->name; 34 - hadName = true; 35 - } 36 - attribs.push_back(next); 37 - } 38 - 39 - if (!hadName) 40 - attribs.push_back(objc_property_attribute_t{"V", prop->name}); 41 - 42 - //attribs.clear(); 43 - LOG << "\tProperty " << prop->name << " with " << attribs.size() << " attributes\n"; 44 - f(prop->name, &attribs[0], attribs.size()); 45 - } 46 - } 47 - 48 - void bug_gnustepFixPropertyCount(Class c); 49 - 50 - 51 - #endif
-33
src/libobjcdarwin/common/ref.h
··· 1 - #ifndef COMMON_REF_H 2 - #define COMMON_REF_H 3 - #include <algorithm> 4 - #include <map> 5 - 6 - template<typename OrigType, typename NewType> 7 - static void find_and_fix(OrigType** start, OrigType** end, const OrigType* what, const NewType* ptr) 8 - { 9 - OrigType** pos = std::find(start, end, const_cast<OrigType*>(what)); 10 - if (pos != end) 11 - { 12 - LOG << "ObjC fixup @" << pos << ": " << *pos << " -> " << ptr << std::endl; 13 - *reinterpret_cast<uintptr_t*>(pos) = reinterpret_cast<uintptr_t>(ptr); 14 - } 15 - } 16 - 17 - template<typename OrigType, typename NewType> 18 - static void find_and_fix(OrigType** start, OrigType** end, const std::map<const OrigType*,NewType*>& map) 19 - { 20 - LOG << "ObjC fixup in range " << start << " -> " << end << std::endl; 21 - std::for_each(start, end, [&map](OrigType*& origPtr) { 22 - auto it = map.find(origPtr); 23 - if (it != map.end()) 24 - { 25 - LOG << "ObjC fixup @" << &origPtr << ": " << origPtr << " -> " << it->second << std::endl; 26 - origPtr = reinterpret_cast<OrigType*>(it->second); 27 - } 28 - else 29 - LOG << "ObjC fixup FAILED @" << &origPtr << std::endl; 30 - }); 31 - } 32 - 33 - #endif
-79
src/libobjcdarwin/common/selector.cpp
··· 1 - #include "selector.h" 2 - #include "../new/AppleLayout.h" 3 - #include "../old/AppleLayout.h" 4 - #include <libdyld/dyld_public.h> 5 - #include <util/debug.h> 6 - #include <utility> 7 - #include <cstring> 8 - 9 - void UpdateSelectors(const struct mach_header* mh, intptr_t slide) 10 - { 11 - selref* sel_refs; 12 - msgref* msg_refs; 13 - unsigned long selsize, msgsize; 14 - 15 - #ifdef OBJC_ABI_2 16 - sel_refs = reinterpret_cast<selref*>( 17 - getsectdata(mh, SEG_OBJC_SELREFS_NEW, SECT_OBJC_SELREFS_NEW, &selsize) 18 - ); 19 - 20 - msg_refs = reinterpret_cast<msgref*>( 21 - getsectdata(mh, SEG_OBJC_MSGREFS_NEW, SECT_OBJC_MSGREFS_NEW, &msgsize) 22 - ); 23 - 24 - #else 25 - 26 - sel_refs = reinterpret_cast<selref*>( 27 - getsectdata(mh, SEG_OBJC_SELREFS_OLD, SECT_OBJC_SELREFS_OLD, &selsize) 28 - ); 29 - #endif 30 - 31 - if (sel_refs) 32 - { 33 - for (size_t i = 0; i < selsize / sizeof(selref); i++) 34 - { 35 - SEL native = sel_getUid(sel_refs[i].selName); 36 - LOG << "ObjC SEL \"" << sel_refs[i].selName << "\" fixup @" << (sel_refs+i) << ": " << sel_refs[i].sel << " -> " << native << std::endl; 37 - sel_refs[i].sel = native; 38 - } 39 - } 40 - 41 - #ifdef OBJC_ABI_2 42 - if (msg_refs) 43 - { 44 - for (size_t i = 0; i < msgsize / sizeof(msgref); i++) 45 - { 46 - SEL native = sel_getUid(msg_refs[i].sel.selName); 47 - LOG << "ObjC msgref \"" << msg_refs[i].sel.selName << "\" fixup @" << &msg_refs[i].sel.sel << ": " << msg_refs[i].sel.sel << " -> " << native << std::endl; 48 - msg_refs[i].sel.sel = native; 49 - } 50 - } 51 - #endif 52 - } 53 - 54 - 55 - static const std::pair<const char*, const char*> equivalentTypes[] = { 56 - std::make_pair("CGRect", "_NSRect"), 57 - std::make_pair("CGPoint", "_NSPoint"), 58 - std::make_pair("CGSize", "_NSSize") 59 - }; 60 - 61 - void ConvertSelectorType(std::string& selType) 62 - { 63 - bool changed = false; 64 - for (auto p : equivalentTypes) 65 - { 66 - size_t pos; 67 - 68 - while ((pos = selType.find(p.first)) != std::string::npos) 69 - { 70 - selType.replace(pos, strlen(p.first), p.second); 71 - changed = true; 72 - } 73 - } 74 - 75 - if (changed) 76 - LOG << "convertSelectorType: new type info is " << selType << std::endl; 77 - } 78 - 79 -
-10
src/libobjcdarwin/common/selector.h
··· 1 - #ifndef COMMON_SELECTOR_H 2 - #define COMMON_SELECTOR_H 3 - #include <objc/runtime.h> 4 - #include <stdint.h> 5 - #include <string> 6 - 7 - void UpdateSelectors(const struct mach_header* mh, intptr_t slide); 8 - void ConvertSelectorType(std::string& selType); 9 - 10 - #endif
-291
src/libobjcdarwin/libobjc/class.h
··· 1 - #ifndef __OBJC_CLASS_H_INCLUDED 2 - #define __OBJC_CLASS_H_INCLUDED 3 - #include "visibility.h" 4 - 5 - /** 6 - * Overflow bitfield. Used for bitfields that are more than 63 bits. 7 - */ 8 - struct objc_bitfield 9 - { 10 - /** 11 - * The number of elements in the values array. 12 - */ 13 - int32_t length; 14 - /** 15 - * An array of values. Each 32 bits is stored in the native endian for the 16 - * platform. 17 - */ 18 - int32_t values[0]; 19 - }; 20 - 21 - struct objc_class 22 - { 23 - /** 24 - * Pointer to the metaclass for this class. The metaclass defines the 25 - * methods use when a message is sent to the class, rather than an 26 - * instance. 27 - */ 28 - struct objc_class *isa; 29 - /** 30 - * Pointer to the superclass. The compiler will set this to the name of 31 - * the superclass, the runtime will initialize it to point to the real 32 - * class. 33 - */ 34 - struct objc_class *super_class; 35 - /** 36 - * The name of this class. Set to the same value for both the class and 37 - * its associated metaclass. 38 - */ 39 - const char *name; 40 - /** 41 - * The version of this class. This is not used by the language, but may be 42 - * set explicitly at class load time. 43 - */ 44 - long version; 45 - /** 46 - * A bitfield containing various flags. See the objc_class_flags 47 - * enumerated type for possible values. 48 - */ 49 - unsigned long info; 50 - /** 51 - * The size of this class. For classes using the non-fragile ABI, the 52 - * compiler will set this to a negative value The absolute value will be 53 - * the size of the instance variables defined on just this class. When 54 - * using the fragile ABI, the instance size is the size of instances of 55 - * this class, including any instance variables defined on superclasses. 56 - * 57 - * In both cases, this will be set to the size of an instance of the class 58 - * after the class is registered with the runtime. 59 - */ 60 - long instance_size; 61 - /** 62 - * Metadata describing the instance variables in this class. 63 - */ 64 - struct objc_ivar_list *ivars; 65 - /** 66 - * Metadata for for defining the mappings from selectors to IMPs. Linked 67 - * list of method list structures, one per class and one per category. 68 - */ 69 - struct objc_method_list *methods; 70 - /** 71 - * The dispatch table for this class. Intialized and maintained by the 72 - * runtime. 73 - */ 74 - void *dtable; 75 - /** 76 - * A pointer to the first subclass for this class. Filled in by the 77 - * runtime. 78 - */ 79 - struct objc_class *subclass_list; 80 - /** 81 - * A pointer to the next sibling class to this. You may find all 82 - * subclasses of a given class by following the subclass_list pointer and 83 - * then subsequently following the sibling_class pointers in the 84 - * subclasses. 85 - */ 86 - struct objc_class *sibling_class; 87 - 88 - /** 89 - * Metadata describing the protocols adopted by this class. Not used by 90 - * the runtime. 91 - */ 92 - struct objc_protocol_list *protocols; 93 - /** 94 - * Linked list of extra data attached to this class. 95 - */ 96 - struct reference_list *extra_data; 97 - /** 98 - * New ABI. The following fields are only available with classes compiled to 99 - * support the new ABI. You may test whether any given class supports this 100 - * ABI by using the CLS_ISNEW_ABI() macro. 101 - */ 102 - 103 - /** 104 - * The version of the ABI used for this class. Zero indicates the ABI first 105 - * implemented by clang 1.0. One indicates the presence of bitmaps 106 - * indicating the offsets of strong, weak, and unretained ivars. 107 - */ 108 - long abi_version; 109 - 110 - /** 111 - * Array of pointers to variables where the runtime will store the ivar 112 - * offset. These may be used for faster access to non-fragile ivars if all 113 - * of the code is compiled for the new ABI. Each of these pointers should 114 - * have the mangled name __objc_ivar_offset_value_{class name}.{ivar name} 115 - * 116 - * When using the compatible non-fragile ABI, this faster form should only be 117 - * used for classes declared in the same compilation unit. 118 - * 119 - * The compiler should also emit symbols of the form 120 - * __objc_ivar_offset_{class name}.{ivar name} which are pointers to the 121 - * offset values. These should be emitted as weak symbols in every module 122 - * where they are used. The legacy-compatible ABI uses these with a double 123 - * layer of indirection. 124 - */ 125 - int **ivar_offsets; 126 - /** 127 - * List of declared properties on this class (NULL if none). This contains 128 - * the accessor methods for each property. 129 - */ 130 - struct objc_property_list *properties; 131 - 132 - /** 133 - * GC / ARC ABI: Fields below this point only exist if abi_version is >= 1. 134 - */ 135 - 136 - /** 137 - * The location of all strong pointer ivars declared by this class. 138 - * 139 - * If the low bit of this field is 0, then this is a pointer to an 140 - * objc_bitfield structure. If the low bit is 1, then the remaining 63 141 - * bits are set, from low to high, for each ivar in the object that is a 142 - * strong pointer. 143 - */ 144 - intptr_t strong_pointers; 145 - /** 146 - * The location of all zeroing weak pointer ivars declared by this class. 147 - * The format of this field is the same as the format of the 148 - * strong_pointers field. 149 - */ 150 - intptr_t weak_pointers; 151 - }; 152 - 153 - /** 154 - * Structure representing the old ABI class structure. This is only ever 155 - * required so that we can take its size - struct objc_class begins with the 156 - * same fields, and you can test the new abi flag to tell whether it is safe to 157 - * access the subsequent fields. 158 - */ 159 - struct legacy_abi_objc_class 160 - { 161 - struct objc_class *isa; 162 - struct objc_class *super_class; 163 - const char *name; 164 - long version; 165 - unsigned long info; 166 - long instance_size; 167 - struct objc_ivar_list *ivars; 168 - struct objc_method_list *methods; 169 - void *dtable; 170 - struct objc_class *subclass_list; 171 - struct objc_class *sibling_class; 172 - struct objc_protocol_list *protocols; 173 - void *gc_object_type; 174 - }; 175 - 176 - 177 - /** 178 - * An enumerated type describing all of the valid flags that may be used in the 179 - * info field of a class. 180 - */ 181 - enum objc_class_flags 182 - { 183 - /** This class structure represents a class. */ 184 - objc_class_flag_class = (1<<0), 185 - /** This class structure represents a metaclass. */ 186 - objc_class_flag_meta = (1<<1), 187 - /** 188 - * This class has been sent a +initalize message. This message is sent 189 - * exactly once to every class that is sent a message by the runtime, just 190 - * before the first other message is sent. 191 - */ 192 - objc_class_flag_initialized = (1<<2), 193 - /** 194 - * The class has been initialized by the runtime. Its super_class pointer 195 - * should now point to a class, rather than a C string containing the class 196 - * name, and its subclass and sibling class links will have been assigned, 197 - * if applicable. 198 - */ 199 - objc_class_flag_resolved = (1<<3), 200 - /** 201 - * The class uses the new, Objective-C 2, runtime ABI. This ABI defines an 202 - * ABI version field inside the class, and so will be used for all 203 - * subsequent versions that retain some degree of compatibility. 204 - */ 205 - objc_class_flag_new_abi = (1<<4), 206 - /** 207 - * This class was created at run time and may be freed. 208 - */ 209 - objc_class_flag_user_created = (1<<5), 210 - /** 211 - * Instances of this class are provide ARC-safe retain / release / 212 - * autorelease implementations. 213 - */ 214 - objc_class_flag_fast_arc = (1<<6), 215 - /** 216 - * This class is a hidden class (should not be registered in the class 217 - * table nor returned from object_getClass()). 218 - */ 219 - objc_class_flag_hidden_class = (1<<7), 220 - /** 221 - * This class is a hidden class used to store associated values. 222 - */ 223 - objc_class_flag_assoc_class = (1<<8) 224 - }; 225 - 226 - #if 0 227 - 228 - /** 229 - * Sets the specific class flag. Note: This is not atomic. 230 - */ 231 - static inline void objc_set_class_flag(struct objc_class *aClass, 232 - enum objc_class_flags flag) 233 - { 234 - aClass->info |= (unsigned long)flag; 235 - } 236 - /** 237 - * Unsets the specific class flag. Note: This is not atomic. 238 - */ 239 - static inline void objc_clear_class_flag(struct objc_class *aClass, 240 - enum objc_class_flags flag) 241 - { 242 - aClass->info &= ~(unsigned long)flag; 243 - } 244 - /** 245 - * Checks whether a specific class flag is set. 246 - */ 247 - static inline BOOL objc_test_class_flag(struct objc_class *aClass, 248 - enum objc_class_flags flag) 249 - { 250 - return (aClass->info & (unsigned long)flag) == (unsigned long)flag; 251 - } 252 - 253 - /** 254 - * Adds a class to the class table. 255 - */ 256 - void class_table_insert(Class class); 257 - 258 - /** 259 - * Array of classes used for small objects. Small objects are embedded in 260 - * their pointer. In 32-bit mode, we have one small object class (typically 261 - * used for storing 31-bit signed integers. In 64-bit mode then we can have 7, 262 - * because classes are guaranteed to be word aligned. 263 - */ 264 - extern Class SmallObjectClasses[7]; 265 - 266 - static BOOL isSmallObject(id obj) 267 - { 268 - uintptr_t addr = ((uintptr_t)obj); 269 - return (addr & OBJC_SMALL_OBJECT_MASK) != 0; 270 - } 271 - 272 - __attribute__((always_inline)) 273 - static inline Class classForObject(id obj) 274 - { 275 - if (UNLIKELY(isSmallObject(obj))) 276 - { 277 - if (sizeof(Class) == 4) 278 - { 279 - return SmallObjectClasses[0]; 280 - } 281 - else 282 - { 283 - uintptr_t addr = ((uintptr_t)obj); 284 - return SmallObjectClasses[(addr & OBJC_SMALL_OBJECT_MASK)]; 285 - } 286 - } 287 - return obj->isa; 288 - } 289 - 290 - #endif 291 - #endif //__OBJC_CLASS_H_INCLUDED
-105
src/libobjcdarwin/libobjc/properties.h
··· 1 - #include "visibility.h" 2 - 3 - enum PropertyAttributeKind 4 - { 5 - /** 6 - * Property has no attributes. 7 - */ 8 - OBJC_PR_noattr = 0x00, 9 - /** 10 - * The property is declared read-only. 11 - */ 12 - OBJC_PR_readonly = (1<<0), 13 - /** 14 - * The property has a getter. 15 - */ 16 - OBJC_PR_getter = (1<<1), 17 - /** 18 - * The property has assign semantics. 19 - */ 20 - OBJC_PR_assign = (1<<2), 21 - /** 22 - * The property is declared read-write. 23 - */ 24 - OBJC_PR_readwrite = (1<<3), 25 - /** 26 - * Property has retain semantics. 27 - */ 28 - OBJC_PR_retain = (1<<4), 29 - /** 30 - * Property has copy semantics. 31 - */ 32 - OBJC_PR_copy = (1<<5), 33 - /** 34 - * Property is marked as non-atomic. 35 - */ 36 - OBJC_PR_nonatomic = (1<<6), 37 - /** 38 - * Property has setter. 39 - */ 40 - OBJC_PR_setter = (1<<7) 41 - }; 42 - 43 - /** 44 - * Structure used for property enumeration. Note that property enumeration is 45 - * currently quite broken on OS X, so achieving full compatibility there is 46 - * impossible. Instead, we strive to achieve compatibility with the 47 - * documentation. 48 - */ 49 - struct objc_property 50 - { 51 - /** 52 - * Name of this property. 53 - */ 54 - const char *name; 55 - /** 56 - * Attributes for this property. Made by ORing together 57 - * PropertyAttributeKinds. 58 - */ 59 - char attributes; 60 - /** 61 - * Flag set if the property is synthesized. 62 - */ 63 - const char isSynthesized; 64 - /** 65 - * Name of the getter for this property. 66 - */ 67 - const char *getter_name; 68 - /** 69 - * Type encoding for the get method for this property. 70 - */ 71 - const char *getter_types; 72 - /** 73 - * Name of the set method for this property. 74 - */ 75 - const char *setter_name; 76 - /** 77 - * Type encoding of the setter for this property. 78 - */ 79 - const char *setter_types; 80 - }; 81 - 82 - /** 83 - * List of property inrospection data. 84 - */ 85 - struct objc_property_list 86 - { 87 - /** 88 - * Number of properties in this array. 89 - */ 90 - int count; 91 - /* 92 - * The next property in a linked list. 93 - */ 94 - struct objc_property_list *next; 95 - /** 96 - * List of properties. 97 - */ 98 - struct objc_property properties[]; 99 - }; 100 - 101 - /** 102 - * Constructs a property description from a list of attributes. 103 - */ 104 - PRIVATE struct objc_property propertyFromAttrs(const objc_property_attribute_t *attributes, 105 - unsigned int attributeCount);
-24
src/libobjcdarwin/libobjc/visibility.h
··· 1 - #if defined _WIN32 || defined __CYGWIN__ 2 - # define PUBLIC __attribute__((dllexport)) 3 - # define PRIVATE 4 - #else 5 - # define PUBLIC __attribute__ ((visibility("default"))) 6 - # define PRIVATE __attribute__ ((visibility("hidden"))) 7 - #endif 8 - #ifdef NO_LEGACY 9 - # define LEGACY PRIVATE 10 - #else 11 - # define LEGACY PUBLIC 12 - #endif 13 - 14 - #if defined(DEBUG) || (!defined(__clang__)) 15 - # include <assert.h> 16 - # define UNREACHABLE(x) assert(0 && x) 17 - # define ASSERT(x) assert(x) 18 - #else 19 - # define UNREACHABLE(x) __builtin_unreachable() 20 - # define ASSERT(x) do { if (x) __builtin_unreachable(); } while(0) 21 - #endif 22 - 23 - #define LIKELY(x) __builtin_expect(x, 1) 24 - #define UNLIKELY(x) __builtin_expect(x, 0)
-8
src/libobjcdarwin/misc.mm
··· 1 - #import <Foundation/NSException.h> 2 - #include "visibility.h" 3 - 4 - DARLING_VISIBLE extern "C" void objc_enumerationMutation(id obj) 5 - { 6 - [NSException raise: NSGenericException format: @"Collection %@ was mutated while being enumerated", obj]; 7 - } 8 -
-174
src/libobjcdarwin/new/AppleLayout.h
··· 1 - #ifndef NEW_APPLELAYOUT_H 2 - #define NEW_APPLELAYOUT_H 3 - #include "../common/AppleLayout.h" 4 - #include <iterator> 5 - 6 - struct method_t 7 - { 8 - const char* selName; 9 - const char* types; 10 - void* impl; 11 - }; 12 - 13 - struct method_list_t 14 - { 15 - uint32_t entsize_and_flags; 16 - uint32_t count; 17 - method_t method_list[]; 18 - 19 - uint32_t entsize() const { return entsize_and_flags & ~uint32_t(3); } 20 - }; 21 - 22 - struct ivar_t 23 - { 24 - uintptr_t* offset; 25 - const char* name; 26 - const char* type; 27 - uint32_t alignment, size; 28 - }; 29 - 30 - struct ivar_list_t 31 - { 32 - uint32_t entsize, count; 33 - ivar_t ivar_list[]; 34 - }; 35 - 36 - struct protocol_list_t; 37 - struct property_list_t; 38 - struct protocol_t 39 - { 40 - id isa; 41 - const char* name; 42 - protocol_list_t* protocols; // inherited protocols 43 - method_list_t *methods, *staticMethods, *optMethods, *optStaticMethods; 44 - property_list_t* properties; 45 - uint32_t size, flags; 46 - const char** extMethTypes; // reflects the order and count of methods above as listed in this struct 47 - 48 - inline const protocol_t* next() const 49 - { 50 - uintptr_t ptr = reinterpret_cast<uintptr_t>(this); 51 - ptr += size; 52 - return reinterpret_cast<const protocol_t*>(ptr); 53 - } 54 - }; 55 - 56 - template <typename ProtoList> 57 - class protocol_iterator : public std::iterator<std::input_iterator_tag, const protocol_t*> 58 - { 59 - const ProtoList* m_list; 60 - size_t m_index; 61 - intptr_t m_slide; 62 - public: 63 - protocol_iterator(const ProtoList* list, size_t index, intptr_t slide) : m_list(list), m_index(index), m_slide(slide) {} 64 - protocol_iterator(const protocol_iterator& that) : m_list(that.m_list), m_index(that.m_index), m_slide(that.m_slide) {} 65 - protocol_iterator& operator++() { m_index++; return *this; } 66 - bool operator==(const protocol_iterator& that) { return that.m_index == m_index; } 67 - bool operator!=(const protocol_iterator& that) { return that.m_index != m_index; } 68 - const protocol_t* operator*() { return m_list->elem(m_index, m_slide); } 69 - }; 70 - 71 - struct protocol_list_t 72 - { 73 - uintptr_t count; 74 - uintptr_t list[]; // the compiler doesn't add a rebase here 75 - inline const protocol_t* elem(size_t i, uintptr_t slide) const 76 - { 77 - return reinterpret_cast<const protocol_t*>(list[i] + 0); 78 - } 79 - protocol_iterator<protocol_list_t> begin(intptr_t slide) const { return protocol_iterator<protocol_list_t>(this, 0, 0); } 80 - protocol_iterator<protocol_list_t> end(intptr_t slide) const { return protocol_iterator<protocol_list_t>(this, count, 0); } 81 - }; 82 - 83 - struct property_t 84 - { 85 - const char *name, *attributes; 86 - }; 87 - 88 - struct property_list_t 89 - { 90 - uint32_t entsize, count; 91 - property_t list[]; 92 - }; 93 - 94 - struct class_ro_t 95 - { 96 - uint32_t flags, instStart, instSize; 97 - #ifdef __x86_64__ 98 - uint32_t nothing; 99 - #endif 100 - void* ivarLayout; 101 - const char* className; 102 - const method_list_t* baseMethods; // instance methods for classes, static methods for metaclasses 103 - const protocol_list_t* baseProtocols; 104 - const ivar_list_t* ivars; 105 - 106 - void* todo[1]; // TODO: more pointers 107 - const property_list_t* baseProperties; 108 - }; 109 - 110 - struct class_t 111 - { 112 - class_t* isa; // instance of 113 - class_t* superclass; 114 - void* cache; // empty cache imported here 115 - void* vtable; 116 - uintptr_t data_and_flags; 117 - 118 - class_ro_t* data() const 119 - { 120 - uintptr_t p = data_and_flags & ~uintptr_t(3); 121 - return reinterpret_cast<class_ro_t*>(p); 122 - } 123 - }; 124 - 125 - struct category_t 126 - { 127 - const char* name; 128 - id cls; 129 - method_list_t *methods, *staticMethods; 130 - protocol_list_t *protocols; 131 - property_list_t *properties; 132 - }; 133 - 134 - #ifndef CLS_CLASS 135 - #define CLS_CLASS 0x1 136 - #define CLS_META 0x2 137 - #define CLS_POSING 0x8 138 - #define CLS_METHOD_ARRAY 0x100 139 - #define CLS_HAS_CXX_STRUCTORS 0x2000 140 - #define CLS_NO_METHOD_ARRAY 0x4000 141 - #define CLS_HAS_LOAD_METHOD 0x8000 142 - #define CLS_NO_PROPERTY_ARRAY 0x80000 143 - #endif 144 - 145 - static const char* SEG_DATA = "__DATA"; 146 - static const char* SEG_OBJC_CLASSLIST_NEW = SEG_DATA; 147 - static const char* SECT_OBJC_CLASSLIST_NEW = "__objc_classlist"; 148 - static const char* SEG_OBJC_CLASSREFS_NEW = SEG_DATA; 149 - static const char* SECT_OBJC_CLASSREFS_NEW = "__objc_classrefs"; 150 - static const char* SEG_OBJC_SUPERREFS_NEW = SEG_DATA; 151 - static const char* SECT_OBJC_SUPERREFS_NEW = "__objc_superrefs"; 152 - static const char* SEG_OBJC_SELREFS_NEW = SEG_DATA; 153 - static const char* SECT_OBJC_SELREFS_NEW = "__objc_selrefs"; 154 - static const char* SEG_OBJC_MSGREFS_NEW = SEG_DATA; // used with objc_msgSend_fixup 155 - static const char* SECT_OBJC_MSGREFS_NEW = "__objc_msgrefs"; 156 - static const char* SEG_OBJC_PROTOREFS_NEW = SEG_DATA; 157 - static const char* SECT_OBJC_PROTOREFS_NEW = "__objc_protorefs"; 158 - static const char* SEG_OBJC_PROTOLIST_NEW = SEG_DATA; 159 - static const char* SECT_OBJC_PROTOLIST_NEW = "__objc_protolist"; 160 - static const char* SEG_OBJC_CATLIST_NEW = SEG_DATA; 161 - static const char* SECT_OBJC_CATLIST_NEW = "__objc_catlist"; 162 - 163 - /* TODO? 164 - * __DATA,__objc_classlist was __OBJC2,__class_list 165 - * __DATA,__objc_catlist was __OBJC2,__category_list 166 - * __DATA,__objc_protolist was __OBJC2,__protocol_list 167 - * __DATA,__objc_msgrefs was __OBJC2,__message_refs 168 - * __DATA,__objc_classrefs was __OBJC2,__class_refs 169 - * __DATA,__objc_superrefs was __OBJC2,__super_refs 170 - * __DATA,__objc_imageinfo was __OBJC,__image_info 171 - * */ 172 - 173 - #endif 174 -
-51
src/libobjcdarwin/new/category.cpp
··· 1 - #include "./category.h" 2 - #include "../common/property.h" 3 - #include "../common/method.h" 4 - #include "./protocol.h" 5 - #include "../../util/log.h" 6 - #include <map> 7 - 8 - extern std::map<const void*,Class> g_classPointers; 9 - 10 - void ProcessCategoriesNew(const struct mach_header* mh, intptr_t slide) 11 - { 12 - category_t** cats; 13 - unsigned long size; 14 - 15 - cats = reinterpret_cast<category_t**>( 16 - getsectdata(mh, SEG_OBJC_CATLIST_NEW, SECT_OBJC_CATLIST_NEW, &size) 17 - ); 18 - if (!cats) 19 - { 20 - LOG << "No categories found\n"; 21 - return; 22 - } 23 - 24 - LOG << "Processing categories, " << (size / sizeof(category_t*)) << " found\n"; 25 - 26 - for (size_t i = 0; i < size / sizeof(category_t*); i++) 27 - { 28 - // g_classPointers 29 - category_t* cat = cats[i]; 30 - auto itClass = g_classPointers.find(cat->cls); 31 - Class c; 32 - 33 - if (itClass != g_classPointers.end()) 34 - c = itClass->second; 35 - else 36 - c = reinterpret_cast<Class>(cat->cls); 37 - 38 - LOG << "Processing category " << cat->name << " on top of class @" << c << std::endl; 39 - 40 - if (cat->methods) 41 - ConvertMethodListGen(c, cat->methods); 42 - if (cat->staticMethods) 43 - ConvertMethodListGen(object_getClass(id(c)), cat->staticMethods); 44 - if (cat->protocols) 45 - AddClassProtocols(c, cat->protocols, slide); 46 - if (cat->properties) 47 - { 48 - ConvertProperties(cat->properties, [c](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(c, name, attr, count); bug_gnustepFixPropertyCount(c); }); 49 - } 50 - } 51 - }
-10
src/libobjcdarwin/new/category.h
··· 1 - #ifndef NEW_CATEGORY_H 2 - #define NEW_CATEGORY_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - #include <libdyld/dyld_public.h> 7 - 8 - void ProcessCategoriesNew(const struct mach_header* mh, intptr_t slide); 9 - 10 - #endif
-104
src/libobjcdarwin/new/class.cpp
··· 1 - #include "./class.h" 2 - #include "../../util/trace.h" 3 - #include "../../util/log.h" 4 - #include <map> 5 - #include <algorithm> 6 - #include "../common/method.h" 7 - #include "../common/property.h" 8 - #include "../common/ref.h" 9 - #include "./ivar.h" 10 - #include "./protocol.h" 11 - #include "../TopologySort.h" 12 - 13 - extern std::map<const void*,Class> g_classPointers; 14 - 15 - Class RegisterClass(const class_t* cls, intptr_t slide) 16 - { 17 - LOG << "Processing ObjC class " << cls->data()->className << std::endl; 18 - 19 - const class_t* meta = cls->isa; 20 - Class conv, super; 21 - auto itSuper = g_classPointers.find(cls->superclass); 22 - 23 - if (itSuper != g_classPointers.end()) 24 - super = itSuper->second; 25 - else 26 - super = reinterpret_cast<Class>(cls->superclass); 27 - 28 - LOG << "...superclass is @" << super << std::endl; 29 - assert(objc_getClass(cls->data()->className) == nullptr); 30 - conv = objc_allocateClassPair(super, cls->data()->className, 0); 31 - 32 - const class_ro_t* ro = cls->data(); 33 - const class_ro_t* roMeta = meta->data(); 34 - 35 - if (ro->baseMethods) 36 - ConvertMethodListGen(conv, ro->baseMethods); 37 - if (roMeta->baseMethods) 38 - ConvertMethodListGen(object_getClass(id(conv)), roMeta->baseMethods); 39 - if (ro->ivars) 40 - ConvertIvarList(conv, ro->ivars); 41 - if (ro->baseProtocols) 42 - AddClassProtocols(conv, ro->baseProtocols, slide); 43 - if (ro->baseProperties) 44 - { 45 - ConvertProperties(ro->baseProperties, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(conv, name, attr, count); bug_gnustepFixPropertyCount(conv); }); 46 - } 47 - 48 - // conv->instance_size = ro->instSize; 49 - // conv->isa->instance_size = roMeta->instSize; 50 - 51 - objc_registerClassPair(conv); 52 - 53 - LOG << "ObjC class " << cls->data()->className << " now @" << conv << std::endl; 54 - g_classPointers[cls] = conv; 55 - g_classPointers[cls->isa] = object_getClass(id(conv)); 56 - 57 - return conv; 58 - } 59 - 60 - std::vector<const char*> ProcessClassesNew(const struct mach_header* mh, intptr_t slide, const class_t** classes, unsigned long size) 61 - { 62 - std::vector<const class_t*> vecClasses; 63 - std::set<const class_t*> setClasses; 64 - std::vector<const char*> classNames; 65 - 66 - std::copy(classes, classes+size/sizeof(class_t*), std::inserter(setClasses, setClasses.begin())); 67 - 68 - topology_sort<const class_t>(setClasses, vecClasses, 69 - [&setClasses](const class_t* t) { return setClasses.count(t->superclass) ? std::set<const class_t*>{t->superclass} : std::set<const class_t*>(); } 70 - ); 71 - 72 - for (const class_t* cls : vecClasses) 73 - { 74 - RegisterClass(cls, slide); 75 - classNames.push_back(cls->data()->className); 76 - } 77 - 78 - return classNames; 79 - } 80 - 81 - void UpdateClassRefs(const struct mach_header* mh) 82 - { 83 - unsigned long refsize, refsize_s; 84 - class_t **class_refs, **class_refs_end, **super_refs, **super_refs_end; 85 - 86 - class_refs = reinterpret_cast<class_t**>( 87 - getsectdata(mh, SEG_OBJC_CLASSREFS_NEW, SECT_OBJC_CLASSREFS_NEW, &refsize) 88 - ); 89 - super_refs = reinterpret_cast<class_t**>( 90 - getsectdata(mh, SEG_OBJC_SUPERREFS_NEW, SECT_OBJC_SUPERREFS_NEW, &refsize_s) 91 - ); 92 - if (class_refs) 93 - class_refs_end = class_refs + refsize / sizeof(class_t*); 94 - 95 - if (super_refs) 96 - super_refs_end = super_refs + refsize_s / sizeof(class_t*); 97 - 98 - if (class_refs) 99 - find_and_fix((void**) class_refs, (void**) class_refs_end, g_classPointers); 100 - 101 - if (super_refs) 102 - find_and_fix((void**) super_refs, (void**) super_refs_end, g_classPointers); 103 - } 104 -
-13
src/libobjcdarwin/new/class.h
··· 1 - #ifndef NEW_CLASS_H 2 - #define NEW_CLASS_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - #include <vector> 7 - #include <libdyld/dyld_public.h> 8 - 9 - Class RegisterClass(const class_t* cls, intptr_t slide); 10 - std::vector<const char*> ProcessClassesNew(const struct mach_header* mh, intptr_t slide, const class_t** classes, unsigned long size); 11 - void UpdateClassRefs(const struct mach_header* mh); 12 - 13 - #endif
-38
src/libobjcdarwin/new/exceptions.cpp
··· 1 - #include "exceptions.h" 2 - #include "return.h" 3 - 4 - extern "C" void __cxa_rethrow(); 5 - extern "C" void* __cxa_begin_catch(void*); 6 - extern "C" void __cxa_end_catch(); 7 - 8 - #define thread_local __thread 9 - 10 - static thread_local bool m_cxx = false; 11 - 12 - void __darwin_objc_exception_rethrow() 13 - { 14 - __cxa_rethrow(); 15 - } 16 - 17 - void* __darwin_objc_begin_catch(void* p) 18 - { 19 - void *rv = returnReturn(); 20 - void* cpp = __cxa_begin_catch(p); 21 - if (cpp) 22 - { 23 - m_cxx = true; 24 - return cpp; 25 - } 26 - else 27 - { 28 - m_cxx = false; 29 - return rv; 30 - } 31 - } 32 - 33 - void __darwin_objc_end_catch() 34 - { 35 - if (m_cxx) 36 - __cxa_end_catch(); 37 - } 38 -
-14
src/libobjcdarwin/new/exceptions.h
··· 1 - #ifndef OBJC_EXCEPTIONS_H 2 - #define OBJC_EXCEPTIONS_H 3 - #include "../visibility.h" 4 - 5 - extern "C" { 6 - 7 - DARLING_VISIBLE void __darwin_objc_exception_rethrow(); 8 - DARLING_VISIBLE void* __darwin_objc_begin_catch(void*); 9 - DARLING_VISIBLE void __darwin_objc_end_catch(); 10 - 11 - } 12 - 13 - #endif 14 -
-28
src/libobjcdarwin/new/ivar.cpp
··· 1 - #include "./ivar.h" 2 - #include "../../util/log.h" 3 - 4 - void ConvertIvarList(Class c, const ivar_list_t* list) 5 - { 6 - LOG << list->count << " ivars within\n"; 7 - 8 - for (size_t i = 0; i < list->count; i++) 9 - { 10 - auto* v = &list->ivar_list[i]; 11 - int align = __builtin_ffs(v->alignment) - 1; 12 - 13 - LOG << "Ivar: name: " << v->name << "; type: " << v->type << "; offset: " << *v->offset << "; size: " << v->size << "; alignment: " << v->alignment << std::endl; 14 - class_addIvar(c, v->name, v->size, v->alignment, v->type); 15 - 16 - Ivar ivar = class_getInstanceVariable(c, v->name); 17 - 18 - if (ivar) 19 - { 20 - *v->offset = ivar_getOffset(ivar); 21 - LOG << "Ivar registered, ivar_getOffset() = " << ivar_getOffset(ivar) << " in " << class_getInstanceSize(c) << std::endl; 22 - } 23 - 24 - assert(ivar != nullptr); 25 - // assert(ivar_getOffset(ivar) == *v->offset); 26 - } 27 - } 28 -
-9
src/libobjcdarwin/new/ivar.h
··· 1 - #ifndef NEW_IVAR_H 2 - #define NEW_IVAR_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - 7 - void ConvertIvarList(Class c, const ivar_list_t* list); 8 - 9 - #endif
-107
src/libobjcdarwin/new/protocol.cpp
··· 1 - #include "./protocol.h" 2 - #include <cstring> 3 - #include <util/debug.h> 4 - #include <libdyld/dyld_public.h> 5 - #include "../common/ref.h" 6 - #include "../common/property.h" 7 - #include "../TopologySort.h" 8 - 9 - void AddClassProtocols(Class c, const protocol_list_t* list, intptr_t slide) 10 - { 11 - for (size_t i = 0; i < list->count; i++) 12 - { 13 - const char* name = list->elem(i, slide)->name; 14 - Protocol* p = objc_getProtocol(name); 15 - assert(p != nullptr); 16 - class_addProtocol(c, p); 17 - } 18 - } 19 - 20 - void RegisterProtocolMethods(Protocol* p, const method_list_t* list, const char** extTypes, size_t& extIndex, bool required, bool instance) 21 - { 22 - LOG << "Registering Protocol methods (" << required << ", " << instance << "): " << list->count << " methods within\n"; 23 - for (size_t i = 0; i < list->count; i++, extIndex++) 24 - { 25 - SEL sel = sel_registerName(list->method_list[i].selName); 26 - protocol_addMethodDescription(p, sel, list->method_list[i].types, required, instance); 27 - // TODO: what do we do with extTypes? 28 - } 29 - } 30 - 31 - Protocol* RegisterProtocol(const protocol_t* prot, intptr_t slide) 32 - { 33 - Protocol *existingProtocol = objc_getProtocol(prot->name); 34 - 35 - // Return existing protocols 36 - if (existingProtocol) 37 - { 38 - LOG << "Found existing ObjC Protocol: " << prot->name << std::endl; 39 - return existingProtocol; 40 - } 41 - 42 - LOG << "Processing ObjC Protocol: " << prot->name << std::endl; 43 - Protocol* conv = objc_allocateProtocol(prot->name); 44 - size_t methodIndex = 0; 45 - 46 - if (prot->protocols) 47 - { 48 - for (size_t i = 0; i < prot->protocols->count; i++) 49 - { 50 - const char* name = prot->protocols->elem(i, slide)->name; 51 - protocol_addProtocol(conv, objc_getProtocol(name)); 52 - } 53 - } 54 - 55 - if (prot->methods) 56 - RegisterProtocolMethods(conv, prot->methods, prot->extMethTypes, methodIndex, true, true); 57 - if (prot->staticMethods) 58 - RegisterProtocolMethods(conv, prot->staticMethods, prot->extMethTypes, methodIndex, true, false); 59 - if (prot->optMethods) 60 - RegisterProtocolMethods(conv, prot->optMethods, prot->extMethTypes, methodIndex, false, true); 61 - if (prot->optStaticMethods) 62 - RegisterProtocolMethods(conv, prot->optStaticMethods, prot->extMethTypes, methodIndex, false, false); 63 - 64 - if (prot->properties) 65 - ConvertProperties(prot->properties, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { protocol_addProperty(conv, name, attr, count, true, true); }); 66 - 67 - objc_registerProtocol(conv); 68 - return conv; 69 - } 70 - 71 - void ProcessProtocolsNew(const struct mach_header* mh, intptr_t slide) 72 - { 73 - const protocol_t** protocol_list; 74 - unsigned long protosize; 75 - 76 - protocol_list = reinterpret_cast<const protocol_t**>( 77 - getsectdata(mh, SEG_OBJC_PROTOLIST_NEW, SECT_OBJC_PROTOLIST_NEW, &protosize) 78 - ); 79 - 80 - if (protocol_list) 81 - { 82 - unsigned long refsize; 83 - protocol_t** protocol_refs; 84 - protocol_t** protocol_refs_end; 85 - std::set<const protocol_t*> setProtocols; 86 - std::vector<const protocol_t*> vecProtocols; 87 - 88 - protocol_refs = reinterpret_cast<protocol_t**>( 89 - getsectdata(mh, SEG_OBJC_PROTOREFS_NEW, SECT_OBJC_PROTOREFS_NEW, &refsize) 90 - ); 91 - 92 - if (protocol_refs) 93 - protocol_refs_end = protocol_refs + refsize / sizeof(protocol_t*); 94 - 95 - std::copy(protocol_list, protocol_list+protosize/sizeof(protocol_t*), std::inserter(setProtocols, setProtocols.begin())); 96 - topology_sort<const protocol_t>(setProtocols, vecProtocols, 97 - [&setProtocols,slide](const protocol_t* p) { return p->protocols ? std::set<const protocol_t*>(p->protocols->begin(slide), p->protocols->end(slide)) : std::set<const protocol_t*>(); }); 98 - 99 - for (const protocol_t* proto : vecProtocols) 100 - { 101 - Protocol* p = RegisterProtocol(proto, slide); 102 - 103 - if (protocol_refs) 104 - find_and_fix(protocol_refs, protocol_refs_end, proto, p); 105 - } 106 - } 107 - }
-12
src/libobjcdarwin/new/protocol.h
··· 1 - #ifndef NEW_PROTOCOL_H 2 - #define NEW_PROTOCOL_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - 7 - Protocol* RegisterProtocol(const protocol_t* prot, intptr_t slide); 8 - void ProcessProtocolsNew(const struct mach_header* mh, intptr_t slide); 9 - void RegisterProtocolMethods(Protocol* p, const method_list_t* list, const char** extTypes, size_t& extIndex, bool required, bool instance); 10 - void AddClassProtocols(Class c, const protocol_list_t* list, intptr_t slide); 11 - 12 - #endif
-9
src/libobjcdarwin/new/return.h
··· 1 - #ifndef OBJC_RETURN_H 2 - #define OBJC_RETURN_H 3 - 4 - // Does nothing, but given it's signature, it will actually return 5 - // the last return value (contents of eax/rax on x86) 6 - extern "C" void* returnReturn(); 7 - 8 - #endif 9 -
-8
src/libobjcdarwin/new/return.nasm
··· 1 - section .note.GNU-stack noalloc noexec nowrite progbits 2 - section text 3 - 4 - global returnReturn 5 - 6 - returnReturn: 7 - ret 8 -
-37
src/libobjcdarwin/objc_msgSend.nasm
··· 1 - global __darwin_objc_msgSend_noarg 2 - 3 - extern objc_msgSend 4 - 5 - section .note.GNU-stack noalloc noexec nowrite progbits 6 - 7 - %ifidn __OUTPUT_FORMAT__, elf64 8 - 9 - BITS 64 10 - section text 11 - 12 - __darwin_objc_msgSend_noarg: 13 - jmp objc_msgSend WRT ..plt 14 - 15 - %elifidn __OUTPUT_FORMAT__, elf 16 - 17 - BITS 32 18 - section text 19 - 20 - extern _GLOBAL_OFFSET_TABLE_ 21 - 22 - __darwin_objc_msgSend_noarg: 23 - push ebx 24 - call .get_GOT 25 - .get_GOT: 26 - pop ebx 27 - add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 28 - lea eax, [ebx + objc_msgSend WRT ..got] 29 - pop ebx 30 - 31 - jmp eax 32 - 33 - %else 34 - 35 - %error "Unsupported platform" 36 - 37 - %endif
-189
src/libobjcdarwin/objc_msgSendSuper.nasm
··· 1 - global __darwin_objc_msgSendSuper 2 - global __darwin_objc_msgSendSuper2 ; requires extracting superclass from Class 3 - global __darwin_objc_msgSendSuper2_stret 4 - extern objc_msg_lookup_super 5 - 6 - section .note.GNU-stack noalloc noexec nowrite progbits 7 - 8 - %ifidn __OUTPUT_FORMAT__, elf64 9 - 10 - BITS 64 11 - section text 12 - 13 - %macro SaveRegisters 0 14 - push rdi 15 - push rsi 16 - push rdx 17 - push rcx 18 - push r8 19 - push r9 20 - %endmacro 21 - 22 - %macro RestoreRegisters 0 23 - pop r9 24 - pop r8 25 - pop rcx 26 - pop rdx 27 - pop rsi 28 - pop rdi 29 - %endmacro 30 - 31 - __darwin_objc_msgSendSuper2: 32 - SaveRegisters 33 - 34 - ; Make a copy of the struct on stack 35 - mov rax, [rdi] 36 - mov [rsp-16], rax 37 - mov rax, [rdi+8] 38 - mov rax, [rax+8] ; load superclass 39 - mov [rsp-8], rax 40 - 41 - sub rsp, 16 42 - mov rdi, rsp 43 - 44 - call objc_msg_lookup_super WRT ..plt 45 - 46 - add rsp, 16 47 - 48 - RestoreRegisters 49 - 50 - mov rdi, [rdi] 51 - jmp rax 52 - 53 - __darwin_objc_msgSendSuper: 54 - SaveRegisters 55 - 56 - call objc_msg_lookup_super WRT ..plt 57 - 58 - RestoreRegisters 59 - 60 - mov rdi, [rdi] 61 - jmp rax 62 - 63 - __darwin_objc_msgSendSuper2_stret: 64 - SaveRegisters 65 - 66 - ; Make a copy of the struct on stack 67 - mov rax, [rsi] 68 - mov [rsp-16], rax 69 - mov rax, [rsi+8] 70 - mov rax, [rax+8] ; load superclass 71 - mov [rsp-8], rax 72 - 73 - sub rsp, 16 74 - mov rdi, rsp 75 - mov rsi, rdx 76 - 77 - call objc_msg_lookup_super WRT ..plt 78 - 79 - add rsp, 16 80 - 81 - RestoreRegisters 82 - 83 - mov rsi, [rsi] 84 - jmp rax 85 - __darwin_objc_msgSendSuper_stret: 86 - SaveRegisters 87 - 88 - mov rdi, rsi 89 - mov rsi, rdx 90 - 91 - call objc_msg_lookup_super WRT ..plt 92 - 93 - RestoreRegisters 94 - 95 - mov rsi, [rsi] 96 - jmp rax 97 - 98 - %elifidn __OUTPUT_FORMAT__, elf 99 - 100 - BITS 32 101 - section text 102 - 103 - extern _GLOBAL_OFFSET_TABLE_ 104 - 105 - %macro DereferenceArgument 1 106 - mov ecx, [ebp+(%1*4)+8] ; get objc_super* 107 - mov ecx, [ecx] ; get the first member's value 108 - mov [ebp+(%1*4)+8], ecx ; fix the first argument 109 - %endmacro 110 - 111 - ; NOT USED 112 - __darwin_objc_msgSendSuper2: 113 - mov eax, [esp+4] ; get objc_super* 114 - ; make a copy on the stack 115 - mov ecx, [eax] ; 1st elem 116 - mov [esp-8], ecx 117 - mov ecx, [eax+4] ; 2nd elem 118 - mov ecx, [ecx+4] ; get superclass from objc_class 119 - mov [esp-4], ecx 120 - 121 - sub esp, 8 122 - mov eax, [esp+16]; SEL (2nd argument) 123 - push eax 124 - lea eax, [esp+4]; fixed objc_super (1st argument) 125 - push eax 126 - 127 - call objc_msg_lookup_super WRT ..plt 128 - 129 - add esp, 16 ; remove args & struct from the stack 130 - 131 - DereferenceArgument 0 132 - 133 - jmp eax 134 - 135 - __darwin_objc_msgSendSuper: 136 - 137 - push ebp 138 - mov ebp, esp 139 - push ebx 140 - call .get_GOT 141 - .get_GOT: 142 - pop ebx 143 - add ebx, _GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 144 - 145 - mov eax, [ebp+12] 146 - push eax 147 - mov eax, [ebp+8] 148 - push eax 149 - call objc_msg_lookup_super WRT ..plt 150 - add esp, 8 151 - 152 - DereferenceArgument 0 153 - 154 - mov ebx, [ebp-4] 155 - mov esp, ebp 156 - pop ebp 157 - 158 - jmp eax 159 - 160 - __darwin_objc_msgSendSuper2_stret: 161 - push ebp 162 - mov ebp, esp 163 - push ebx 164 - call .get_GOT 165 - .get_GOT: 166 - pop ebx 167 - add ebx, _GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 168 - 169 - mov eax, [ebp+16] 170 - push eax 171 - mov eax, [ebp+12] 172 - push eax 173 - 174 - call objc_msg_lookup_super WRT ..plt 175 - sub esp, 8 176 - 177 - DereferenceArgument 1 178 - 179 - mov ebx, [ebp-4] 180 - mov esp, ebp 181 - pop ebp 182 - 183 - jmp eax 184 - 185 - %else 186 - 187 - %error "Unsupported platform" 188 - 189 - %endif
-58
src/libobjcdarwin/objc_msgSend_fixup.nasm
··· 1 - global __darwin_objc_msgSend_fixup 2 - global objc_msgSendSuper2_fixup 3 - global objc_msgSendSuper2_stret_fixup 4 - global __darwin_objc_msgSend_fpret_fixup 5 - global __darwin_objc_msgSend_fp2ret_fixup 6 - global objc_msgSend_stret_fixup 7 - extern objc_msgSend 8 - extern objc_msgSend_fpret 9 - extern __darwin_objc_msgSendSuper2 10 - extern __darwin_objc_msgSendSuper2_stret 11 - extern objc_msgSend_stret 12 - 13 - section .note.GNU-stack noalloc noexec nowrite progbits 14 - 15 - %ifidn __OUTPUT_FORMAT__, elf64 16 - 17 - BITS 64 18 - section text 19 - 20 - __darwin_objc_msgSend_fp2ret_fixup: 21 - __darwin_objc_msgSend_fpret_fixup: 22 - mov rsi, [rsi+8] 23 - jmp objc_msgSend_fpret WRT ..plt 24 - 25 - __darwin_objc_msgSend_fixup: 26 - mov rsi, [rsi+8] 27 - jmp objc_msgSend WRT ..plt 28 - 29 - objc_msgSendSuper2_fixup: 30 - mov rsi, [rsi+8] 31 - jmp __darwin_objc_msgSendSuper2 WRT ..plt 32 - 33 - objc_msgSend_stret_fixup: 34 - mov rdx, [rdx+8] 35 - jmp objc_msgSend_stret WRT ..plt 36 - 37 - objc_msgSendSuper2_stret_fixup: 38 - mov rdx, [rdx+8] 39 - jmp __darwin_objc_msgSendSuper2_stret WRT ..plt 40 - 41 - %elifidn __OUTPUT_FORMAT__, elf 42 - 43 - BITS 32 44 - section text 45 - 46 - ; Is it even used with the old runtime? 47 - ;__darwin_objc_msgSend_fixup: 48 - ; mov eax, [esp+8] 49 - ; add eax, 4 50 - ; mov eax, [eax] 51 - ; mov [esp+8], eax 52 - ; jmp objc_msgSend WRT ..plt 53 - 54 - %else 55 - 56 - %error "Unsupported platform" 57 - 58 - %endif
-194
src/libobjcdarwin/old/AppleLayout.h
··· 1 - #ifndef APPLELAYOUT_H 2 - #define APPLELAYOUT_H 3 - #include "../common/AppleLayout.h" 4 - 5 - struct old_method_decl 6 - { 7 - const char *name, *types; 8 - }; 9 - struct old_method_decl_list 10 - { 11 - int count; 12 - old_method_decl list[]; 13 - }; 14 - struct old_property 15 - { 16 - const char *name, *attributes; 17 - }; 18 - 19 - struct old_property_list 20 - { 21 - uint32_t entsize, count; 22 - old_property list[]; 23 - }; 24 - 25 - struct old_protocol; 26 - struct old_protocol_list 27 - { 28 - old_protocol_list* linked; 29 - long count; 30 - old_protocol* list[]; 31 - }; 32 - 33 - struct old_protocol_ext 34 - { 35 - uint32_t size; 36 - old_method_decl_list *optMethods, *optStaticMethods; 37 - old_property_list* properties; 38 - const char** extMethTypes; 39 - }; 40 - 41 - struct old_protocol 42 - { 43 - union 44 - { 45 - id isa; 46 - old_protocol_ext* ext; // __protocol_ext section 47 - uintptr_t ext_ptrValue; 48 - }; 49 - const char* name; 50 - old_protocol_list* protocols; 51 - old_method_decl_list *methods, *staticMethods; 52 - }; 53 - 54 - union old_class_ptr 55 - { 56 - struct old_class* cls; 57 - const char* name; 58 - uintptr_t ptrValue; 59 - Class clsNew; 60 - }; 61 - 62 - struct old_class 63 - { 64 - old_class_ptr isa; 65 - old_class_ptr super_class; 66 - const char *name; 67 - long version; 68 - long info; 69 - long instance_size; 70 - struct old_ivar_list *ivars; 71 - struct old_method_list *methodList; 72 - void* cache; 73 - struct old_protocol_list *protocols; 74 - // CLS_EXT only 75 - const uint8_t *ivar_layout; 76 - struct old_class_ext *ext; 77 - }; 78 - 79 - struct old_class_ext 80 - { 81 - uint32_t size; 82 - const uint8_t *weak_ivar_layout; 83 - union 84 - { 85 - old_property_list **propertyLists; 86 - old_property_list *propertyList; 87 - }; 88 - }; 89 - 90 - struct old_ivar 91 - { 92 - char *name; 93 - char *type; 94 - int offset; 95 - #ifdef __x86_64__ 96 - int space; 97 - #endif 98 - }; 99 - 100 - struct old_ivar_list 101 - { 102 - int count; 103 - #ifdef __x86_64__ 104 - int space; 105 - #endif 106 - /* variable length structure */ 107 - struct old_ivar ivar_list[1]; 108 - }; 109 - 110 - 111 - struct old_method 112 - { 113 - const char* selName; 114 - const char* types; 115 - void* impl; 116 - }; 117 - 118 - struct old_method_list 119 - { 120 - struct old_method_list *obsolete; 121 - 122 - int count; 123 - #ifdef __x86_64__ 124 - int space; 125 - #endif 126 - /* variable length structure */ 127 - struct old_method method_list[1]; 128 - }; 129 - 130 - union clsref 131 - { 132 - const char* clsName; 133 - Class cls; 134 - }; 135 - 136 - struct symtab 137 - { 138 - unsigned long selCount; 139 - SEL* selectors; 140 - uint16_t countClasses, countCategories; 141 - void* classesAndCategories[]; 142 - }; 143 - 144 - struct module_info 145 - { 146 - unsigned long version, size; 147 - const char* name; 148 - struct symtab* symtab; 149 - }; 150 - 151 - struct old_category 152 - { 153 - const char* name; 154 - const char* clsName; 155 - old_method_list *methods, *staticMethods; 156 - old_protocol_list* protocols; // since version 5 157 - uint32_t size; 158 - old_property_list* properties; // since version 7 159 - }; 160 - 161 - // static const size_t sizeof_old_category_4 = offsetof(old_category, protocols); 162 - // static const size_t sizeof_old_category_5 = offsetof(old_category, size); 163 - 164 - static const char* SEG_OBJC = "__OBJC"; 165 - static const char* SEG_OBJC_CLASSLIST_OLD = SEG_OBJC; 166 - static const char* SECT_OBJC_CLASSLIST_OLD = "__class"; 167 - static const char* SEG_OBJC_METALIST_OLD = SEG_OBJC; 168 - static const char* SECT_OBJC_METALIST_OLD = "__meta_class"; 169 - static const char* SEG_OBJC_CLASSREFS_OLD = SEG_OBJC; 170 - static const char* SECT_OBJC_CLASSREFS_OLD = "__cls_refs"; 171 - static const char* SEG_OBJC_SELREFS_OLD = SEG_OBJC; 172 - static const char* SECT_OBJC_SELREFS_OLD = "__message_refs"; 173 - static const char* SEG_OBJC_PROTOCOLS_OLD = SEG_OBJC; 174 - static const char* SECT_OBJC_PROTOCOLS_OLD = "__protocol"; 175 - static const char* SEG_OBJC_PROTOEXT_OLD = SEG_OBJC; 176 - static const char* SECT_OBJC_PROTOEXT_OLD = "__protocol_ext"; 177 - static const char* SEG_OBJC_MODINFO_OLD = SEG_OBJC; 178 - static const char* SECT_OBJC_MODINFO_OLD = "__module_info"; 179 - static const char* SEG_OBJC_CATEGORIES_OLD = SEG_OBJC; 180 - static const char* SECT_OBJC_CATEGORIES_OLD = "__category"; 181 - 182 - #ifndef CLS_CLASS 183 - #define CLS_CLASS 0x1 184 - #define CLS_META 0x2 185 - #define CLS_POSING 0x8 186 - #define CLS_METHOD_ARRAY 0x100 187 - #define CLS_HAS_CXX_STRUCTORS 0x2000 188 - #define CLS_NO_METHOD_ARRAY 0x4000 189 - #define CLS_HAS_LOAD_METHOD 0x8000 190 - #define CLS_NO_PROPERTY_ARRAY 0x80000 191 - #endif 192 - 193 - #endif 194 -
-41
src/libobjcdarwin/old/category.cpp
··· 1 - #include "./category.h" 2 - #include "../../util/log.h" 3 - #include "./class.h" 4 - #include "../common/property.h" 5 - #include "../common/method.h" 6 - 7 - void ProcessCategoriesOld(const struct mach_header* mh, intptr_t slide, module_info* modinfo) 8 - { 9 - struct symtab* symtab = modinfo->symtab; 10 - const size_t firstCat = symtab->countClasses; 11 - 12 - if (!symtab->countCategories) 13 - { 14 - LOG << "No categories found\n"; 15 - return; 16 - } 17 - 18 - for (size_t i = 0; i < symtab->countCategories; i++) 19 - { 20 - old_category* cat = reinterpret_cast<old_category*>(symtab->classesAndCategories[i+firstCat]); 21 - Class cls = (Class) objc_getClass(cat->clsName); 22 - 23 - LOG << "Processing category " << cat->name << " @" << cat << " on top of " << cat->clsName << " @" << cls << std::endl; 24 - 25 - assert(cls != nullptr); 26 - 27 - if (cat->methods) 28 - ConvertMethodListGen(cls, cat->methods); 29 - if (cat->staticMethods) 30 - ConvertMethodListGen(object_getClass(id(cls)), cat->staticMethods); 31 - 32 - if (modinfo->version >= 5 && cat->protocols) 33 - AddClassProtocols(cls, cat->protocols); 34 - 35 - if (modinfo->version >= 7 && cat->properties) 36 - { 37 - ConvertProperties(cat->properties, [cls](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(cls, name, attr, count); bug_gnustepFixPropertyCount(cls); }); 38 - } 39 - } 40 - } 41 -
-12
src/libobjcdarwin/old/category.h
··· 1 - #ifndef OLD_CATEGORY_H 2 - #define OLD_CATEGORY_H 3 - 4 - #include "./AppleLayout.h" 5 - #include <objc/runtime.h> 6 - #include <stdint.h> 7 - #include <libdyld/dyld_public.h> 8 - 9 - void ProcessCategoriesOld(const struct mach_header* mh, intptr_t slide, module_info* modinfo); 10 - 11 - #endif 12 -
-153
src/libobjcdarwin/old/class.cpp
··· 1 - #include "./class.h" 2 - #include "../../util/log.h" 3 - #include "../TopologySort.h" 4 - #include "../common/method.h" 5 - #include "ivar.h" 6 - #include "../common/property.h" 7 - #include <map> 8 - #include <algorithm> 9 - 10 - extern std::map<const void*,Class> g_classPointers; 11 - 12 - Class RegisterClass(old_class* cls, bool hasExt) 13 - { 14 - LOG << "Processing old ObjC class " << cls->name << std::endl; 15 - 16 - const old_class* meta = cls->isa.cls; 17 - Class conv, super; 18 - /* 19 - old_class* psuper = cls->super_class.cls; 20 - auto itSuper = g_classPointers.find(psuper); // TODO: may not be needed, should always be a string 21 - 22 - if (itSuper != g_classPointers.end()) 23 - super = itSuper->second; 24 - else 25 - super = reinterpret_cast<Class>(psuper); 26 - */ 27 - 28 - super = (Class) objc_getClass(cls->super_class.name); 29 - LOG << "...with superclass @" << super << std::endl; 30 - conv = objc_allocateClassPair(super, cls->name, 0); 31 - 32 - if (cls->methodList) 33 - ConvertMethodListGen(conv, cls->methodList); 34 - if (meta->methodList) 35 - ConvertMethodListGen(object_getClass(id(conv)), meta->methodList); 36 - if (cls->ivars) 37 - ConvertIvarList(conv, cls->ivars); 38 - if (cls->protocols) 39 - AddClassProtocols(conv, cls->protocols); 40 - 41 - if (hasExt && cls->ext && cls->ext->propertyLists) 42 - { 43 - LOG << "Class has EXT and a property list/lists\n"; 44 - //if (cls->info & CLS_NO_PROPERTY_ARRAY) 45 - if (true) 46 - { 47 - ConvertProperties(cls->ext->propertyList, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(conv, name, attr, count); bug_gnustepFixPropertyCount(conv); }); 48 - } 49 - else 50 - { 51 - for (size_t i = 0; cls->ext->propertyLists[i] != nullptr; i++) 52 - { 53 - const old_property_list* l = cls->ext->propertyLists[i]; 54 - ConvertProperties(l, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { class_addProperty(conv, name, attr, count); bug_gnustepFixPropertyCount(conv); }); 55 - } 56 - } 57 - } 58 - 59 - objc_registerClassPair(conv); 60 - g_classPointers[cls] = conv; 61 - g_classPointers[cls->name] = conv; 62 - 63 - LOG << "ObjC class " << cls->name << " @" << conv << std::endl; 64 - 65 - return conv; 66 - } 67 - 68 - void AddClassProtocols(Class conv, old_protocol_list* list) 69 - { 70 - for (long i = 0; i < list->count; i++) 71 - { 72 - Protocol* p = objc_getProtocol(list->list[i]->name); 73 - assert(p != nullptr); 74 - class_addProtocol(conv, p); 75 - } 76 - } 77 - 78 - std::vector<const char*> ProcessClassesOld(const struct mach_header* mh, intptr_t slide, module_info* info) 79 - { 80 - unsigned long cstrLen; 81 - void* ptr; 82 - std::vector<old_class*> vecClasses; 83 - std::set<old_class*> setClasses; 84 - std::map<const char*,old_class*> mapClassNames; 85 - std::vector<const char*> vecClassNames; 86 - 87 - // ptr = getsectdata(mh, "__TEXT", "__cstring", &cstrLen); 88 - // if (ptr) 89 - // g_cstringSection = std::pair<uintptr_t,uintptr_t>(uintptr_t(ptr), cstrLen); 90 - // else 91 - // g_cstringSection = std::pair<uintptr_t,uintptr_t>(0, 0); 92 - 93 - for (uint16_t i = 0; i < info->symtab->countClasses; i++) 94 - { 95 - old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i]); 96 - mapClassNames[cls->name] = cls; 97 - setClasses.insert(cls); 98 - } 99 - 100 - topology_sort(setClasses, vecClasses, 101 - [&mapClassNames](old_class* t) -> std::set<old_class*> { auto it = mapClassNames.find(t->super_class.name); return (it != mapClassNames.end()) ? std::set<old_class*>{it->second} : std::set<old_class*>(); } 102 - ); 103 - 104 - for (old_class* c : vecClasses) 105 - RegisterClass(c, info->version >= 6); 106 - 107 - // Change class names in 'super_class' from strings to pointers to Class 108 - // for (size_t i = 0; i < size / sizeof(old_class); i++) 109 - for (uint16_t i = 0; i < info->symtab->countClasses; i++) 110 - { 111 - old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i]); 112 - Class c = (Class) objc_getClass(cls->super_class.name); 113 - LOG << "ObjC fixup super_class @" << &cls->super_class << ": " << cls->super_class.name << " -> " << c << std::endl; 114 - cls->super_class.clsNew = c; 115 - } 116 - 117 - // Fix the same in metaclasses 118 - // for (size_t i = 0; i < size / sizeof(old_class); i++) 119 - for (uint16_t i = 0; i < info->symtab->countClasses; i++) 120 - { 121 - old_class* cls = static_cast<old_class*>(info->symtab->classesAndCategories[i])->isa.cls; 122 - Class c = (Class) objc_getMetaClass(cls->super_class.name); 123 - LOG << "ObjC fixup super_class @" << cls << ": " << cls->name << " -> " << c << std::endl; 124 - cls->super_class.clsNew = c; 125 - } 126 - 127 - //std::transform(mapClassNames.begin(), mapClassNames.end(), vecClassNames.begin(), [](const std::pair<const char*,old_class*>& p) { return p.first; }); 128 - for (auto it = mapClassNames.begin(); it != mapClassNames.end(); it++) 129 - vecClassNames.push_back(it->first); 130 - 131 - return vecClassNames; 132 - } 133 - 134 - void UpdateClassRefs(const struct mach_header* mh) 135 - { 136 - clsref* class_refs; 137 - unsigned long refsize; 138 - 139 - class_refs = reinterpret_cast<clsref*>( 140 - getsectdata(mh, SEG_OBJC_CLASSREFS_OLD, SECT_OBJC_CLASSREFS_OLD, &refsize) 141 - ); 142 - 143 - if (class_refs) 144 - { 145 - for (size_t i = 0; i < refsize / sizeof(clsref); i++) 146 - { 147 - Class c = (Class) objc_getClass(class_refs[i].clsName); 148 - LOG << "ObjC fixup classref @" << &class_refs[i].cls << ": " << class_refs[i].cls << " -> " << c << std::endl; 149 - class_refs[i].cls = c; 150 - } 151 - } 152 - } 153 -
-15
src/libobjcdarwin/old/class.h
··· 1 - #ifndef OLD_CLASS_H 2 - #define OLD_CLASS_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - #include <string> 7 - #include <vector> 8 - #include <libdyld/dyld_public.h> 9 - 10 - Class RegisterClass(old_class* cls, bool hasExt); 11 - std::vector<const char*> ProcessClassesOld(const struct mach_header* mh, intptr_t slide, module_info* info); 12 - void AddClassProtocols(Class conv, old_protocol_list* list); 13 - void UpdateClassRefs(const struct mach_header* mh); 14 - 15 - #endif
-73
src/libobjcdarwin/old/exceptions.cpp
··· 1 - #include "exceptions.h" 2 - #include <cstdlib> 3 - #include <iostream> 4 - #include "../util/trace.h" 5 - 6 - static __thread TryBlock* m_lastBlock = nullptr; 7 - 8 - void __darwin_objc_exception_throw(objc_object* object) 9 - { 10 - TRACE1(object); 11 - 12 - if (!object) 13 - { 14 - std::cerr << "NULL Objective-C exception thrown!\n"; 15 - abort(); 16 - } 17 - 18 - if (!m_lastBlock) 19 - { 20 - std::cerr << "Unhandled Objective-C exception: " << class_getName(object_getClass(object)) << '(' << object << ")\n"; 21 - abort(); 22 - } 23 - else 24 - { 25 - TryBlock* currentBlock = m_lastBlock; 26 - 27 - currentBlock->exceptionObject = object; 28 - m_lastBlock = m_lastBlock->previousBlock; 29 - 30 - longjmp(currentBlock->buffer, true); 31 - } 32 - } 33 - 34 - void objc_exception_try_enter(TryBlock* state) 35 - { 36 - TRACE1(state); 37 - state->previousBlock = m_lastBlock; 38 - m_lastBlock = state; 39 - } 40 - 41 - void objc_exception_try_exit(TryBlock* state) 42 - { 43 - TRACE1(state); 44 - if (state != m_lastBlock) 45 - { 46 - std::cerr << "Incorrect try-block state passed to objc_exception_try_exit\n"; 47 - abort(); 48 - } 49 - m_lastBlock = state->previousBlock; 50 - } 51 - 52 - void* objc_exception_extract(TryBlock* state) 53 - { 54 - TRACE1(state); 55 - return state->exceptionObject; 56 - } 57 - 58 - int objc_exception_match(objc_class* cls, objc_object* object) 59 - { 60 - TRACE2(cls, object); 61 - objc_class* objClass = object_getClass(object); 62 - 63 - while (objClass) 64 - { 65 - if (objClass == cls) 66 - return true; 67 - else 68 - objClass = class_getSuperclass(objClass); 69 - } 70 - 71 - return false; 72 - } 73 -
-49
src/libobjcdarwin/old/exceptions.h
··· 1 - #ifndef OBJC_EXCEPTIONS_H 2 - #define OBJC_EXCEPTIONS_H 3 - #include <objc/runtime.h> 4 - #include <setjmp.h> 5 - #include "../visibility.h" 6 - 7 - // Apple 32-bit ObjC ABI doesn't use Itanium ABI zero-cost exceptions. 8 - // Instead, every try block is registered and deregistered, every catch 9 - // block is tested for usability with a runtime function call and if no 10 - // match is found, the exception is thrown again to traverse the try 11 - // block chain. 12 - 13 - struct TryBlock 14 - { 15 - jmp_buf buffer; 16 - 17 - union 18 - { 19 - void* fourPointers[4]; 20 - 21 - struct 22 - { 23 - objc_object* exceptionObject; 24 - TryBlock* previousBlock; 25 - }; 26 - }; 27 - }; 28 - 29 - extern "C" { 30 - 31 - // This function is called repeatedly until a handler is found 32 - DARLING_VISIBLE void __darwin_objc_exception_throw(objc_object* object); 33 - 34 - // Called on every @try { 35 - DARLING_VISIBLE void objc_exception_try_enter(TryBlock* state); 36 - 37 - // Called on every } of a @try block 38 - DARLING_VISIBLE void objc_exception_try_exit(TryBlock* state); 39 - 40 - // Called to get the exception object 41 - DARLING_VISIBLE void* objc_exception_extract(TryBlock* state); 42 - 43 - // Called to check if the handler's type is appropriate for the exception object 44 - DARLING_VISIBLE int objc_exception_match(objc_class* cls, objc_object* object); 45 - 46 - } 47 - 48 - #endif 49 -
-9
src/libobjcdarwin/old/ivar.h
··· 1 - #ifndef OLD_IVAR_H 2 - #define OLD_IVAR_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - 7 - void ConvertIvarList(Class c, const old_ivar_list* list); 8 - 9 - #endif
-20
src/libobjcdarwin/old/ivar.mm
··· 1 - #include "./ivar.h" 2 - #include <Foundation/NSObjCRuntime.h> 3 - #include "../../util/log.h" 4 - 5 - void ConvertIvarList(Class c, const old_ivar_list* list) 6 - { 7 - LOG << list->count << " ivars within\n"; 8 - 9 - for (size_t i = 0; i < list->count; i++) 10 - { 11 - auto* v = &list->ivar_list[i]; 12 - NSUInteger size, alignment; 13 - 14 - NSGetSizeAndAlignment(v->type, &size, &alignment); 15 - alignment = __builtin_ffs(alignment) - 1; // TODO: why do we need alignment when we have an offset? 16 - 17 - LOG << "Ivar: name: " << v->name << "; type: " << v->type << "; offset: " << v->offset << "; size: " << size << "; alignment: " << alignment << std::endl; 18 - class_addIvar(c, v->name, size, alignment, v->type); 19 - } 20 - }
-110
src/libobjcdarwin/old/protocol.cpp
··· 1 - #include "./protocol.h" 2 - #include "../../util/log.h" 3 - #include "../TopologySort.h" 4 - #include "../common/property.h" 5 - #include <cstring> 6 - 7 - void RegisterProtocolMethods(Protocol* p, const old_method_decl_list* list, bool required, bool instance) 8 - { 9 - LOG << "Registering Protocol methods (" << required << ", " << instance << "): " << list->count << " methods within\n"; 10 - for (size_t i = 0; i < list->count; i++) 11 - { 12 - SEL sel = sel_registerName(list->list[i].name); 13 - protocol_addMethodDescription(p, sel, list->list[i].types, required, instance); 14 - // TODO: what do we do with extTypes? 15 - } 16 - } 17 - 18 - Protocol* RegisterProtocol(old_protocol* prot, uintptr_t extStart, unsigned long extLen) 19 - { 20 - // For reasons unknown, the NSObject protocol is duplicated into the binaries 21 - if (strcmp(prot->name, "NSObject") == 0) 22 - return objc_getProtocol(prot->name); 23 - 24 - LOG << "Processing old ObjC Protocol: " << prot->name << std::endl; 25 - Protocol* conv = objc_allocateProtocol(prot->name); 26 - 27 - if (prot->protocols) 28 - { 29 - for (size_t i = 0; i < prot->protocols->count; i++) 30 - { 31 - const char* name = prot->protocols->list[i]->name; 32 - protocol_addProtocol(conv, objc_getProtocol(name)); 33 - } 34 - } 35 - 36 - if (prot->methods) 37 - RegisterProtocolMethods(conv, prot->methods, true, true); 38 - if (prot->staticMethods) 39 - RegisterProtocolMethods(conv, prot->staticMethods, true, false); 40 - 41 - // Protocol EXT - weird stuff 42 - if (prot->ext_ptrValue >= extStart && prot->ext_ptrValue < extStart + extLen) 43 - { 44 - // TODO: check if rebase is present 45 - if (prot->ext->optMethods) 46 - RegisterProtocolMethods(conv, prot->ext->optMethods, false, true); 47 - if (prot->ext->optStaticMethods) 48 - RegisterProtocolMethods(conv, prot->ext->optStaticMethods, false, false); 49 - if (prot->ext->properties) 50 - ConvertProperties(prot->ext->properties, [conv](const char* name, const objc_property_attribute_t* attr, unsigned int count) { protocol_addProperty(conv, name, attr, count, true, true); }); 51 - } 52 - 53 - objc_registerProtocol(conv); 54 - return conv; 55 - } 56 - 57 - 58 - void ProcessProtocolsOld(const struct mach_header* mh, intptr_t slide) 59 - { 60 - old_protocol* protocols; 61 - unsigned long protosize; 62 - 63 - protocols = reinterpret_cast<old_protocol*>( 64 - getsectdata(mh, SEG_OBJC_PROTOCOLS_OLD, SECT_OBJC_PROTOCOLS_OLD, &protosize) 65 - ); 66 - 67 - if (protocols) 68 - { 69 - std::vector<old_protocol*> vecProtocols; 70 - std::set<old_protocol*> setProtocols; 71 - // std::map<const char*,old_protocol*> mapProtocols; 72 - 73 - for (size_t i = 0; i < protosize / sizeof(old_protocol); i++) 74 - { 75 - if (strcmp(protocols[i].name, "NSObject") != 0) // No need to re-register protocol NSObject 76 - setProtocols.insert(protocols + i); 77 - // mapProtocols[protocols[i].name] = protocols + i; 78 - } 79 - 80 - topology_sort<old_protocol>(setProtocols, vecProtocols, 81 - [&setProtocols](old_protocol* p) -> std::set<old_protocol*> 82 - { 83 - std::set<old_protocol*> set; 84 - if (p->protocols) 85 - { 86 - for (size_t i = 0; i < p->protocols->count; i++) 87 - { 88 - if (setProtocols.count(p->protocols->list[i])) 89 - set.insert(p->protocols->list[i]); 90 - } 91 - } 92 - return set; 93 - } 94 - ); 95 - 96 - // Find the section that holds protocol_ext structs 97 - uintptr_t extStart; 98 - unsigned long extLen = 0; 99 - 100 - extStart = reinterpret_cast<uintptr_t>( 101 - getsectdata(mh, SEG_OBJC_PROTOEXT_OLD, SECT_OBJC_PROTOEXT_OLD, &extLen) 102 - ); 103 - 104 - for (old_protocol* old : vecProtocols) 105 - { 106 - Protocol* p = RegisterProtocol(old, extStart, extLen); 107 - old->isa = (id) p; // This is what is referenced in the code 108 - } 109 - } 110 - }
-12
src/libobjcdarwin/old/protocol.h
··· 1 - #ifndef OLD_PROTOCOL_H 2 - #define OLD_PROTOCOL_H 3 - #include "./AppleLayout.h" 4 - #include <objc/runtime.h> 5 - #include <stdint.h> 6 - #include <libdyld/dyld_public.h> 7 - 8 - void RegisterProtocolMethods(Protocol* p, const old_method_decl_list* list, bool required, bool instance); 9 - Protocol* RegisterProtocol(old_protocol* prot, uintptr_t extStart, unsigned long extLen); 10 - void ProcessProtocolsOld(const struct mach_header* mh, intptr_t slide); 11 - 12 - #endif
-14
src/libobjcdarwin/old/ptr.h
··· 1 - #ifndef OLD_PTR_H 2 - #define OLD_PTR_H 3 - 4 - 5 - template<typename T> 6 - static T* advance_ptr(T* ptr, size_t bytes) 7 - { 8 - uintptr_t v = reinterpret_cast<uintptr_t>(ptr); 9 - v += bytes; 10 - return reinterpret_cast<T*>(v); 11 - } 12 - 13 - 14 - #endif
-7
src/libobjcdarwin/visibility.h
··· 1 - #ifndef VISIBILITY_H 2 - #define VISIBILITY_H 3 - 4 - #define DARLING_VISIBLE __attribute__((visibility("default"))) 5 - 6 - #endif 7 -