[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