[PATCH 1/3] libc_elf: improve auxiliary vector handling

Carmelo AMOROSO carmelo.amoroso at st.com
Mon May 2 16:44:01 UTC 2011


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 <carmelo.amoroso at st.com>
---
 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 <carmelo.amoroso at st.com>
+ *
+ * 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 <carmelo.amoroso at st.com>
-
+#
 # 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 <carmelo.amoroso at st.com>
+ *
+ * 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



More information about the uClibc mailing list