int rp_share(uint64_t rp, void *buf, size_t size, uint64_t offset, int prot) { struct msg *msg; int err; /* check alignment */ if ((uintptr_t) buf % PAGESZ) { return 1; } msg = aalloc(PAGESZ + size, PAGESZ); if (!msg) return 1; msg->source = RP_CURRENT_THREAD; msg->target = rp; msg->length = PAGESZ - sizeof(struct msg) + size; msg->port = PORT_SHARE; msg->arch = ARCH_NAT; ((uint64_t*) msg->data)[0] = offset; page_self(buf, &msg->data[PAGESZ - sizeof(struct msg)], size); page_prot(&msg->data[PAGESZ - sizeof(struct msg)], size, prot); if (msend(msg)) return 1; msg = mwait(PORT_REPLY, rp); if (msg->length != 1) { err = 1; } else { err = msg->data[0]; } free(msg); return err; }
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; }