void *__pack_load(uint32_t key, size_t *size) { size_t i; if (!phys(__pack_vector)) { page_anon(__pack_vector, PAGESZ, PROT_READ | PROT_WRITE); __pack_vector[0].key = 0; } for (i = 0; __pack_vector[i].key; i++) { if (__pack_vector[i].key == key) { *size = __pack_vector[i].size; return __pack_vector[i].data; } } return NULL; }
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; }