2005-04-17 02:20:36 +04:00
/*
* arch / um / kernel / elf_aux . c
*
* Scan the Elf auxiliary vector provided by the host to extract
* information about vsyscall - page , etc .
*
* Copyright ( C ) 2004 Fujitsu Siemens Computers GmbH
* Author : Bodo Stroesser ( bodo . stroesser @ fujitsu - siemens . com )
*/
# include <elf.h>
# include <stddef.h>
# include "init.h"
# include "elf_user.h"
2005-07-30 01:03:33 +04:00
# include "mem_user.h"
2005-09-29 01:27:23 +04:00
# include <kern_constants.h>
2005-04-17 02:20:36 +04:00
2005-09-21 20:39:47 +04:00
/* Use the one from the kernel - the host may miss it, if having old headers. */
# if UM_ELF_CLASS == UM_ELFCLASS32
2005-04-17 02:20:36 +04:00
typedef Elf32_auxv_t elf_auxv_t ;
# else
typedef Elf64_auxv_t elf_auxv_t ;
# endif
char * elf_aux_platform ;
long elf_aux_hwcap ;
unsigned long vsyscall_ehdr ;
unsigned long vsyscall_end ;
unsigned long __kernel_vsyscall ;
__init void scan_elf_aux ( char * * envp )
{
long page_size = 0 ;
elf_auxv_t * auxv ;
while ( * envp + + ! = NULL ) ;
for ( auxv = ( elf_auxv_t * ) envp ; auxv - > a_type ! = AT_NULL ; auxv + + ) {
switch ( auxv - > a_type ) {
case AT_SYSINFO :
__kernel_vsyscall = auxv - > a_un . a_val ;
break ;
case AT_SYSINFO_EHDR :
vsyscall_ehdr = auxv - > a_un . a_val ;
2005-07-30 01:03:33 +04:00
/* See if the page is under TASK_SIZE */
if ( vsyscall_ehdr < ( unsigned long ) envp )
vsyscall_ehdr = 0 ;
2005-04-17 02:20:36 +04:00
break ;
case AT_HWCAP :
elf_aux_hwcap = auxv - > a_un . a_val ;
break ;
case AT_PLATFORM :
2005-06-09 02:48:01 +04:00
/* elf.h removed the pointer elements from
* a_un , so we have to use a_val , which is
* all that ' s left .
*/
2005-09-17 06:27:48 +04:00
elf_aux_platform =
( char * ) ( long ) auxv - > a_un . a_val ;
2005-04-17 02:20:36 +04:00
break ;
case AT_PAGESZ :
page_size = auxv - > a_un . a_val ;
break ;
}
}
if ( ! __kernel_vsyscall | | ! vsyscall_ehdr | |
! elf_aux_hwcap | | ! elf_aux_platform | |
! page_size | | ( vsyscall_ehdr % page_size ) ) {
__kernel_vsyscall = 0 ;
vsyscall_ehdr = 0 ;
elf_aux_hwcap = 0 ;
elf_aux_platform = " i586 " ;
}
else {
vsyscall_end = vsyscall_ehdr + page_size ;
}
}