int main(int argc, char **argv) { struct NaClApp state, *nap = &state; struct SystemManifest sys_mft; struct GioMemoryFileSnapshot main_file; GTimer *timer; /* zerovm initialization */ memset(nap, 0, sizeof *nap); nap->system_manifest = &sys_mft; memset(nap->system_manifest, 0, sizeof *nap->system_manifest); gnap = nap; ParseCommandLine(nap, argc, argv); NaClSignalHandlerInit(); NaClSyscallTableInit(); /* initialize mem_map and set nap fields to default values */ ZLOGFAIL(NaClAppCtor(nap) == 0, EFAULT, "Error while constructing app state"); /* We use the signal handler to verify a signal took place. */ if(nap->skip_qualification == 0) NaClRunSelQualificationTests(); /* Remove the signal handler if we are not using it. */ if(nap->handle_signals == 0) { NaClSignalHandlerFini(); NaClSignalAssertNoHandlers(); /* Sanity check. */ } /* read nexe into memory */ timer = g_timer_new(); ZLOGFAIL(0 == GioMemoryFileSnapshotCtor(&main_file, nap->system_manifest->nexe), ENOENT, "Cannot open '%s'. %s", nap->system_manifest->nexe, strerror(errno)); #define TIMER_REPORT(msg) \ do {\ ZLOGS(LOG_DEBUG, msg " took %.3f milliseconds",\ g_timer_elapsed(timer, NULL) * NACL_MICROS_PER_MILLI);\ g_timer_start(timer);\ } while(0) TIMER_REPORT("GioMemoryFileSnapshotCtor()"); /* validate given nexe (ensure that text segment is safe) */ ValidateNexe(nap); TIMER_REPORT("ValidateNexe()"); /* validate nexe structure (check elf header and segments) */ ZLOGS(LOG_DEBUG, "Loading nacl file %s", nap->system_manifest->nexe); NaClAppLoadFile((struct Gio *) &main_file, nap); TIMER_REPORT("NaClAppLoadFile()"); if(-1 == (*((struct Gio *)&main_file)->vtbl->Close)((struct Gio *)&main_file)) ZLOG(LOG_ERROR, "Error while closing '%s'", nap->system_manifest->nexe); (*((struct Gio *) &main_file)->vtbl->Dtor)((struct Gio *) &main_file); /* quit if fuzz testing specified */ if(nap->quit_after_load) { SetExitState(OK_STATE); NaClExit(0); } /* setup zerovm from manifest */ SystemManifestCtor(nap); /* "defence in depth" call */ LastDefenseLine(nap); /* start accounting */ AccountingCtor(nap); /* Make sure all the file buffers are flushed before entering the nexe */ fflush((FILE*) NULL); TIMER_REPORT("nexe start preparation"); /* set user code trap() exit location and switch to the user code */ if(setjmp(user_exit) == 0) ZLOGFAIL(!NaClCreateMainThread(nap), EFAULT, "switching to nexe failed"); SetExitState(OK_STATE); TIMER_REPORT("NaClCreateMainThread()"); /* zerovm exit with finalization, report and stuff */ NaClExit(0); /* Unreachable, but having the return prevents a compiler error. */ return -1; }
int main(int argc, char **argv) { struct NaClApp state, *nap = &state; struct SystemManifest sys_mft; struct GioMemoryFileSnapshot main_file; struct NaClPerfCounter time_all_main; /* zerovm initialization */ memset(nap, 0, sizeof *nap); nap->system_manifest = &sys_mft; memset(nap->system_manifest, 0, sizeof *nap->system_manifest); gnap = nap; ParseCommandLine(nap, argc, argv); NaClSignalHandlerInit(); NaClTimeInit(); NaClSyscallTableInit(); NaClPerfCounterCtor(&time_all_main, "SelMain"); /* initialize mem_map and set nap fields to default values */ ZLOGFAIL(NaClAppCtor(nap) == 0, EFAULT, "Error while constructing app state"); /* We use the signal handler to verify a signal took place. */ if(nap->skip_qualification == 0) NaClRunSelQualificationTests(); /* Remove the signal handler if we are not using it. */ if(nap->handle_signals == 0) { NaClSignalHandlerFini(); NaClSignalAssertNoHandlers(); /* Sanity check. */ } #define PERF_CNT(str) \ NaClPerfCounterMark(&time_all_main, str);\ NaClPerfCounterIntervalLast(&time_all_main); /* read nexe into memory */ ZLOGFAIL(0 == GioMemoryFileSnapshotCtor(&main_file, nap->system_manifest->nexe), ENOENT, "Cannot open '%s'. %s", nap->system_manifest->nexe, strerror(errno)); PERF_CNT("SnapshotNaclFile"); /* validate given nexe (ensure that text segment is safe) */ ValidateNexe(nap); /* validate nexe structure (check elf header and segments) */ ZLOGS(LOG_DEBUG, "Loading nacl file %s", nap->system_manifest->nexe); NaClAppLoadFile((struct Gio *) &main_file, nap); PERF_CNT("AppLoadEnd"); if(-1 == (*((struct Gio *)&main_file)->vtbl->Close)((struct Gio *)&main_file)) ZLOG(LOG_ERROR, "Error while closing '%s'", nap->system_manifest->nexe); (*((struct Gio *) &main_file)->vtbl->Dtor)((struct Gio *) &main_file); if(nap->quit_after_load) NaClExit(0); /* setup zerovm from manifest */ SystemManifestCtor(nap); /* needs dyn_array initialized */ /* "defence in depth" call */ LastDefenseLine(nap); /* start accounting */ AccountingCtor(nap); /* Make sure all the file buffers are flushed before entering the nexe */ fflush((FILE*) NULL); /* set user code trap() exit location and switch to the user code */ PERF_CNT("CreateMainThread"); if(setjmp(user_exit) == 0) ZLOGFAIL(!NaClCreateMainThread(nap), EFAULT, "switching to nexe failed"); SetExitState(OK_STATE); PERF_CNT("WaitForMainThread"); PERF_CNT("SelMainEnd"); /* zerovm exit with finalization, report and stuff */ NaClExit(0); /* Unreachable, but having the return prevents a compiler error. */ return -1; }