uintptr_t start_sim(int argc, const char* argv[], const char* envp[], const char* apple[], const macho_header* mainExecutableMH, const macho_header* dyldMH, uintptr_t dyldSlide, const dyld::SyscallHelpers* sc, uintptr_t* startGlue) { // if simulator dyld loaded slid, it needs to rebase itself // we have to do this before using any global variables if ( dyldSlide != 0 ) { rebaseDyld(dyldMH, dyldSlide); } // save table of syscall pointers gSyscallHelpers = sc; // allow dyld to use mach messaging mach_init(); // set up random value for stack canary __guard_setup(apple); // setup gProcessInfo to point to host dyld's struct dyld::gProcessInfo = (struct dyld_all_image_infos*)(sc->getProcessInfo()); syncProcessInfo(); // now that we are done bootstrapping dyld, call dyld's main uintptr_t appsSlide = slideOfMainExecutable(mainExecutableMH); return dyld::_main(mainExecutableMH, appsSlide, argc, argv, envp, apple, startGlue); }
// // This is code to bootstrap dyld. This work in normally done for a program by dyld and crt. // In dyld we have to do this manually. // uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char* argv[], intptr_t slide, const struct macho_header* dyldsMachHeader, uintptr_t* startGlue) { // if kernel had to slide dyld, we need to fix up load sensitive locations // we have to do this before using any global variables if ( slide != 0 ) { rebaseDyld(dyldsMachHeader, slide); } // allow dyld to use mach messaging mach_init(); // kernel sets up env pointer to be just past end of agv array const char** envp = &argv[argc+1]; // kernel sets up apple pointer to be just past end of envp array const char** apple = envp; while(*apple != NULL) { ++apple; } ++apple; // set up random value for stack canary __guard_setup(apple); #if DYLD_INITIALIZER_SUPPORT // run all C++ initializers inside dyld runDyldInitializers(dyldsMachHeader, slide, argc, argv, envp, apple); #endif // now that we are done bootstrapping dyld, call dyld's main uintptr_t appsSlide = slideOfMainExecutable(appsMachHeader); return dyld::_main(appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue); }
/* * Initialization. */ uintptr_t start(const macho_header* exec_header, int argc, const char* argv[], intptr_t slide, const macho_header* lnk_header) { if (slide != 0) { //lnk::ldbg::printNumber("lnk: rebased @ ", slide); /* * This will relocate the nl symbol pointers for the linker. * It must be called before any complex functions are called, since * globals are not relative. * * This is only needed if slide != 0. If slide is zero then the * linker has been compiled with a fixed load address thing. */ lnk::bootstrap::rebaseLinker(lnk_header, slide); } #if (1) /* * Print version info stuff. * * It's probably unnecessary to print this in production. * It was really nice at first though :) */ lnk::log("%s %s (built by %s on %s) \n" " slide: %d\n" " main header: %p\n" " lnk header: %p", gLibCoreName, gLibCoreVersion, gLibCoreVersioningUser, gLibCoreBuildDate, slide, exec_header, lnk_header); #endif sLinkerHeader = lnk_header; sLinkerSlide = slide; uintptr_t execSlide = slideOfMainExecutable(exec_header); lnk::_main(exec_header, execSlide, argc, argv, NULL, NULL); lnk::halt("lnk::_main returned, something went wrong!"); /* if something went wrong, loop so the kernel doesn't panic because of a * launchd crash */ _exit(0); }