void _init() { extern int main(int argc, char **argv); extern void _on_event(void); char **argv, *pack; size_t length; int argc; _when((uintptr_t) _on_event); /* unpack environment variables */ __loadenv(); /* setup standard streams */ stdin = fdopen(fdload(0), "r"); stdout = fdopen(fdload(1), "w"); stderr = fdopen(fdload(2), "w"); fs_root = fdload(3); /* set up signals */ __sig_init(); when(PORT_CHILD, NULL); /* set up I/O handlers */ when(PORT_REPLY, NULL); when(PORT_READ, reject); when(PORT_WRITE, reject); when(PORT_SYNC, reject); when(PORT_RESET, reject); when(PORT_SHARE, reject); when(PORT_RCALL, reject); when(PORT_EVENT, ignore); when(PORT_FIND, reject); when(PORT_CONS, reject); when(PORT_MOVE, reject); when(PORT_REMV, reject); when(PORT_LINK, reject); when(PORT_LIST, reject); when(PORT_SIZE, reject); when(PORT_TYPE, reject); when(PORT_PERM, reject); when(PORT_AUTH, reject); /* unpack argument list */ pack = __pack_load(PACK_KEY_ARG, &length); if (pack) { argv = loadarg(pack); for (argc = 0; argv[argc]; argc++); setenv("NAME", argv[0]); } else { argv = NULL; argc = 0; setenv("NAME", "unknown"); } __pack_reset(); /* execute main program */ exit(main(argc, argv)); }
int _exec(void *image, size_t size, int flags) { struct slt32_header *slt_hdr; struct slt32_entry *slt; struct elf32_ehdr *exec; struct elf_cache cache; void *entry; size_t i; const char *soname; char imgname[28]; /* check executable */ if (elf_check(image)) { return 1; } /*** POINT OF MAYBE RETURNING IF YOU, y'know, have to... ***/ /* copy executable high */ exec = (void*) sltalloc("dl.img:exec", size); if ((uintptr_t) image % PAGESZ) { /* not aligned, copy */ page_anon(exec, size, PROT_READ | PROT_WRITE); memcpy(exec, image, size); } else { /* aligned, use paging */ page_self(image, exec, size); } /*** POINT OF NO RETURN ***/ /* load dependencies */ for (i = 0;; i++) { soname = _dep(exec, i, 0); if (!soname) break; strlcpy(imgname, "dl.img:", 28); strlcat(imgname, soname, 28); slt = sltget_name(imgname); if (!slt) continue; _load((void*) slt->base, slt->size, RTLD_LAZY | RTLD_GLOBAL | RTLD_OVERWRITE); sltfree_name(imgname); } /* clear lower memory */ slt = (void*) SLT_BASE; slt_hdr = (void*) SLT_BASE; for (i = slt_hdr->first; i; i = slt[i].next) { if (slt[i].flags & SLT_FLAG_CLEANUP) { page_free((void*) slt[i].base, slt[i].size); } } /* load executable */ elf_load(exec, 0); exec = (void*) 0x100000; entry = (void*) exec->e_entry; elf_gencache(&cache, exec, 1); elfc_relocate_all(&cache); /* remove executable image */ sltfree_name("dl.img:exec"); /* reset event handler */ _when(0); /* enter executable */ dl_enter(entry); return 1; }