示例#1
0
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;
	}
}
示例#2
0
文件: dyld.cpp 项目: X0rg/darling
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;
	}
}