diff options
author | Andreas Schwab <schwab@redhat.com> | 2010-01-20 17:34:29 +0100 |
---|---|---|
committer | Andreas Schwab <schwab@redhat.com> | 2010-01-20 17:34:29 +0100 |
commit | f0dfc72f9d9bae2e8b210113ca2c4a4428d4cb5b (patch) | |
tree | f7454314d1fe7c613ecded2a524004fff3942593 /elf | |
parent | 1795b735237206f4798e2ff831327521e14dde2c (diff) | |
parent | e3b7670be21d6992e3ca9ee1ad3a5d08eb3a24c9 (diff) | |
download | glibc-f0dfc72f9d9bae2e8b210113ca2c4a4428d4cb5b.tar.gz glibc-f0dfc72f9d9bae2e8b210113ca2c4a4428d4cb5b.tar.xz glibc-f0dfc72f9d9bae2e8b210113ca2c4a4428d4cb5b.zip |
Merge remote branch 'origin/master' into fedora/master
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-open.c | 9 | ||||
-rw-r--r-- | elf/dl-sysdep.c | 10 | ||||
-rw-r--r-- | elf/dynamic-link.h | 15 | ||||
-rw-r--r-- | elf/elf.h | 6 | ||||
-rw-r--r-- | elf/rtld.c | 41 |
5 files changed, 56 insertions, 25 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/dynamic-link.h b/elf/dynamic-link.h index c34cbcd43b..6d7e14282f 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -103,6 +103,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) { ElfW(Dyn) *dyn = l->l_ld; ElfW(Dyn) **info; +#if __ELF_NATIVE_CLASS == 32 + typedef Elf32_Word d_tag_utype; +#elif __ELF_NATIVE_CLASS == 64 + typedef Elf64_Xword d_tag_utype; +#endif #ifndef RTLD_BOOTSTRAP if (dyn == NULL) @@ -113,20 +118,20 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) while (dyn->d_tag != DT_NULL) { - if (dyn->d_tag < DT_NUM) + if ((d_tag_utype) dyn->d_tag < DT_NUM) info[dyn->d_tag] = dyn; else if (dyn->d_tag >= DT_LOPROC && dyn->d_tag < DT_LOPROC + DT_THISPROCNUM) info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; - else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) + else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) info[VERSYMIDX (dyn->d_tag)] = dyn; - else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) + else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM] = dyn; - else if ((Elf32_Word) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) + else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn; - else if ((Elf32_Word) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) + else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; ++dyn; diff --git a/elf/elf.h b/elf/elf.h index 1bc8ef3489..8af7c177ce 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -2493,6 +2493,12 @@ typedef Elf32_Addr Elf32_Conflict; /* Keep this the last entry. */ #define R_SH_NUM 256 +/* S/390 specific definitions. */ + +/* Valid values for the e_flags field. */ + +#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ + /* Additional s390 relocs */ #define R_390_NONE 0 /* No reloc. */ 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 |