int main(int argc, char** argv, char** envp) { if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printHelp(argv[0]); return 1; } if (!HasUserDirectoryStructure()) SetupUserDirectoryStructure(); std::set_terminate(terminateHandler); sigset_t set; sigemptyset(&set); sigaddset(&set, SIGHUP); sigprocmask(SIG_BLOCK, &set, NULL); try { MachOObject* obj; MachOMgr* mgr = MachOMgr::instance(); std::string executable; executable = locateBundleExecutable(argv[1]); argv[1] = const_cast<char*>(executable.c_str()); mgr->detectSysRootFromPath(argv[1]); mgr->setPrintInitializers(getenv("DYLD_PRINT_INITIALIZERS") != nullptr); mgr->setPrintLibraries(getenv("DYLD_PRINT_LIBRARIES") != nullptr); #ifdef __arm__ // dyld_stub_binder hasn't been ported to ARM yet mgr->setBindAtLaunch(true); #else mgr->setBindAtLaunch(getenv("DYLD_BIND_AT_LAUNCH") != nullptr); #endif mgr->setIgnoreMissingSymbols(getenv("DYLD_IGN_MISSING_SYMS") != nullptr); mgr->setPrintSegments(getenv("DYLD_PRINT_SEGMENTS") != nullptr); mgr->setPrintBindings(getenv("DYLD_PRINT_BINDINGS") != nullptr); mgr->setPrintRpathExpansion(getenv("DYLD_PRINT_RPATHS") != nullptr); if (const char* path = getenv("DYLD_LIBRARY_PATH")) mgr->setLibraryPath(path); if (const char* path = getenv("DYLD_ROOT_PATH")) mgr->setSysRoot(path); if (const char* path = getenv("DYLD_TRAMPOLINE")) mgr->setUseTrampolines(true, path); obj = new MachOObject(argv[1]); if (!obj->isMainModule()) throw std::runtime_error("Not an MH_EXECUTE file"); obj->setCommandLine(argc-1, &argv[1], envp); obj->load(); obj->run(); } catch (const std::exception& e) { std::cerr << "dyld: Cannot execute binary file: " << e.what() << std::endl; return ENOSYS; } }
int main(int argc, char** argv, char** envp) { if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printHelp(argv[0]); return 1; } if (!HasUserDirectoryStructure()) SetupUserDirectoryStructure(); try { MachOMgr* mgr = MachOMgr::instance(); std::string executable, unprefixed_argv0; const char* pretendArgv0; pretendArgv0 = findFakeArgv0(argv[1]); executable = locateBundleExecutable(argv[1]); argv[1] = const_cast<char*>(executable.c_str()); mgr->detectSysRootFromPath(argv[1]); mgr->setPrintInitializers(getenv("DYLD_PRINT_INITIALIZERS") != nullptr); mgr->setPrintLibraries(getenv("DYLD_PRINT_LIBRARIES") != nullptr); #ifdef __arm__ // dyld_stub_binder hasn't been ported to ARM yet mgr->setBindAtLaunch(true); #else mgr->setBindAtLaunch(getenv("DYLD_BIND_AT_LAUNCH") != nullptr); #endif mgr->setIgnoreMissingSymbols(getenv("DYLD_IGN_MISSING_SYMS") != nullptr); // mgr->setIgnoreMissingDependencies(getenv("DYLD_IGN_MISSING_DEPS") != nullptr); mgr->setPrintSegments(getenv("DYLD_PRINT_SEGMENTS") != nullptr); mgr->setPrintBindings(getenv("DYLD_PRINT_BINDINGS") != nullptr); mgr->setPrintRpathExpansion(getenv("DYLD_PRINT_RPATHS") != nullptr); mgr->setForceFlatNamespace(getenv("DYLD_FORCE_FLAT_NAMESPACE") != nullptr); if (const char* path = getenv("DYLD_LIBRARY_PATH")) mgr->setLibraryPath(path); if (const char* path = getenv("DYLD_ROOT_PATH")) mgr->setSysRoot(path); if (const char* path = getenv("DYLD_TRAMPOLINE")) mgr->setUseTrampolines(true, path); if (const char* path = getenv("DPREFIX")) { __prefix_set(path); unprefixed_argv0 = __prefix_untranslate_path(argv[1], strlen(argv[1])); } if (getenv("DYLD_GDBJIT") != nullptr) Darling::SetupGDBJIT(); if (isELF(argv[1])) { NativeObject* obj; typedef int (mainPtr)(int argc, char** argv, char** envp); mainPtr* main; obj = new NativeObject(argv[1]); obj->load(); NativeObject::setMainObject(obj); main = (mainPtr*) obj->getExportedSymbol("main", false); if (!main) throw std::runtime_error("No entry point found in Darling-native executable"); if (pretendArgv0 != nullptr) argv[1] = (char*) pretendArgv0; else if (!unprefixed_argv0.empty()) argv[1] = (char*) unprefixed_argv0.c_str(); exit(main(argc-1, &argv[1], envp)); } else { MachOObject* obj; if (::mmap(0, 4096, PROT_READ|PROT_EXEC, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) != 0) { if (errno == EPERM) { std::cerr << "Cannot map page zero, some macOS apps may require this.\n"; std::cerr << "This problem can be fixed by running 'setcap cap_sys_rawio=ep " << pathToSelf() << "' as root.\n"; } } obj = new MachOObject(argv[1]); if (!obj->isMainModule()) { throw std::runtime_error("This is not a Mach-O executable; dynamic libraries, " "kernel extensions and other Mach-O files cannot be executed with dyld"); } if (pretendArgv0 != nullptr) argv[1] = (char*) pretendArgv0; else if (!unprefixed_argv0.empty()) argv[1] = (char*) unprefixed_argv0.c_str(); obj->setCommandLine(argc-1, &argv[1], envp); obj->load(); obj->run(); } } catch (const std::exception& e) { std::cerr << "dyld: Cannot execute binary file: " << e.what() << std::endl; return ENOSYS; } }