]> Zhao Yanbai Git Server - minix.git/commitdiff
AT_SUN_EXECNAME support
authorBen Gras <ben@minix3.org>
Wed, 18 Apr 2012 14:32:38 +0000 (16:32 +0200)
committerBen Gras <ben@minix3.org>
Thu, 26 Apr 2012 11:32:39 +0000 (13:32 +0200)
. 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

include/minix/com.h
lib/libc/sys-minix/execve.c
libexec/ld.elf_so/expand.c
servers/vfs/exec.c
servers/vfs/exec.h
servers/vfs/main.c

index 3a95f6fd1555e34d94c7edbf64d06190b0e19688..68eff5e879094f6075b0afabba11034ef53dd164 100644 (file)
 #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. */
index 06b5d1e45f58a8a6d90d7d8114a5b80ec5455eae..dcb84373c613d0a9be4da288efefcbee6424d377 100644 (file)
@@ -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);
 
index 9cd0b55644f9ee0d66bc69c36299552a88456591..88503201d389bf5975af781ac4e9220f91f795ae 100644 (file)
@@ -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
 }
                
 
index 3898588726e49a1817e614f6a2e18f2ebea8797d..87fe6704a055f26ac0ddf1ac863f9d9105332064 100644 (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_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;
 }
 
index 63dfa37b072d1d393fac5c8373a7647c8ab997e1..11dc85983b5fea2c3025a9ee75adf99c57a60af4 100644 (file)
@@ -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_ */
index ab17a32897bfc5435e14f9d7ca9fb1a07fbad391..eb752d0eb2d6213bd0373c7b73b32a7154b33511 100644 (file)
@@ -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;