aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-01-24 20:26:04 -0800
committerH. Peter Anvin <hpa@zytor.com>2014-01-24 20:28:23 -0800
commit45e09deb6a0a4fcb3a56efb7e18807b2800e358f (patch)
tree12f35ecc704e565935515b9e3c49b6f805fefeae
parente0c108682e87aaf0567cb851e1a7918a0d3cd650 (diff)
downloadklibc-45e09deb6a0a4fcb3a56efb7e18807b2800e358f.tar.gz
auxv: convert auxiliary vector into an array; define getauxval()
Convert the ELF auxiliary vector into an array. Define getauxval() as an inline accessor to that array. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--usr/include/sys/auxv.h16
-rw-r--r--usr/include/sys/elfcommon.h2
-rw-r--r--usr/klibc/libc_init.c25
3 files changed, 30 insertions, 13 deletions
diff --git a/usr/include/sys/auxv.h b/usr/include/sys/auxv.h
new file mode 100644
index 00000000000000..08fcfcf623fd3c
--- /dev/null
+++ b/usr/include/sys/auxv.h
@@ -0,0 +1,16 @@
+#ifndef _SYS_AUXV_H
+#define _SYS_AUXV_H
+
+#include <klibc/compiler.h>
+#include <elf.h>
+
+#define _AUXVAL_MAX AT_SYSINFO_EHDR
+
+__extern unsigned long __auxval[_AUXVAL_MAX];
+
+__static_inline unsigned long getauxval(unsigned long __t)
+{
+ return (__t >= _AUXVAL_MAX) ? 0 : __auxval[__t];
+}
+
+#endif /* _SYS_AUXV_H */
diff --git a/usr/include/sys/elfcommon.h b/usr/include/sys/elfcommon.h
index 300ff4e31dc9c9..603b0ce50de4d4 100644
--- a/usr/include/sys/elfcommon.h
+++ b/usr/include/sys/elfcommon.h
@@ -107,6 +107,8 @@
#define AT_CLKTCK 17 /* frequency at which times() increments */
/* 18..22 = ? */
#define AT_SECURE 23 /* secure mode boolean */
+#define AT_SYSINFO 32 /* vdso entry point address */
+#define AT_SYSINFO_EHDR 33 /* vdso header address */
/* Program header permission flags */
#define PF_X 0x1
diff --git a/usr/klibc/libc_init.c b/usr/klibc/libc_init.c
index 8d18820df402f6..1087f9532edf1c 100644
--- a/usr/klibc/libc_init.c
+++ b/usr/klibc/libc_init.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <klibc/compiler.h>
#include <elf.h>
+#include <sys/auxv.h>
#include "atexit.h"
/* This file is included from __static_init.c or __shared_init.c */
@@ -35,12 +36,14 @@ char **environ;
unsigned int __page_size, __page_shift;
struct auxentry {
- uintptr_t type;
- uintptr_t v;
+ unsigned long type;
+ unsigned long v;
};
extern void __init_stdio(void);
+unsigned long __auxval[_AUXVAL_MAX];
+
__noreturn __libc_init(uintptr_t * elfdata, void (*onexit) (void))
{
int argc;
@@ -76,20 +79,16 @@ __noreturn __libc_init(uintptr_t * elfdata, void (*onexit) (void))
auxentry = (struct auxentry *)(envend + 1);
while (auxentry->type) {
- switch (auxentry->type) {
-#if SHARED
- case AT_ENTRY:
- MAIN = (main_t) (auxentry->v);
- break;
-#endif
- case AT_PAGESZ:
- page_size = (unsigned int)(auxentry->v);
- break;
- }
+ if (auxentry->type < _AUXVAL_MAX)
+ __auxval[auxentry->type] = auxentry->v;
auxentry++;
}
- __page_size = page_size;
+#if SHARED
+ MAIN = (main_t) __auxval[AT_ENTRY];
+#endif
+
+ __page_size = page_size = __auxval[AT_PAGESZ];
#if __GNUC__ >= 4
/* unsigned int is 32 bits on all our architectures */