This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch, master, updated. glibc-2.11-144-g7760ccc
- From: drepper at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 15 Jan 2010 17:11:06 -0000
- Subject: GNU C Library master sources branch, master, updated. glibc-2.11-144-g7760ccc
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, master has been updated
via 7760ccced8883571bc00b42ed29384381d1413a5 (commit)
via 3a56ea26730755076cb5bc1d07727c7a4fcb8fd7 (commit)
from 5306d3613a3e71d8ede6529e858e2398223ac3da (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7760ccced8883571bc00b42ed29384381d1413a5
commit 7760ccced8883571bc00b42ed29384381d1413a5
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
Date: Fri Jan 15 09:10:44 2010 -0800
/390: Add runtime check for the highgprs kernel feature.
diff --git a/elf/elf.h b/elf/elf.h
index 1bc8ef3..8af7c17 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/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 251a5f6..415b388 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -27,6 +27,7 @@
#include <sys/param.h>
#include <string.h>
#include <link.h>
+#include <sysdeps/s390/dl-procinfo.h>
/* This is an older, now obsolete value. */
#define EM_S390_OLD 0xA390
@@ -35,6 +36,12 @@
static inline int
elf_machine_matches_host (const Elf32_Ehdr *ehdr)
{
+ /* Check if the kernel provides the high gpr facility if needed by
+ the binary. */
+ if ((ehdr->e_flags & EF_S390_HIGH_GPRS)
+ && !(GLRO (dl_hwcap) & HWCAP_S390_HIGH_GPRS))
+ return 0;
+
return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
&& ehdr->e_ident[EI_CLASS] == ELFCLASS32;
}
diff --git a/sysdeps/s390/s390-32/elf/start.S b/sysdeps/s390/s390-32/elf/start.S
index f729010..066f7f0 100644
--- a/sysdeps/s390/s390-32/elf/start.S
+++ b/sysdeps/s390/s390-32/elf/start.S
@@ -59,6 +59,88 @@
.globl _start
.type _start,@function
_start:
+ /* Check if the kernel provides highgprs facility if needed by
+ the binary. */
+
+ lr %r6,%r15
+ la %r6,4(%r6) /* Skip the argument counter. */
+
+.L11: l %r5,0(%r6) /* Skip the argument vector. */
+ la %r6,4(%r6)
+ ltr %r5,%r5
+ jne .L11
+
+.L12: l %r5,0(%r6) /* Skip the environment vector. */
+ la %r6,4(%r6)
+ ltr %r5,%r5
+ jne .L12
+
+ /* Obtain the needed values from the auxiliary vector. */
+
+ lhi %r7,16 /* AT_HWCAP */
+ lhi %r8,3 /* AT_PHDR */
+ lhi %r9,5 /* AT_PHNUM */
+ lhi %r2,4 /* AT_PHENT */
+.L13: l %r5,0(%r6)
+ clr %r5,%r7
+ jne .L15
+ l %r10,4(%r6) /* r10 = AT_HWCAP value. */
+.L15: clr %r5,%r8
+ jne .L16
+ l %r11,4(%r6) /* r11 = AT_PHDR value. */
+.L16: clr %r5,%r9
+ jne .L17
+ l %r12,4(%r6) /* r12 = AT_PHNUM value. */
+.L17: clr %r5,%r2
+ jne .L18
+ l %r0,4(%r6) /* r0 = AT_PHENT value. */
+.L18: ltr %r5,%r5
+ la %r6,8(%r6)
+ jnz .L13
+
+ /* Locate the ELF header by looking for the first PT_LOAD
+ segment with a p_offset of zero. */
+
+ lr %r4,%r11 /* Backup AT_PHDR. */
+ lhi %r7,1 /* PT_LOAD id */
+ lhi %r8,0
+.L19: cl %r7,0(%r4) /* p_type == PT_LOAD? */
+ jne .L20
+ cl %r8,4(%r4) /* p_offset == 0? */
+ jne .L20
+ l %r9,8(%r4) /* r9 = p_vaddr <- ELF header address */
+ j .L24
+.L20: alr %r4,%r0 /* r4 += AT_PHENT value */
+ brct %r12,.L19
+
+ j .+2 /* Trap, there must be such a phdr. */
+
+.L24: lr %r4,%r11 /* Backup AT_PHDR. */
+ lhi %r2,6 /* PT_PHDR id */
+.L23: cl %r2,0(%r4)
+ jne .L22
+ l %r3,8(%r4) /* r3 = PT_PHDR p_vaddr */
+ j .L25
+.L22: alr %r4,%r0 /* r4 += AT_PHENT value */
+ brct %r12,.L23
+
+ ltr %r9,%r9 /* Load address == 0? */
+ jz .L14 /* No checking for PIE without PT_PHDR. */
+ j .L21
+
+.L25: clr %r3,%r11 /* PT_PHDR p_vaddr == AT_PHDR? */
+ je .L21
+ lr %r9,%r11
+ slr %r9,%r3 /* elf_header_addr = AT_PHDR - PT_PHDR.p_vaddr */
+
+.L21: l %r5,36(%r9) /* Load the e_flags field. */
+ tml %r5,1
+ jz .L14 /* Binary does not require highgprs facility. */
+
+ tml %r10,512 /* Check the AT_HWCAP value. */
+ jz 2 /* Trap if no highgprs facility available. */
+.L14:
+
/* Setup pointer to literal pool of _start */
basr %r13,0
.L0: ahi %r13,.Llit-.L0
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3a56ea26730755076cb5bc1d07727c7a4fcb8fd7
commit 3a56ea26730755076cb5bc1d07727c7a4fcb8fd7
Author: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
Date: Fri Jan 15 09:09:35 2010 -0800
ld.so: Adjust the auxv if ld.so is directly invoked.
If a binary gets invoked by passing it as argument to ld.so the stack
still holds the auxiliary vector of ld.so when entering the _start
routine of the executable. So the invocation via ld.so is not fully
transparent to the executable. This causes problems if the executable
wants to scan the auxv itself.
diff --git a/ChangeLog b/ChangeLog
index 1e766bd..dbfd864 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-01-13 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf/dl-sysdep.c (_dl_sysdep_start): Added the auxv parameter to
+ dl_main.
+ * elf/dl-open.c (_dl_sysdep_start): Likewise..
+ * sysdeps/generic/ldsodefs.h (_dl_sysdep_start): Likewise.
+ * elf/rtld.c (dl_main): Added new parameter auxv. Adjust the
+ AT_PHDR, AT_PHNUM and AT_ENTRY fields if the ld.so is directly
+ started.
+
2010-01-14 Ulrich Drepper <drepper@redhat.com>
[BZ #11027]
diff --git a/elf/dl-open.c b/elf/dl-open.c
index e920c77..754a263 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 49c5dfb..5507e57 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 55b84c3..3afb997 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
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index e18e60f..230c39a 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1,5 +1,5 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects.
- Copyright (C) 1995-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1995-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
@@ -1015,7 +1015,8 @@ extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep,
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))
attribute_hidden;
extern void _dl_sysdep_start_cleanup (void)
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 10 +++++
elf/dl-open.c | 9 ++--
elf/dl-sysdep.c | 10 ++--
elf/elf.h | 6 +++
elf/rtld.c | 41 +++++++++++++-----
sysdeps/generic/ldsodefs.h | 5 +-
sysdeps/s390/s390-32/dl-machine.h | 7 +++
sysdeps/s390/s390-32/elf/start.S | 82 +++++++++++++++++++++++++++++++++++++
8 files changed, 148 insertions(+), 22 deletions(-)
hooks/post-receive
--
GNU C Library master sources