static int load_elf(struct exec_info *execi) { int r; struct vnode *vp; int proc_e; phys_bytes tot_bytes; /* total space for program, including gap */ vir_bytes text_vaddr, text_paddr, text_filebytes, text_membytes; vir_bytes data_vaddr, data_paddr, data_filebytes, data_membytes; off_t text_offset, data_offset; int sep_id, is_elf; assert(execi != NULL); assert(execi->hdr != NULL); assert(execi->vp != NULL); proc_e = execi->proc_e; vp = execi->vp; /* Read the file header and extract the segment sizes. */ r = read_header_elf(execi->hdr, &text_vaddr, &text_paddr, &text_filebytes, &text_membytes, &data_vaddr, &data_paddr, &data_filebytes, &data_membytes, &execi->pc, &text_offset, &data_offset); if (r != OK) return(r); sep_id = 0; is_elf = 1; tot_bytes = 0; /* Use default stack size */ r = exec_newmem(proc_e, trunc_page(text_vaddr), text_membytes, trunc_page(data_vaddr), data_membytes, tot_bytes, execi->frame_len, sep_id, is_elf, vp->v_dev, vp->v_inode_nr, execi->sb.st_ctime, execi->progname, execi->new_uid, execi->new_gid, &execi->stack_top, &execi->load_text, &execi->setugid); if (r != OK) { printf("VFS: load_elf: exec_newmem failed: %d\n", r); return(r); } /* Read in text and data segments. */ if (execi->load_text) r = read_seg(vp, text_offset, proc_e, T, text_vaddr, text_filebytes); if (r == OK) r = read_seg(vp, data_offset, proc_e, D, data_vaddr, data_filebytes); return(r); }
static int load_aout(struct exec_info *execi) { int r; struct vnode *vp; int proc_e; off_t off; int hdrlen; int sep_id; vir_bytes text_bytes, data_bytes, bss_bytes; phys_bytes tot_bytes; /* total space for program, including gap */ assert(execi != NULL); assert(execi->hdr != NULL); assert(execi->vp != NULL); proc_e = execi->proc_e; vp = execi->vp; /* Read the file header and extract the segment sizes. */ r = read_header_aout(execi->hdr, execi->vp->v_size, &sep_id, &text_bytes, &data_bytes, &bss_bytes, &tot_bytes, &execi->pc, &hdrlen); if (r != OK) return(r); r = exec_newmem(proc_e, 0 /* text_addr */, text_bytes, 0 /* data_addr */, data_bytes + bss_bytes, tot_bytes, execi->frame_len, sep_id, 0 /* is_elf */, vp->v_dev, vp->v_inode_nr, execi->sb.st_ctime, execi->progname, execi->new_uid, execi->new_gid, &execi->stack_top, &execi->load_text, &execi->setugid); if (r != OK) { printf("VFS: load_aout: exec_newmem failed: %d\n", r); return(r); } off = hdrlen; /* Read in text and data segments. */ if (execi->load_text) r = read_seg(vp, off, proc_e, T, 0, text_bytes); off += text_bytes; if (r == OK) r = read_seg(vp, off, proc_e, D, 0, data_bytes); return (r); }
static int load_elf(struct exec_info *execi) { int r; int proc_e; phys_bytes tot_bytes; /* total space for program, including gap */ vir_bytes text_addr, text_filebytes, text_membytes; vir_bytes data_addr, data_filebytes, data_membytes; off_t text_offset, data_offset; int sep_id, is_elf, load_text, allow_setuid; uid_t new_uid; gid_t new_gid; assert(execi != NULL); assert(execi->image != NULL); proc_e = execi->proc_e; /* Read the file header and extract the segment sizes. */ r = read_header_elf(execi->image, &text_addr, &text_filebytes, &text_membytes, &data_addr, &data_filebytes, &data_membytes, &tot_bytes, &execi->pc, &text_offset, &data_offset); if (r != OK) { return(r); } new_uid= getuid(); new_gid= getgid(); sep_id = 1; is_elf = 1; r = exec_newmem(proc_e, trunc_page(text_addr), text_membytes, trunc_page(data_addr), data_membytes, tot_bytes, execi->frame_len, sep_id, is_elf, 0 /*dev*/, proc_e /*inum*/, 0 /*ctime*/, execi->progname, new_uid, new_gid, &execi->stack_top, &load_text, &allow_setuid); if (r != OK) { printf("RS: load_elf: exec_newmem failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } /* Read in text and data segments. */ if (load_text) { r = read_seg(execi, text_offset, proc_e, T, text_addr, text_filebytes); if (r != OK) { printf("RS: load_elf: read_seg failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } } else printf("RS: load_elf: not loading text segment\n"); r = read_seg(execi, data_offset, proc_e, D, data_addr, data_filebytes); if (r != OK) { printf("RS: load_elf: read_seg failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } return(OK); }
static int load_aout(struct exec_info *execi) { int r; int hdrlen, sep_id, load_text, allow_setuid; vir_bytes text_bytes, data_bytes, bss_bytes; phys_bytes tot_bytes; off_t off; uid_t new_uid; gid_t new_gid; int proc_e; assert(execi != NULL); assert(execi->image != NULL); proc_e = execi->proc_e; /* Read the file header and extract the segment sizes. */ r = read_header_aout(execi->image, execi->image_len, &sep_id, &text_bytes, &data_bytes, &bss_bytes, &tot_bytes, &execi->pc, &hdrlen); if (r != OK) { return r; } new_uid= getuid(); new_gid= getgid(); /* XXX what should we use to identify the executable? */ r= exec_newmem(proc_e, 0 /*text_addr*/, text_bytes, 0 /*data_addr*/, data_bytes + bss_bytes, tot_bytes, execi->frame_len, sep_id, 0 /*is_elf*/, 0 /*dev*/, proc_e /*inum*/, 0 /*ctime*/, execi->progname, new_uid, new_gid, &execi->stack_top, &load_text, &allow_setuid); if (r != OK) { printf("RS: load_aout: exec_newmem failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } off = hdrlen; /* Read in text and data segments. */ if (load_text) { r= read_seg(execi, off, proc_e, T, 0, text_bytes); if (r != OK) { printf("RS: load_aout: read_seg failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } } else printf("RS: load_aout: not loading text segment\n"); off += text_bytes; r= read_seg(execi, off, proc_e, D, 0, data_bytes); if (r != OK) { printf("RS: load_aout: read_seg failed: %d\n", r); exec_restart(proc_e, r, execi->pc); return r; } return OK; }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main() { /* Main routine of the process manager. */ int result, s, proc_nr; struct mproc *rmp; sigset_t sigset; pm_init(); /* initialize process manager tables */ /* This is PM's main loop- get work and do it, forever and forever. */ while (TRUE) { get_work(); /* wait for an PM system call */ /* Check for system notifications first. Special cases. */ switch(call_nr) { case SYN_ALARM: pm_expire_timers(m_in.NOTIFY_TIMESTAMP); result = SUSPEND; /* don't reply */ break; case SYS_SIG: /* signals pending */ sigset = m_in.NOTIFY_ARG; if (sigismember(&sigset, SIGKSIG)) { (void) ksig_pending(); } result = SUSPEND; /* don't reply */ break; case PM_GET_WORK: if (who_e == FS_PROC_NR) { send_work(); result= SUSPEND; /* don't reply */ } else result= ENOSYS; break; case PM_EXIT_REPLY: case PM_REBOOT_REPLY: case PM_EXEC_REPLY: case PM_CORE_REPLY: case PM_EXIT_REPLY_TR: if (who_e == FS_PROC_NR) { handle_fs_reply(&m_in); result= SUSPEND; /* don't reply */ } else result= ENOSYS; break; case ALLOCMEM: result= do_allocmem(); break; case FORK_NB: result= do_fork_nb(); break; case EXEC_NEWMEM: result= exec_newmem(); break; case EXEC_RESTART: result= do_execrestart(); break; case PROCSTAT: result= do_procstat(); break; case GETPROCNR: result= do_getprocnr(); break; case GETPUID: result= do_getpuid(); break; case DIAG_REPL : diag_repl(); result= SUSPEND; break; default: /* Else, if the system call number is valid, perform the * call. */ if ((unsigned) call_nr >= NCALLS) { result = ENOSYS; } else { #if ENABLE_SYSCALL_STATS calls_stats[call_nr]++; #endif result = (*call_vec[call_nr])(); } break; } /* Send the results back to the user to indicate completion. */ if (result != SUSPEND) setreply(who_p, result); /* Send out all pending reply messages, including the answer to * the call just made above. */ for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) { /* In the meantime, the process may have been killed by a * signal (e.g. if a lethal pending signal was unblocked) * without the PM realizing it. If the slot is no longer in * use or just a zombie, don't try to reply. */ if ((rmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) == (REPLY | IN_USE)) { s=sendnb(rmp->mp_endpoint, &rmp->mp_reply); if (s != OK) { printf("PM can't reply to %d (%s): %d\n", rmp->mp_endpoint, rmp->mp_name, s); } rmp->mp_flags &= ~REPLY; } } } return(OK); }