AT_SUN_EXECNAME support
. vfs: pass execname in aux vectors . ld.elf_so: use this to expand $ORIGIN . this requires the executable to reserve more space at exec() calling time
This commit is contained in:
parent
b41df2eb0d
commit
755102d67f
6 changed files with 50 additions and 16 deletions
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue