2003-04-22  Roland McGrath  <roland@redhat.com>

	* elf/elf.h (AT_SYSINFO_EHDR): New macro, replaces AT_SYSINFO_EH_FRAME.
	* sysdeps/generic/ldsodefs.h (struct rtld_global): Remove
	dl_sysinfo_eh_frame member, add dl_sysinfo_dso member instead.
	* elf/dl-support.c: Update defn.
	* sysdeps/generic/libc-start.c: Don't call __register_frame_info_bases.
	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start) [NEED_DL_SYSINFO]:
	Set GL(dl_sysinfo_dso) from AT_SYSINFO_EHDR.
	(_dl_show_auxv): Grok AT_SYSINFO_EHDR, not AT_SYSINFO_EH_FRAME.
	* elf/rtld.c (dl_main) [NEED_DL_SYSINFO]: If GL(dl_sysinfo_dso) is
	set, set up a link_map for the preloaded, prelinked object.
This commit is contained in:
Ulrich Drepper 2003-05-04 04:30:13 +00:00
parent 003f9e7223
commit f866314b89
6 changed files with 87 additions and 43 deletions

View File

@ -1,3 +1,16 @@
2003-04-22 Roland McGrath <roland@redhat.com>
* elf/elf.h (AT_SYSINFO_EHDR): New macro, replaces AT_SYSINFO_EH_FRAME.
* sysdeps/generic/ldsodefs.h (struct rtld_global): Remove
dl_sysinfo_eh_frame member, add dl_sysinfo_dso member instead.
* elf/dl-support.c: Update defn.
* sysdeps/generic/libc-start.c: Don't call __register_frame_info_bases.
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start) [NEED_DL_SYSINFO]:
Set GL(dl_sysinfo_dso) from AT_SYSINFO_EHDR.
(_dl_show_auxv): Grok AT_SYSINFO_EHDR, not AT_SYSINFO_EH_FRAME.
* elf/rtld.c (dl_main) [NEED_DL_SYSINFO]: If GL(dl_sysinfo_dso) is
set, set up a link_map for the preloaded, prelinked object.
2003-05-03 Roland McGrath <roland@redhat.com> 2003-05-03 Roland McGrath <roland@redhat.com>
* sysdeps/gnu/Makefile (generated): Append errlist-compat.c here, ... * sysdeps/gnu/Makefile (generated): Append errlist-compat.c here, ...

View File

@ -127,8 +127,8 @@ size_t _dl_phnum;
#ifdef NEED_DL_SYSINFO #ifdef NEED_DL_SYSINFO
/* Needed for improved syscall handling on at least x86/Linux. */ /* Needed for improved syscall handling on at least x86/Linux. */
uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT; uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
/* Address of the unwind info for the vsyscall page. */ /* Address of the ELF headers in the vsyscall page. */
uintptr_t _dl_sysinfo_eh_frame; const ElfW(Ehdr) *_dl_sysinfo_dso;
#endif #endif
/* During the program run we must not modify the global data of /* During the program run we must not modify the global data of

View File

@ -1069,6 +1069,48 @@ of this helper program; chances are you did not intend to run this program.\n\
assert (i == npreloads); assert (i == npreloads);
} }
#ifdef NEED_DL_SYSINFO
if (GL(dl_sysinfo_dso) != NULL)
{
/* We have a prelinked DSO preloaded by the system. */
GL(dl_sysinfo) = GL(dl_sysinfo_dso)->e_entry;
/* Do an abridged version of the work _dl_map_object_from_fd would do
to map in the object. It's already mapped and prelinked (and
better be, since it's read-only and so we couldn't relocate it).
We just want our data structures to describe it as if we had just
mapped and relocated it normally. */
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL);
if (__builtin_expect (l != NULL, 1))
{
l->l_phdr = ((const void *) GL(dl_sysinfo_dso)
+ GL(dl_sysinfo_dso)->e_phoff);
l->l_phnum = GL(dl_sysinfo_dso)->e_phnum;
for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
{
const ElfW(Phdr) *const ph = &l->l_phdr[i];
if (ph->p_type == PT_DYNAMIC)
{
l->l_ld = (void *) ph->p_vaddr;
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
break;
}
if (ph->p_type == PT_LOAD)
assert ((void *) ph->p_vaddr == GL(dl_sysinfo_dso));
}
elf_get_dynamic_info (l);
_dl_setup_hash (l);
l->l_relocated = 1;
/* Now that we have the info handy, use the DSO image's soname
so this object can be looked up by name. */
if (l->l_info[DT_SONAME] != NULL)
l->l_libname->name = ((char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
}
}
#endif
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
specified some libraries to load, these are inserted before the actual specified some libraries to load, these are inserted before the actual
dependencies in the executable's searchlist for symbol resolution. */ dependencies in the executable's searchlist for symbol resolution. */

View File

@ -139,8 +139,8 @@ _dl_sysdep_start (void **start_argptr,
case AT_SYSINFO: case AT_SYSINFO:
GL(dl_sysinfo) = av->a_un.a_val; GL(dl_sysinfo) = av->a_un.a_val;
break; break;
case AT_SYSINFO_EH_FRAME: case AT_SYSINFO_EHDR:
GL(dl_sysinfo_eh_frame) = av->a_un.a_val; GL(dl_sysinfo_dso) = av->a_un.a_ptr;
break; break;
#endif #endif
#ifdef DL_PLATFORM_AUXV #ifdef DL_PLATFORM_AUXV
@ -227,7 +227,7 @@ _dl_show_auxv (void)
{ {
static const struct static const struct
{ {
const char label[23]; const char label[20];
enum { dec, hex, str } form; enum { dec, hex, str } form;
} auxvars[] = } auxvars[] =
{ {
@ -251,8 +251,10 @@ _dl_show_auxv (void)
[AT_DCACHEBSIZE - 2] = { "AT_DCACHEBSIZE: 0x", hex }, [AT_DCACHEBSIZE - 2] = { "AT_DCACHEBSIZE: 0x", hex },
[AT_ICACHEBSIZE - 2] = { "AT_ICACHEBSIZE: 0x", hex }, [AT_ICACHEBSIZE - 2] = { "AT_ICACHEBSIZE: 0x", hex },
[AT_UCACHEBSIZE - 2] = { "AT_UCACHEBSIZE: 0x", hex }, [AT_UCACHEBSIZE - 2] = { "AT_UCACHEBSIZE: 0x", hex },
#ifdef DL_NEED_SYSINFO
[AT_SYSINFO - 2] = { "AT_SYSINFO: 0x", hex }, [AT_SYSINFO - 2] = { "AT_SYSINFO: 0x", hex },
[AT_SYSINFO_EH_FRAME - 2] = { "AT_SYSINFO_EH_FRAME: 0x", hex } [AT_SYSINFO_EHDR - 2] = { "AT_SYSINFO_EHDR: 0x", hex }
#endif
}; };
unsigned int idx = (unsigned int) (av->a_type - 2); unsigned int idx = (unsigned int) (av->a_type - 2);

View File

@ -395,8 +395,9 @@ struct rtld_global
/* Syscall handling improvements. This is very specific to x86. */ /* Syscall handling improvements. This is very specific to x86. */
EXTERN uintptr_t _dl_sysinfo; EXTERN uintptr_t _dl_sysinfo;
/* Address of the unwind info for the vsyscall page. */ /* The vsyscall page is a virtual DSO pre-mapped by the kernel.
EXTERN uintptr_t _dl_sysinfo_eh_frame; This points to its ELF header. */
EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso;
#endif #endif
#ifdef SHARED #ifdef SHARED

View File

@ -28,13 +28,6 @@ extern void __libc_init_first (int argc, char **argv, char **envp);
extern int __libc_multiple_libcs; extern int __libc_multiple_libcs;
extern void *__libc_stack_end; extern void *__libc_stack_end;
#ifdef NEED_DL_SYSINFO
# include "unwind-dw2-fde.h"
extern __typeof (__register_frame_info_bases)
INTUSE(__register_frame_info_bases);
static struct object eh_obj;
#endif
#include <tls.h> #include <tls.h>
#ifndef SHARED #ifndef SHARED
# include <dl-osinfo.h> # include <dl-osinfo.h>
@ -157,13 +150,6 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
__libc_check_standard_fds (); __libc_check_standard_fds ();
#endif #endif
#ifdef NEED_DL_SYSINFO
/* Register the kernel's unwind table. */
if (GL(dl_sysinfo_eh_frame) != 0)
INTUSE(__register_frame_info_bases) ((void *) GL(dl_sysinfo_eh_frame),
&eh_obj, 0, 0);
#endif
/* Register the destructor of the dynamic linker if there is any. */ /* Register the destructor of the dynamic linker if there is any. */
if (__builtin_expect (rtld_fini != NULL, 1)) if (__builtin_expect (rtld_fini != NULL, 1))
__cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL); __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);