Browse Source

[Pal, LibOS] Remove passing of ELF aux vectors from PAL to LibOS

Previously, PAL initialized a subset of ELF aux vectors on binary start
and passed them to LibOS. However, LibOS initializes ELF aux vectors on
its own, without consulting PAL's ones. This commit removes the ELF auxv
logic from PAL and simplifies logic in LibOS.
Dmitrii Kuvaiskii 4 years ago
parent
commit
4ddca71177

+ 4 - 0
LibOS/shim/include/shim_defs.h

@@ -37,4 +37,8 @@
 #define MIGRATE_SYSV_SEM            0
 #define MIGRATE_SYSV_MSG            1
 
+/* ELF aux vectors  */
+#define REQUIRED_ELF_AUXV           7   /* number of LibOS-supported vectors */
+#define REQUIRED_ELF_AUXV_SPACE     16  /* extra memory space (in bytes) */
+
 #endif /* _SHIM_DEFS_H_ */

+ 1 - 1
LibOS/shim/include/shim_thread.h

@@ -349,6 +349,6 @@ bool check_on_stack (struct shim_thread * cur_thread, void * mem)
 
 int init_stack (const char ** argv, const char ** envp,
                 int ** argcpp, const char *** argpp,
-                int nauxv, elf_auxv_t ** auxpp);
+                elf_auxv_t ** auxpp);
 
 #endif /* _SHIM_THREAD_H_ */

+ 1 - 1
LibOS/shim/include/shim_utils.h

@@ -215,7 +215,7 @@ int load_elf_interp (struct shim_handle * exec);
 int free_elf_interp (void);
 void execute_elf_object (struct shim_handle * exec,
                          int * argcp, const char ** argp,
-                         int nauxv, elf_auxv_t * auxp);
+                         elf_auxv_t * auxp);
 int remove_loaded_libraries (void);
 
 /* gdb debugging support */

+ 18 - 11
LibOS/shim/src/elf/shim_rtld.c

@@ -1563,21 +1563,15 @@ int register_library (const char * name, unsigned long load_address)
 
 void execute_elf_object (struct shim_handle * exec,
                          int * argcp, const char ** argp,
-                         int nauxv, ElfW(auxv_t) * auxp)
+                         ElfW(auxv_t) * auxp)
 {
     struct link_map * exec_map = __search_map_by_handle(exec);
     assert(exec_map);
-    assert((uintptr_t)argcp % 16 == 0);  // Stack should be aligned to 16 on entry point.
+    assert((uintptr_t)argcp % 16 == 0);  /* stack must be 16B-aligned */
     assert((void*)argcp + sizeof(long) == argp || argp == NULL);
 
-    /* random 16 bytes follows auxp */
-    ElfW(Addr) random = (ElfW(Addr))&auxp[7];
-    int ret = DkRandomBitsRead((PAL_PTR)random, 16);
-    if (ret < 0) {
-        debug("execute_elf_object: DkRandomBitsRead failed.\n");
-        DkThreadExit();
-    }
-
+    /* populate ELF aux vectors */
+    assert(REQUIRED_ELF_AUXV >= 7); /* stack allocated enough space */
     auxp[0].a_type = AT_PHDR;
     auxp[0].a_un.a_val = (__typeof(auxp[0].a_un.a_val)) exec_map->l_phdr;
     auxp[1].a_type = AT_PHNUM;
@@ -1589,8 +1583,21 @@ void execute_elf_object (struct shim_handle * exec,
     auxp[4].a_type = AT_BASE;
     auxp[4].a_un.a_val = interp_map ? interp_map->l_addr : 0;
     auxp[5].a_type = AT_RANDOM;
-    auxp[5].a_un.a_val = random;
+    auxp[5].a_un.a_val = 0; /* filled later */
     auxp[6].a_type = AT_NULL;
+    auxp[6].a_un.a_val = 0;
+
+    /* populate extra memory space for aux vector data */
+    assert(REQUIRED_ELF_AUXV_SPACE >= 16); /* stack allocated enough space */
+    ElfW(Addr) auxp_extra = (ElfW(Addr))&auxp[7];
+
+    ElfW(Addr) random = auxp_extra; /* random 16B for AT_RANDOM */
+    int ret = DkRandomBitsRead((PAL_PTR)random, 16);
+    if (ret < 0) {
+        debug("execute_elf_object: DkRandomBitsRead failed.\n");
+        DkThreadExit();
+    }
+    auxp[5].a_un.a_val = random;
 
     ElfW(Addr) entry = interp_map ? interp_map->l_entry : exec_map->l_entry;
 

+ 8 - 31
LibOS/shim/src/shim_init.c

@@ -286,8 +286,7 @@ void * allocate_stack (size_t size, size_t protect_size, bool user)
 }
 
 static int populate_user_stack (void * stack, size_t stack_size,
-                                int nauxv, elf_auxv_t ** auxpp,
-                                int ** argcpp,
+                                elf_auxv_t ** auxpp, int ** argcpp,
                                 const char *** argvp, const char *** envpp)
 {
     const int argc = **argcpp;
@@ -336,16 +335,9 @@ copy_envp:
     if (!new_envp)
         *(const char **) ALLOCATE_BOTTOM(sizeof(const char *)) = NULL;
 
-    if (nauxv) {
-        new_auxp = ALLOCATE_BOTTOM(sizeof(elf_auxv_t) * nauxv);
-        if (*auxpp)
-            memcpy(new_auxp, *auxpp, nauxv * sizeof(elf_auxv_t));
-    }
-
-    /* reserve at least 16 bytes on the stack to accommodate AT_RANDOM bytes
-     * later
-     */
-    ALLOCATE_TOP(16);
+    /* reserve space for ELF aux vectors, populated later by LibOS */
+    new_auxp = ALLOCATE_BOTTOM(REQUIRED_ELF_AUXV * sizeof(elf_auxv_t) +
+                               REQUIRED_ELF_AUXV_SPACE);
 
     /* x86_64 ABI requires 16 bytes alignment on stack on every function
        call. */
@@ -369,7 +361,7 @@ unsigned long sys_stack_size = 0;
 
 int init_stack (const char ** argv, const char ** envp,
                 int ** argcpp, const char *** argpp,
-                int nauxv, elf_auxv_t ** auxpp)
+                elf_auxv_t ** auxpp)
 {
     if (!sys_stack_size) {
         sys_stack_size = DEFAULT_SYS_STACK_SIZE;
@@ -393,8 +385,7 @@ int init_stack (const char ** argv, const char ** envp,
     if (initial_envp)
         envp = initial_envp;
 
-    int ret = populate_user_stack(stack, sys_stack_size,
-                                  nauxv, auxpp, argcpp, &argv, &envp);
+    int ret = populate_user_stack(stack, sys_stack_size, auxpp, argcpp, &argv, &envp);
     if (ret < 0)
         return ret;
 
@@ -546,18 +537,6 @@ struct shim_profile profile_root;
     } while (0)
 
 
-static elf_auxv_t* __process_auxv (elf_auxv_t * auxp)
-{
-    elf_auxv_t * av;
-
-    for (av = auxp; av->a_type != AT_NULL; av++)
-        switch (av->a_type) {
-            default: break;
-        }
-
-    return av + 1;
-}
-
 #ifdef PROFILE
 static void set_profile_enabled (const char ** envp)
 {
@@ -715,7 +694,6 @@ noreturn void* shim_init (int argc, void * args)
 
     /* call to figure out where the arguments are */
     FIND_ARG_COMPONENTS(args, argc, argv, envp, auxp);
-    int nauxv = __process_auxv(auxp) - auxp;
 
 #ifdef PROFILE
     set_profile_enabled(envp);
@@ -780,7 +758,7 @@ restore:
     RUN_INIT(init_mount);
     RUN_INIT(init_important_handles);
     RUN_INIT(init_async);
-    RUN_INIT(init_stack, argv, envp, &argcp, &argp, nauxv, &auxp);
+    RUN_INIT(init_stack, argv, envp, &argcp, &argp, &auxp);
     RUN_INIT(init_loader);
     RUN_INIT(init_ipc_helper);
     RUN_INIT(init_signal);
@@ -829,8 +807,7 @@ restore:
         restore_context(&cur_tcb->context);
 
     if (cur_thread->exec)
-        execute_elf_object(cur_thread->exec,
-                           argcp, argp, nauxv, auxp);
+        execute_elf_object(cur_thread->exec, argcp, argp, auxp);
     shim_do_exit(0);
 }
 

+ 2 - 7
LibOS/shim/src/sys/shim_exec.c

@@ -70,8 +70,6 @@ static int           new_argc;
 static int *         new_argcp;
 static elf_auxv_t *  new_auxp;
 
-#define REQUIRED_ELF_AUXV       6
-
 int init_brk_from_executable (struct shim_handle * exec);
 
 int shim_do_execve_rtld (struct shim_handle * hdl, const char ** argv,
@@ -112,8 +110,7 @@ int shim_do_execve_rtld (struct shim_handle * hdl, const char ** argv,
     for (const char ** a = argv ; *a ; a++, new_argc++);
 
     new_argcp = &new_argc;
-    if ((ret = init_stack(argv, envp, &new_argcp, &new_argp,
-                          REQUIRED_ELF_AUXV, &new_auxp)) < 0)
+    if ((ret = init_stack(argv, envp, &new_argcp, &new_argp, &new_auxp)) < 0)
         return ret;
 
     SAVE_PROFILE_INTERVAL(alloc_new_stack_for_exec);
@@ -197,9 +194,7 @@ retry_dump_vmas:
 #endif
 
     debug("execve: start execution\n");
-    execute_elf_object(cur_thread->exec, new_argcp, new_argp,
-                       REQUIRED_ELF_AUXV, new_auxp);
-
+    execute_elf_object(cur_thread->exec, new_argcp, new_argp, new_auxp);
     return 0;
 }
 

+ 6 - 20
Pal/src/db_rtld.c

@@ -1331,7 +1331,7 @@ void start_execution (const char * first_argument, const char ** arguments,
     ncookies++; /* for NULL-end */
 
     int cookiesz = sizeof(unsigned long int) * ncookies
-                      + sizeof(ElfW(auxv_t)) * 6 + 16
+                      + sizeof(ElfW(auxv_t)) * 1  /* only AT_NULL */
                       + sizeof(void *) * 4 + 16;
 
     unsigned long int * cookies = __alloca(cookiesz);
@@ -1349,26 +1349,12 @@ void start_execution (const char * first_argument, const char ** arguments,
         cookies[cnt++] = (unsigned long int) environs[i];
     cookies[cnt++] = 0;
 
+    /* NOTE: LibOS implements its own ELF aux vectors. Any info from host's
+     * aux vectors must be passed in PAL_CONTROL. Here we pass an empty list
+     * of aux vectors for sanity. */
     ElfW(auxv_t) * auxv = (ElfW(auxv_t) *) &cookies[cnt];
-    /* random 16 bytes follows auxp */
-    ElfW(Addr) random = (ElfW(Addr))&auxv[7];
-    int ret = DkRandomBitsRead((PAL_PTR)random, 16);
-    if (ret < 0)
-        INIT_FAIL(-ret, "start_execution: DkRandomBitsRead failed\n");
-
-    auxv[0].a_type = AT_PHDR;
-    auxv[0].a_un.a_val = exec_map ? (unsigned long) exec_map->l_phdr  : 0;
-    auxv[1].a_type = AT_PHNUM;
-    auxv[1].a_un.a_val = exec_map ? exec_map->l_phnum : 0;
-    auxv[2].a_type = AT_PAGESZ;
-    auxv[2].a_un.a_val = __pal_control.pagesize;
-    auxv[3].a_type = AT_ENTRY;
-    auxv[3].a_un.a_val = exec_map ? exec_map->l_entry : 0;
-    auxv[4].a_type = AT_BASE;
-    auxv[4].a_un.a_val = exec_map ? exec_map->l_addr  : 0;
-    auxv[5].a_type = AT_RANDOM;
-    auxv[5].a_un.a_val = random;
-    auxv[6].a_type = AT_NULL;
+    auxv[0].a_type = AT_NULL;
+    auxv[0].a_un.a_val = 0;
 
 #if PROFILING == 1
     __pal_control.startup_time = _DkSystemTimeQuery() - pal_state.start_time;