diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-open.c | 9 | ||||
-rw-r--r-- | elf/dl-sysdep.c | 10 | ||||
-rw-r--r-- | elf/rtld.c | 41 |
3 files changed, 40 insertions, 20 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index e920c7738c..754a263fa1 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1,5 +1,5 @@ /* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996-2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1996-2007, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -40,7 +40,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, - ElfW(Addr) *user_entry)); + ElfW(Addr) *user_entry, + ElfW(auxv_t) *auxv)); weak_extern (BP_SYM (_dl_sysdep_start)) extern int __libc_multiple_libcs; /* Defined in init-first.c. */ @@ -346,8 +347,8 @@ dl_open_worker (void *a) { /* If this here is the shared object which we want to profile make sure the profile is started. We can find out whether - this is necessary or not by observing the `_dl_profile_map' - variable. If was NULL but is not NULL afterwars we must + this is necessary or not by observing the `_dl_profile_map' + variable. If was NULL but is not NULL afterwars we must start the profiling. */ struct link_map *old_profile_map = GL(dl_profile_map); diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c index 49c5dfb27d..5507e57b96 100644 --- a/elf/dl-sysdep.c +++ b/elf/dl-sysdep.c @@ -85,7 +85,7 @@ void *_dl_random attribute_relro = NULL; ElfW(Addr) _dl_sysdep_start (void **start_argptr, void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, - ElfW(Addr) *user_entry)) + ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)) { const ElfW(Phdr) *phdr = NULL; ElfW(Word) phnum = 0; @@ -241,7 +241,7 @@ _dl_sysdep_start (void **start_argptr, if (__builtin_expect (INTUSE(__libc_enable_secure), 0)) __libc_check_standard_fds (); - (*dl_main) (phdr, phnum, &user_entry); + (*dl_main) (phdr, phnum, &user_entry, _dl_auxv); return user_entry; } @@ -511,9 +511,9 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, /* Fill in the information. This follows the following scheme (indeces from TEMP for four strings): entry #0: 0, 1, 2, 3 binary: 1111 - #1: 0, 1, 3 1101 - #2: 0, 2, 3 1011 - #3: 0, 3 1001 + #1: 0, 1, 3 1101 + #2: 0, 2, 3 1011 + #3: 0, 3 1001 This allows the representation of all possible combinations of capability names in the string. First generate the strings. */ result[1].str = result[0].str = cp = (char *) (result + *sz); diff --git a/elf/rtld.c b/elf/rtld.c index 55b84c3bf4..3afb997f85 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1,5 +1,5 @@ /* Run time dynamic linker. - Copyright (C) 1995-2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -182,7 +182,7 @@ extern struct rtld_global_ro _rtld_local_ro static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum, - ElfW(Addr) *user_entry); + ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv); /* These two variables cannot be moved into .data.rel.ro. */ static struct libname_list _dl_rtld_libname; @@ -882,7 +882,8 @@ static int version_info attribute_relro; static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum, - ElfW(Addr) *user_entry) + ElfW(Addr) *user_entry, + ElfW(auxv_t) *auxv) { const ElfW(Phdr) *ph; enum mode mode; @@ -927,6 +928,8 @@ dl_main (const ElfW(Phdr) *phdr, if (*user_entry == (ElfW(Addr)) ENTRY_POINT) { + ElfW(auxv_t) *av; + /* Ho ho. We are not the program interpreter! We are the program itself! This means someone ran ld.so as a command. Well, that might be convenient to do sometimes. We support it by @@ -1013,11 +1016,11 @@ of this helper program; chances are you did not intend to run this program.\n\ \n\ --list list all dependencies and how they are resolved\n\ --verify verify that given object really is a dynamically linked\n\ - object we can handle\n\ + object we can handle\n\ --library-path PATH use given PATH instead of content of the environment\n\ - variable LD_LIBRARY_PATH\n\ + variable LD_LIBRARY_PATH\n\ --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\ - in LIST\n\ + in LIST\n\ --audit LIST use objects named in LIST as auditors\n"); ++_dl_skip_args; @@ -1082,6 +1085,22 @@ of this helper program; chances are you did not intend to run this program.\n\ makes sense to free the old string first. */ main_map->l_name = (char *) ""; *user_entry = main_map->l_entry; + + /* Adjust the on-stack auxiliary vector so that it looks like the + binary was executed directly. */ + for (av = auxv; av->a_type != AT_NULL; av++) + switch (av->a_type) + { + case AT_PHDR: + av->a_un.a_val = phdr; + break; + case AT_PHNUM: + av->a_un.a_val = phnum; + break; + case AT_ENTRY: + av->a_un.a_val = *user_entry; + break; + } } else { @@ -2013,7 +2032,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); } - } + } #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) if (version_info) { @@ -2682,10 +2701,10 @@ process_envvars (enum mode *modep) while (*nextp != '\0'); if (__access ("/etc/suid-debug", F_OK) != 0) - { + { unsetenv ("MALLOC_CHECK_"); GLRO(dl_debug_mask) = 0; - } + } if (mode != normal) _exit (5); @@ -2752,7 +2771,7 @@ print_statistics (hp_timing_t *rtld_total_timep) } *wp = '\0'; _dl_debug_printf ("\ - time needed for relocation: %s (%s%%)\n", buf, pbuf); + time needed for relocation: %s (%s%%)\n", buf, pbuf); } #endif @@ -2815,7 +2834,7 @@ print_statistics (hp_timing_t *rtld_total_timep) } *wp = '\0'; _dl_debug_printf ("\ - time needed to load objects: %s (%s%%)\n", + time needed to load objects: %s (%s%%)\n", buf, pbuf); } #endif |