diff --git a/include/minix/com.h b/include/minix/com.h index 3a95f6fd1..68eff5e87 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -546,7 +546,9 @@ #define PMEXEC_FLAGS m1_i3 /* PMEF_* */ #define PMEF_AUXVECTORS 20 +#define PMEF_EXECNAMELEN1 256 #define PMEF_AUXVECTORSPACE 0x01 /* space for PMEF_AUXVECTORS on stack */ +#define PMEF_EXECNAMESPACE1 0x02 /* space for PMEF_EXECNAMELEN1 execname */ /* Flags for PR_FORK_FLAGS. */ #define PFF_VMINHIBIT 0x01 /* Don't schedule until release by VM. */ diff --git a/lib/libc/sys-minix/execve.c b/lib/libc/sys-minix/execve.c index 06b5d1e45..dcb84373c 100644 --- a/lib/libc/sys-minix/execve.c +++ b/lib/libc/sys-minix/execve.c @@ -24,6 +24,7 @@ int execve(const char *path, char * const *argv, char * const *envp) char **vp; char *sp; size_t argc; + int extra; int vectors; size_t frame_size; size_t string_off; @@ -63,8 +64,9 @@ int execve(const char *path, char * const *argv, char * const *envp) */ vectors = sizeof(argc) + sizeof(*ap) + sizeof(*ep) + sizeof(AuxInfo) * PMEF_AUXVECTORS; - frame_size+= vectors; - string_off+= vectors; + extra = vectors + PMEF_EXECNAMELEN1; + frame_size+= extra; + string_off+= extra; /* Align. */ frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1); @@ -116,8 +118,10 @@ int execve(const char *path, char * const *argv, char * const *envp) m.m1_p1 = (char *) __UNCONST(path); m.m1_p2 = frame; - /* Tell PM/VFS we have left space for the aux vectors */ - m.PMEXEC_FLAGS = PMEF_AUXVECTORSPACE; + /* Tell PM/VFS we have left space for the aux vectors + * and executable name + */ + m.PMEXEC_FLAGS = PMEF_AUXVECTORSPACE | PMEF_EXECNAMESPACE1; (void) _syscall(PM_PROC_NR, EXEC, &m); diff --git a/libexec/ld.elf_so/expand.c b/libexec/ld.elf_so/expand.c index 9cd0b5564..88503201d 100644 --- a/libexec/ld.elf_so/expand.c +++ b/libexec/ld.elf_so/expand.c @@ -73,9 +73,6 @@ static int mib[3][2] = { static size_t expand(char *buf, const char *execname, int what, size_t bl) { -#ifdef __minix - return 0; -#else const char *p, *ep; char *bp = buf; size_t len; @@ -93,6 +90,7 @@ expand(char *buf, const char *execname, int what, size_t bl) xerr(1, "bad execname `%s' in AUX vector", execname); break; +#ifndef __minix case 3: /* OSNAME */ case 4: /* OSREL */ case 5: /* PLATFORM */ @@ -103,6 +101,7 @@ expand(char *buf, const char *execname, int what, size_t bl) } ep = (p = name) + len - 1; break; +#endif default: return 0; } @@ -111,7 +110,6 @@ expand(char *buf, const char *execname, int what, size_t bl) *bp++ = *p++, bl--; return bp - buf; -#endif } diff --git a/servers/vfs/exec.c b/servers/vfs/exec.c index 389858872..87fe6704a 100644 --- a/servers/vfs/exec.c +++ b/servers/vfs/exec.c @@ -58,7 +58,7 @@ static int read_seg(struct vnode *vp, off_t off, int proc_e, int seg, static int load_aout(struct exec_info *execi); static int load_elf(struct exec_info *execi); static int stack_prepare_elf(struct exec_info *execi, - char *curstack, size_t *frame_len, int *extrabase); + char *curstack, size_t *frame_len, vir_bytes *vsp, int *extrabase); static int map_header(struct exec_info *execi); #define PTRSIZE sizeof(char *) /* Size of pointers in argv[] and envp[]. */ @@ -66,7 +66,7 @@ static int map_header(struct exec_info *execi); /* Array of loaders for different object file formats */ typedef int (*exechook_t)(struct exec_info *execpackage); typedef int (*stackhook_t)(struct exec_info *execi, char *curstack, - size_t *frame_len, int *extrabase); + size_t *frame_len, vir_bytes *, int *extrabase); struct exec_loaders { exechook_t load_object; /* load executable into memory */ stackhook_t setup_stack; /* prepare stack before argc and argv push */ @@ -283,6 +283,9 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len, FAILCHECK(r); } + /* Remember it */ + strcpy(execi.execname, finalexec); + /* The executable we need to execute first (loader) * is in elf_interpreter, and has to be in fullpath to * be looked up @@ -306,11 +309,10 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len, *pc = execi.pc; /* call a stack-setup function if this executable type wants it */ - vsp = execi.stack_top; - if(makestack) FAILCHECK(makestack(&execi, mbuf, &frame_len, &extrabase)); + vsp = execi.stack_top - frame_len; + if(makestack) FAILCHECK(makestack(&execi, mbuf, &frame_len, &vsp, &extrabase)); /* Patch up stack and copy it from VFS to new core image. */ - vsp -= frame_len; patch_ptr(mbuf, vsp + extrabase); FAILCHECK(sys_datacopy(SELF, (vir_bytes) mbuf, proc_e, (vir_bytes) vsp, (phys_bytes)frame_len)); @@ -390,9 +392,10 @@ static int load_aout(struct exec_info *execi) return(r); } -static int stack_prepare_elf(struct exec_info *execi, char *frame, size_t *framelen, int *extrabase) +static int stack_prepare_elf(struct exec_info *execi, char *frame, size_t *framelen, + vir_bytes *newsp, int *extrabase) { - AuxInfo *a; + AuxInfo *a, *term; Elf_Ehdr *elf_header; int nulls; char **mysp = (char **) frame, @@ -438,6 +441,7 @@ static int stack_prepare_elf(struct exec_info *execi, char *frame, size_t *frame if(*framelen + extrabytes >= ARG_MAX) return ENOMEM; *framelen += extrabytes; + *newsp -= extrabytes; *extrabase += extrabytes; memmove(f+extrabytes, f, remain); memset(f, 0, extrabytes); @@ -457,9 +461,34 @@ static int stack_prepare_elf(struct exec_info *execi, char *frame, size_t *frame AUXINFO(AT_PAGESZ, PAGE_SIZE); AUXINFO(AT_EXECFD, execi->elf_main_fd); + /* This is where we add the AT_NULL */ + term = a; + /* Always terminate with AT_NULL */ AUXINFO(AT_NULL, 0); + /* Empty space starts here, if any. */ + if((execi->userflags & PMEF_EXECNAMESPACE1) + && strlen(execi->execname) < PMEF_EXECNAMELEN1) { + char *spacestart; + vir_bytes userp; + + /* Make space for the real closing AT_NULL entry. */ + AUXINFO(AT_NULL, 0); + + /* Empty space starts here; we can put the name here. */ + spacestart = (char *) a; + strcpy(spacestart, execi->execname); + + /* What will the address of the string for the user be */ + userp = *newsp + (spacestart-frame); + + /* Move back to where the AT_NULL is */ + a = term; + AUXINFO(AT_SUN_EXECNAME, userp); + AUXINFO(AT_NULL, 0); + } + return OK; } diff --git a/servers/vfs/exec.h b/servers/vfs/exec.h index 63dfa37b0..11dc85983 100644 --- a/servers/vfs/exec.h +++ b/servers/vfs/exec.h @@ -23,6 +23,7 @@ struct exec_info { vir_bytes elf_phdr; /* Program header location */ vir_bytes elf_base; /* Userland addr load address */ int elf_main_fd; /* Dyn: FD of main program execuatble */ + char execname[PATH_MAX]; /* Full executable invocation */ }; #endif /* !_VFS_EXEC_H_ */ diff --git a/servers/vfs/main.c b/servers/vfs/main.c index ab17a3289..eb752d0eb 100644 --- a/servers/vfs/main.c +++ b/servers/vfs/main.c @@ -807,7 +807,7 @@ static void service_pm_postponed(void) stack_frame_len = (size_t) job_m_in.PM_FRAME_LEN; r = pm_exec(proc_e, exec_path, exec_path_len, stack_frame, - stack_frame_len, &pc, &newsp, m_in.PM_EXECFLAGS); + stack_frame_len, &pc, &newsp, job_m_in.PM_EXECFLAGS); /* Reply status to PM */ m_out.m_type = PM_EXEC_REPLY;