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 PMEXEC_FLAGS m1_i3 /* PMEF_* */
|
||||||
|
|
||||||
#define PMEF_AUXVECTORS 20
|
#define PMEF_AUXVECTORS 20
|
||||||
|
#define PMEF_EXECNAMELEN1 256
|
||||||
#define PMEF_AUXVECTORSPACE 0x01 /* space for PMEF_AUXVECTORS on stack */
|
#define PMEF_AUXVECTORSPACE 0x01 /* space for PMEF_AUXVECTORS on stack */
|
||||||
|
#define PMEF_EXECNAMESPACE1 0x02 /* space for PMEF_EXECNAMELEN1 execname */
|
||||||
|
|
||||||
/* Flags for PR_FORK_FLAGS. */
|
/* Flags for PR_FORK_FLAGS. */
|
||||||
#define PFF_VMINHIBIT 0x01 /* Don't schedule until release by VM. */
|
#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 **vp;
|
||||||
char *sp;
|
char *sp;
|
||||||
size_t argc;
|
size_t argc;
|
||||||
|
int extra;
|
||||||
int vectors;
|
int vectors;
|
||||||
size_t frame_size;
|
size_t frame_size;
|
||||||
size_t string_off;
|
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) +
|
vectors = sizeof(argc) + sizeof(*ap) + sizeof(*ep) +
|
||||||
sizeof(AuxInfo) * PMEF_AUXVECTORS;
|
sizeof(AuxInfo) * PMEF_AUXVECTORS;
|
||||||
frame_size+= vectors;
|
extra = vectors + PMEF_EXECNAMELEN1;
|
||||||
string_off+= vectors;
|
frame_size+= extra;
|
||||||
|
string_off+= extra;
|
||||||
|
|
||||||
/* Align. */
|
/* Align. */
|
||||||
frame_size= (frame_size + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
|
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_p1 = (char *) __UNCONST(path);
|
||||||
m.m1_p2 = frame;
|
m.m1_p2 = frame;
|
||||||
|
|
||||||
/* Tell PM/VFS we have left space for the aux vectors */
|
/* Tell PM/VFS we have left space for the aux vectors
|
||||||
m.PMEXEC_FLAGS = PMEF_AUXVECTORSPACE;
|
* and executable name
|
||||||
|
*/
|
||||||
|
m.PMEXEC_FLAGS = PMEF_AUXVECTORSPACE | PMEF_EXECNAMESPACE1;
|
||||||
|
|
||||||
(void) _syscall(PM_PROC_NR, EXEC, &m);
|
(void) _syscall(PM_PROC_NR, EXEC, &m);
|
||||||
|
|
||||||
|
|
|
@ -73,9 +73,6 @@ static int mib[3][2] = {
|
||||||
static size_t
|
static size_t
|
||||||
expand(char *buf, const char *execname, int what, size_t bl)
|
expand(char *buf, const char *execname, int what, size_t bl)
|
||||||
{
|
{
|
||||||
#ifdef __minix
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
const char *p, *ep;
|
const char *p, *ep;
|
||||||
char *bp = buf;
|
char *bp = buf;
|
||||||
size_t len;
|
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);
|
xerr(1, "bad execname `%s' in AUX vector", execname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef __minix
|
||||||
case 3: /* OSNAME */
|
case 3: /* OSNAME */
|
||||||
case 4: /* OSREL */
|
case 4: /* OSREL */
|
||||||
case 5: /* PLATFORM */
|
case 5: /* PLATFORM */
|
||||||
|
@ -103,6 +101,7 @@ expand(char *buf, const char *execname, int what, size_t bl)
|
||||||
}
|
}
|
||||||
ep = (p = name) + len - 1;
|
ep = (p = name) + len - 1;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +110,6 @@ expand(char *buf, const char *execname, int what, size_t bl)
|
||||||
*bp++ = *p++, bl--;
|
*bp++ = *p++, bl--;
|
||||||
|
|
||||||
return bp - buf;
|
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_aout(struct exec_info *execi);
|
||||||
static int load_elf(struct exec_info *execi);
|
static int load_elf(struct exec_info *execi);
|
||||||
static int stack_prepare_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);
|
static int map_header(struct exec_info *execi);
|
||||||
|
|
||||||
#define PTRSIZE sizeof(char *) /* Size of pointers in argv[] and envp[]. */
|
#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 */
|
/* Array of loaders for different object file formats */
|
||||||
typedef int (*exechook_t)(struct exec_info *execpackage);
|
typedef int (*exechook_t)(struct exec_info *execpackage);
|
||||||
typedef int (*stackhook_t)(struct exec_info *execi, char *curstack,
|
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 {
|
struct exec_loaders {
|
||||||
exechook_t load_object; /* load executable into memory */
|
exechook_t load_object; /* load executable into memory */
|
||||||
stackhook_t setup_stack; /* prepare stack before argc and argv push */
|
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);
|
FAILCHECK(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remember it */
|
||||||
|
strcpy(execi.execname, finalexec);
|
||||||
|
|
||||||
/* The executable we need to execute first (loader)
|
/* The executable we need to execute first (loader)
|
||||||
* is in elf_interpreter, and has to be in fullpath to
|
* is in elf_interpreter, and has to be in fullpath to
|
||||||
* be looked up
|
* be looked up
|
||||||
|
@ -306,11 +309,10 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
|
||||||
*pc = execi.pc;
|
*pc = execi.pc;
|
||||||
|
|
||||||
/* call a stack-setup function if this executable type wants it */
|
/* call a stack-setup function if this executable type wants it */
|
||||||
vsp = execi.stack_top;
|
vsp = execi.stack_top - frame_len;
|
||||||
if(makestack) FAILCHECK(makestack(&execi, mbuf, &frame_len, &extrabase));
|
if(makestack) FAILCHECK(makestack(&execi, mbuf, &frame_len, &vsp, &extrabase));
|
||||||
|
|
||||||
/* Patch up stack and copy it from VFS to new core image. */
|
/* Patch up stack and copy it from VFS to new core image. */
|
||||||
vsp -= frame_len;
|
|
||||||
patch_ptr(mbuf, vsp + extrabase);
|
patch_ptr(mbuf, vsp + extrabase);
|
||||||
FAILCHECK(sys_datacopy(SELF, (vir_bytes) mbuf, proc_e, (vir_bytes) vsp,
|
FAILCHECK(sys_datacopy(SELF, (vir_bytes) mbuf, proc_e, (vir_bytes) vsp,
|
||||||
(phys_bytes)frame_len));
|
(phys_bytes)frame_len));
|
||||||
|
@ -390,9 +392,10 @@ static int load_aout(struct exec_info *execi)
|
||||||
return(r);
|
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;
|
Elf_Ehdr *elf_header;
|
||||||
int nulls;
|
int nulls;
|
||||||
char **mysp = (char **) frame,
|
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)
|
if(*framelen + extrabytes >= ARG_MAX)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
*framelen += extrabytes;
|
*framelen += extrabytes;
|
||||||
|
*newsp -= extrabytes;
|
||||||
*extrabase += extrabytes;
|
*extrabase += extrabytes;
|
||||||
memmove(f+extrabytes, f, remain);
|
memmove(f+extrabytes, f, remain);
|
||||||
memset(f, 0, extrabytes);
|
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_PAGESZ, PAGE_SIZE);
|
||||||
AUXINFO(AT_EXECFD, execi->elf_main_fd);
|
AUXINFO(AT_EXECFD, execi->elf_main_fd);
|
||||||
|
|
||||||
|
/* This is where we add the AT_NULL */
|
||||||
|
term = a;
|
||||||
|
|
||||||
/* Always terminate with AT_NULL */
|
/* Always terminate with AT_NULL */
|
||||||
AUXINFO(AT_NULL, 0);
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct exec_info {
|
||||||
vir_bytes elf_phdr; /* Program header location */
|
vir_bytes elf_phdr; /* Program header location */
|
||||||
vir_bytes elf_base; /* Userland addr load address */
|
vir_bytes elf_base; /* Userland addr load address */
|
||||||
int elf_main_fd; /* Dyn: FD of main program execuatble */
|
int elf_main_fd; /* Dyn: FD of main program execuatble */
|
||||||
|
char execname[PATH_MAX]; /* Full executable invocation */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !_VFS_EXEC_H_ */
|
#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;
|
stack_frame_len = (size_t) job_m_in.PM_FRAME_LEN;
|
||||||
|
|
||||||
r = pm_exec(proc_e, exec_path, exec_path_len, stack_frame,
|
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 */
|
/* Reply status to PM */
|
||||||
m_out.m_type = PM_EXEC_REPLY;
|
m_out.m_type = PM_EXEC_REPLY;
|
||||||
|
|
Loading…
Reference in a new issue