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:
Ben Gras 2012-04-18 16:32:38 +02:00
parent b41df2eb0d
commit 755102d67f
6 changed files with 50 additions and 16 deletions

View file

@ -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. */

View file

@ -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);

View file

@ -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
} }

View file

@ -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;
} }

View file

@ -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_ */

View file

@ -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;