This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: How to implement a kernel feature check in the crt* files?
Hi Roland,
I don't know exactly what you have in mind, but it sounds rather off to me.
There is nothing to "duplicate". There are a few known auxv entries that
refer to the loaded image, so ld.so needs to change those entries.
It seems to work for me with the attached patch. Is this what you had in mind?
Bye,
-Andreas-
Index: elf/dl-sysdep.c
===================================================================
*** elf/dl-sysdep.c.orig 2010-01-12 17:14:10.000000000 +0100
--- elf/dl-sysdep.c 2010-01-12 17:14:12.000000000 +0100
*************** void *_dl_random attribute_relro = NULL;
*** 84,90 ****
ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
! ElfW(Addr) *user_entry))
{
const ElfW(Phdr) *phdr = NULL;
ElfW(Word) phnum = 0;
--- 84,90 ----
ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
! ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
{
const ElfW(Phdr) *phdr = NULL;
ElfW(Word) phnum = 0;
*************** _dl_sysdep_start (void **start_argptr,
*** 240,246 ****
if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
__libc_check_standard_fds ();
! (*dl_main) (phdr, phnum, &user_entry);
return user_entry;
}
--- 240,246 ----
if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
__libc_check_standard_fds ();
! (*dl_main) (phdr, phnum, &user_entry, _dl_auxv);
return user_entry;
}
Index: elf/rtld.c
===================================================================
*** elf/rtld.c.orig 2010-01-12 17:14:10.000000000 +0100
--- elf/rtld.c 2010-01-12 17:14:31.000000000 +0100
*************** extern struct rtld_global_ro _rtld_local
*** 182,188 ****
static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
! ElfW(Addr) *user_entry);
/* These two variables cannot be moved into .data.rel.ro. */
static struct libname_list _dl_rtld_libname;
--- 182,188 ----
static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
! 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;
*************** static int version_info attribute_relro;
*** 882,888 ****
static void
dl_main (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! ElfW(Addr) *user_entry)
{
const ElfW(Phdr) *ph;
enum mode mode;
--- 882,889 ----
static void
dl_main (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! ElfW(Addr) *user_entry,
! ElfW(auxv_t) *auxv)
{
const ElfW(Phdr) *ph;
enum mode mode;
*************** dl_main (const ElfW(Phdr) *phdr,
*** 927,932 ****
--- 928,935 ----
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
*************** of this helper program; chances are you
*** 1082,1087 ****
--- 1085,1104 ----
makes sense to free the old string first. */
main_map->l_name = (char *) "";
*user_entry = main_map->l_entry;
+
+ 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
{
Index: elf/dl-open.c
===================================================================
*** elf/dl-open.c.orig 2010-01-12 17:14:10.000000000 +0100
--- elf/dl-open.c 2010-01-12 17:14:12.000000000 +0100
***************
*** 40,46 ****
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! ElfW(Addr) *user_entry));
weak_extern (BP_SYM (_dl_sysdep_start))
extern int __libc_multiple_libcs; /* Defined in init-first.c. */
--- 40,47 ----
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! 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. */
Index: sysdeps/generic/ldsodefs.h
===================================================================
*** sysdeps/generic/ldsodefs.h.orig 2010-01-12 17:14:10.000000000 +0100
--- sysdeps/generic/ldsodefs.h 2010-01-12 17:14:12.000000000 +0100
*************** extern void *_dl_sysdep_read_whole_file
*** 1015,1021 ****
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! ElfW(Addr) *user_entry))
attribute_hidden;
extern void _dl_sysdep_start_cleanup (void)
--- 1015,1022 ----
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
! ElfW(Addr) *user_entry,
! ElfW(auxv_t) *auxv))
attribute_hidden;
extern void _dl_sysdep_start_cleanup (void)