diff --git a/src/dyld/dyld.cpp b/src/dyld/dyld.cpp index 0c1e3181a..461b2a4f0 100644 --- a/src/dyld/dyld.cpp +++ b/src/dyld/dyld.cpp @@ -108,14 +108,31 @@ int main(int argc, char** argv, char** envp) return -ENOEXEC; } #endif + // Modify the argument list so that the dyld name disappears from the process list. + // The Linux kernel doesn't really support this - it remembers the byte length of the cmdline, which will now decrease. + // Any app that examines this process' /proc/.../cmdline will from now on see a group of empty arguments after the real arguments. + // We fix this for NSProcessInfo in libobjcdarwin. + + uintptr_t totalLen = argv[argc-1] + strlen(argv[argc-1]) + 1 - argv[0]; + uintptr_t shortenedLen = totalLen - (strlen(argv[0]) + 1); + + memmove(argv[0], argv[1], shortenedLen); + memset(argv[0]+shortenedLen, 0, totalLen - shortenedLen); + + // Reconstruct the argv array + for (int pos = 0, index = 1; index < argc-1; pos++) + { + if (!argv[0][pos]) + argv[index++] = &argv[0][pos+1]; + } - g_argv = argv+1; - g_argc = argc-1; + g_argv = argv; + g_argc = argc; g_loader = new MachOLoader; autoSysrootSearch(); - g_loader->run(*g_mainBinary, argc-1, argv+1, envp); + g_loader->run(*g_mainBinary, argc, argv, envp); delete g_loader; g_loader = 0; diff --git a/src/libobjcdarwin/CMakeLists.txt b/src/libobjcdarwin/CMakeLists.txt index 76749db35..16959738e 100644 --- a/src/libobjcdarwin/CMakeLists.txt +++ b/src/libobjcdarwin/CMakeLists.txt @@ -30,6 +30,7 @@ set(objcdarwin_SRCS common/attribute.cpp common/property.cpp common/selector.cpp + common/cfstring.cpp old/category.cpp old/class.cpp @@ -42,7 +43,7 @@ set(objcdarwin_SRCS new/protocol.cpp NSBundle_dyld.mm - NSCFString.mm + #NSCFString.mm misc.mm zero.c ) diff --git a/src/libobjcdarwin/ClassRegister.cpp b/src/libobjcdarwin/ClassRegister.cpp index bbcb97f42..cfc205472 100644 --- a/src/libobjcdarwin/ClassRegister.cpp +++ b/src/libobjcdarwin/ClassRegister.cpp @@ -9,6 +9,7 @@ #include "old/category.h" #include "new/category.h" #include "common/selector.h" +#include "common/cfstring.h" #include // Superclass references in Mach-O don't use classref @@ -67,6 +68,7 @@ void ProcessImageLoad(const struct mach_header* mh, intptr_t slide) ProcessCategoriesNew(mh, slide); UpdateSelectors(mh, slide); + UpdateCFStrings(mh); } void ProcessImageUnload(const struct mach_header* mh, intptr_t) diff --git a/src/libobjcdarwin/NSBundle_dyld.mm b/src/libobjcdarwin/NSBundle_dyld.mm index 3f40f25d4..d55ca4541 100644 --- a/src/libobjcdarwin/NSBundle_dyld.mm +++ b/src/libobjcdarwin/NSBundle_dyld.mm @@ -6,10 +6,13 @@ #include #include #include +#include #include #include "../util/log.h" extern char g_darwin_executable_path[PATH_MAX]; +extern int g_argc; +extern char** g_argv; static NSBundle* _mainBundle = 0; static NSAutoreleasePool* g_pool = 0; @@ -21,8 +24,12 @@ __attribute__((constructor)) static void myinit() MethodSwizzle(objc_getMetaClass("NSBundle"), @selector(mainBundle), @selector(x_mainBundle)); + // Many OS X apps assume that there is a "default" autorelease pool provided g_pool = [[NSAutoreleasePool alloc] init]; + GSInitializeProcess(g_argc, g_argv, environ); + + /* const char* last = strrchr(g_darwin_executable_path, '/'); if (last != 0) { @@ -31,6 +38,7 @@ __attribute__((constructor)) static void myinit() NSString* str = [NSString stringWithUTF8String:last]; [[NSProcessInfo processInfo] setProcessName:str]; } + */ } __attribute__((destructor)) static void myexit() diff --git a/tests/src/cfbridge.m b/tests/src/cfbridge.m new file mode 100644 index 000000000..1530d1b40 --- /dev/null +++ b/tests/src/cfbridge.m @@ -0,0 +1,22 @@ +// CFLAGS: -framework corefoundation -framework foundation +#import +#import +#include + +int main() +{ + CFStringRef str = CFSTR("Test"); + const char* text = [(NSString*)str UTF8String]; + puts(text); + NSLog(@"%@\n", str); + [str retain]; + printf("%u\n", [str retainCount]); // This should output UINT_MAX + + CFStringRef str2 = CFStringCreateWithBytes(NULL, "Test2", 6, kCFStringEncodingASCII, 0); + CFRetain(str2); + printf("%u\n", [str2 retainCount]); + + return 0; +} + +