This patch is aimed to improve the aux vect handling to gather some useful information from the system through the aux vect. It is achieved by:
- retrieving aux vect inforamtion into _dl_aux_init only - allowing to call _dl_aux_init in both shared and static case - enabling arch specific aux vect data handling - handling aux vect differently in ld.so and libc Signed-off-by: Carmelo Amoroso <[email protected]> --- Makefile.in | 3 +- include/auxvect.h | 33 ++++++++++++++++++++++++ ldso/ldso/dl-startup.c | 5 ++- libc/misc/elf/Makefile.in | 33 ++++++++++++++++++------ libc/misc/elf/dl-support.c | 40 +++++++++++++++++++++++++++--- libc/misc/internals/__uClibc_main.c | 26 ++++++++----------- libc/sysdeps/linux/common/bits/auxvect.h | 13 +++++++++ 7 files changed, 123 insertions(+), 30 deletions(-) create mode 100644 include/auxvect.h create mode 100644 libc/sysdeps/linux/common/bits/auxvect.h diff --git a/Makefile.in b/Makefile.in index 5e0bfcd..e16963a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -224,7 +224,8 @@ HEADERS_RM- := \ tls.h \ rpc/des_crypt.h \ rpc/key_prot.h \ - rpc/rpc_des.h + rpc/rpc_des.h \ + auxvect.h bits/auxvect.h ifeq ($(UCLIBC_STRICT_HEADERS),y) HEADERS_RM- += sgtty.h endif diff --git a/include/auxvect.h b/include/auxvect.h new file mode 100644 index 0000000..37944ab --- /dev/null +++ b/include/auxvect.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 STMicroelectronics Ltd + * Author: Carmelo Amoroso <[email protected]> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + * + * It defines the base macros of aux vect code handling + */ + +#include <bits/auxvect.h> + +/* Minimum number of AT entries from auxiliar vector */ +#define AT_BASE_NUM (AT_EGID + 1) + +#ifdef AT_EXTRA_UPTO +# if !AT_EXTRA_UPTO + /* No extra AT entries needed */ +# define AT_EXTRA_NUM 0 +# else +# define AT_EXTRA_NUM (AT_EXTRA_UPTO - AT_BASE_NUM + 1) +# endif +#else +# error "AT_EXTRA_UPTO has to be defined (0 if not extra AT entried are needed)" +#endif + +#ifdef IS_IN_rtld +/* For the ld.so we are interested to the minimum entries from the auxvect */ +#define AT_NUM AT_BASE_NUM +#elif defined IS_IN_libc +#define AT_NUM (AT_BASE_NUM + AT_EXTRA_NUM) +#else +#error "This header is intended to not be used outside of ld.so or libc" +#endif diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 4492660..f45ae37 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -93,6 +93,7 @@ /* Pull in all the arch specific stuff */ #include "dl-startup.h" +#include <auxvect.h> /* Static declarations */ static int (*_dl_elf_main) (int, char **, char **); @@ -119,7 +120,7 @@ DL_START(unsigned long args) ElfW(Ehdr) *header; struct elf_resolve tpnt_tmp; struct elf_resolve *tpnt = &tpnt_tmp; - ElfW(auxv_t) auxvt[AT_EGID + 1]; + ElfW(auxv_t) auxvt[AT_NUM]; ElfW(Dyn) *dpnt; uint32_t *p32; @@ -158,7 +159,7 @@ DL_START(unsigned long args) while (*aux_dat) { ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; - if (auxv_entry->a_type <= AT_EGID) { + if (auxv_entry->a_type < AT_NUM) { _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t))); } aux_dat += 2; diff --git a/libc/misc/elf/Makefile.in b/libc/misc/elf/Makefile.in index 1b4bd8b..3de4074 100644 --- a/libc/misc/elf/Makefile.in +++ b/libc/misc/elf/Makefile.in @@ -1,22 +1,39 @@ +# # Copyright (C) 2008 STMicroelectronics Ltd. # Author: Carmelo Amoroso <[email protected]> - +# # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -subdirs += libc/misc/elf +subdirs += libc/misc/elf libc/misc/elf/$(TARGET_ARCH) + +CSRC = dl-support.c dl-iterate-phdr.c -libc_a_CSRC = dl-support.c dl-core.c dl-iterate-phdr.c CFLAGS-dl-iterate-phdr.c=-D_GNU_SOURCE -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include CFLAGS-dl-core.c=-I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include -MISC_ELF_OUT:=$(top_builddir)libc/misc/elf -MISC_ELF_OBJ:=$(patsubst %.c,$(MISC_ELF_OUT)/%.o,$(libc_a_CSRC)) +MISC_ELF_ARCH_OUT := $(top_builddir)libc/misc/elf/$(TARGET_ARCH) + +# Pull in any arch specific stuff, if any +-include $(MISC_ELF_ARCH_OUT)/Makefile.arch -libc-static-y += $(MISC_ELF_OBJ) -libc-shared-y += $(MISC_ELF_OUT)/dl-iterate-phdr.oS +CSRC := $(filter-out $(MISC_ELF_ARCH_CSRC),$(CSRC)) -objclean-y+= CLEAN_libc/misc/elf +MISC_ELF_OUT := $(top_builddir)libc/misc/elf +MISC_ELF_OBJS := $(patsubst %.c,$(MISC_ELF_OUT)/%.o,$(CSRC)) + +libc-static-y += $(MISC_ELF_OBJS) \ + $(MISC_ELF_OUT)/dl-core.o + +libc-shared-y += $(patsubst %.o,%.oS,$(MISC_ELF_OBJS)) + +objclean-y += CLEAN_libc/misc/elf + +objclean-y += CLEAN_$(subst $(top_builddir),,$(MISC_ELF_ARCH_OUT)) CLEAN_libc/misc/elf: $(do_rm) $(addprefix $(MISC_ELF_OUT)/*., o os oS) + +# Clean up misc/elf/<target> dir +CLEAN_$(subst $(top_builddir),,$(MISC_ELF_ARCH_OUT)): + $(do_rm) $(addprefix $(MISC_ELF_ARCH_OUT)/*., o os oS) diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c index f194692..cab2143 100644 --- a/libc/misc/elf/dl-support.c +++ b/libc/misc/elf/dl-support.c @@ -19,7 +19,12 @@ #include <ldsodefs.h> #include <string.h> #endif +#include <auxvect.h> +#include <bits/uClibc_page.h> +extern size_t __pagesize; + +#ifndef SHARED #if defined(USE_TLS) && USE_TLS void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; @@ -28,17 +33,43 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; ElfW(Phdr) *_dl_phdr; size_t _dl_phnum; +#endif void internal_function _dl_aux_init (ElfW(auxv_t) *av); void internal_function _dl_aux_init (ElfW(auxv_t) *av) { - /* Get the program headers base address from the aux vect */ - _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val; - /* Get the number of program headers from the aux vect */ - _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val; + for (; av->a_type < AT_NUM; ++av) { + switch (av->a_type) { + case AT_PAGESZ: + /* + * Get the system page size from aux vect if any, otherwise fall + * back to use the fixed arch value + */ + __pagesize = (size_t) (av[AT_PAGESZ].a_un.a_val) ? + av[AT_PAGESZ].a_un.a_val : PAGE_SIZE; + break; + +#ifndef SHARED + case AT_PHDR: + /* Get the program headers base address from the aux vect */ + _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val; + break; + case AT_PHNUM: + /* Get the number of program headers from the aux vect */ + _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val; + break; +#endif + +#ifdef DL_PLATFORM_AUXV + /* Gather any platform specific data */ + DL_PLATFORM_AUXV +#endif + } + } } +#ifndef SHARED #if defined(USE_TLS) && USE_TLS /* Initialize static TLS area and DTV for current (only) thread. libpthread implementations should provide their own hook @@ -67,4 +98,5 @@ _dl_nothread_init_static_tls (struct link_map *map) } #endif +#endif diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 315365a..304b881 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -38,7 +38,8 @@ #endif #ifdef __UCLIBC_HAS_THREADS__ #include <pthread.h> -#endif +#endif +#include <auxvect.h> #ifndef SHARED void *__libc_stack_end = NULL; @@ -58,12 +59,6 @@ uintptr_t __guard attribute_relro; # endif # endif -/* - * Needed to initialize _dl_phdr when statically linked - */ - -void internal_function _dl_aux_init (ElfW(auxv_t) *av); - #ifdef __UCLIBC_HAS_THREADS__ /* * uClibc internal locking requires that we have weak aliases @@ -129,6 +124,7 @@ extern void weak_function __pthread_initialize_minimal(void); extern void __pthread_initialize_minimal(void); #endif #endif +void internal_function _dl_aux_init (ElfW(auxv_t) *av); /* If __UCLIBC_FORMAT_SHARED_FLAT__, all array initialisation and finalisation * is handled by the routines passed to __uClibc_main(). */ @@ -321,7 +317,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, { #ifndef __ARCH_HAS_NO_LDSO__ unsigned long *aux_dat; - ElfW(auxv_t) auxvt[AT_EGID + 1]; + ElfW(auxv_t) auxvt[AT_NUM]; #endif #ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -355,18 +351,20 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, aux_dat++; while (*aux_dat) { ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; - if (auxv_entry->a_type <= AT_EGID) { + if (auxv_entry->a_type < AT_NUM) { memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t))); } aux_dat += 2; } -#ifndef SHARED - /* Get the program headers (_dl_phdr) from the aux vector - It will be used into __libc_setup_tls. */ + /* + * Gather data from the auxiliary vector + * - program headers base address and number (only NOT_SHARED case) + * - pagesize + * - platform specific data (if any) + */ _dl_aux_init (auxvt); #endif -#endif /* We need to initialize uClibc. If we are dynamically linked this * may have already been completed by the shared lib loader. We call @@ -374,8 +372,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, __uClibc_init(); #ifndef __ARCH_HAS_NO_LDSO__ - /* Make certain getpagesize() gives the correct answer */ - __pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE; /* Prevent starting SUID binaries where the stdin. stdout, and * stderr file descriptors are not already opened. */ diff --git a/libc/sysdeps/linux/common/bits/auxvect.h b/libc/sysdeps/linux/common/bits/auxvect.h new file mode 100644 index 0000000..af659ea --- /dev/null +++ b/libc/sysdeps/linux/common/bits/auxvect.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2011 STMicroelectronics Ltd + * Author: Carmelo Amoroso <[email protected]> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + * + * It defines the base macros of aux vect code handling + */ + +#include <elf.h> + +/* No extra AT entries needed with respect to the minimum */ +#define AT_EXTRA_UPTO 0 -- 1.7.4.4 _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
