Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libc/gen/auxv.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (&_DYNAMIC != NULL) | if (&_DYNAMIC != NULL) | ||||
return; | return; | ||||
_once(&aux_vector_once, init_aux_vector_once); | _once(&aux_vector_once, init_aux_vector_once); | ||||
} | } | ||||
static pthread_once_t aux_once = PTHREAD_ONCE_INIT; | static pthread_once_t aux_once = PTHREAD_ONCE_INIT; | ||||
static int pagesize, osreldate, canary_len, ncpus, pagesizes_len, bsdflags; | static int pagesize, osreldate, ncpus, bsdflags; | ||||
static size_t canary_len, pagesizes_len; | |||||
static int hwcap_present, hwcap2_present; | static int hwcap_present, hwcap2_present; | ||||
static char *canary, *pagesizes, *execpath; | static char *canary, *pagesizes, *execpath; | ||||
static void *ps_strings, *timekeep; | static void *ps_strings, *timekeep; | ||||
static u_long hwcap, hwcap2; | static u_long hwcap, hwcap2; | ||||
#ifdef __powerpc__ | #ifdef __powerpc__ | ||||
static int powerpc_new_auxv_format = 0; | static int powerpc_new_auxv_format = 0; | ||||
static void _init_aux_powerpc_fixup(void); | static void _init_aux_powerpc_fixup(void); | ||||
▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
__weak_reference(_elf_aux_info, elf_aux_info); | __weak_reference(_elf_aux_info, elf_aux_info); | ||||
#endif | #endif | ||||
int | int | ||||
_elf_aux_info(int aux, void *buf, int buflen) | _elf_aux_info(int aux, void *buf, int buflen) | ||||
{ | { | ||||
int res; | int res; | ||||
size_t buflen_; | |||||
__init_elf_aux_vector(); | __init_elf_aux_vector(); | ||||
if (__elf_aux_vector == NULL) | if (__elf_aux_vector == NULL) | ||||
return (ENOSYS); | return (ENOSYS); | ||||
_once(&aux_once, init_aux); | _once(&aux_once, init_aux); | ||||
if (buflen < 0) | |||||
return (EINVAL); | |||||
buflen_ = (size_t)buflen; | |||||
switch (aux) { | switch (aux) { | ||||
case AT_CANARY: | case AT_CANARY: | ||||
if (canary != NULL && canary_len >= buflen) { | if (canary != NULL && canary_len >= buflen_) { | ||||
memcpy(buf, canary, buflen); | memcpy(buf, canary, buflen_); | ||||
memset(canary, 0, canary_len); | memset(canary, 0, canary_len); | ||||
canary = NULL; | canary = NULL; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
break; | break; | ||||
case AT_EXECPATH: | case AT_EXECPATH: | ||||
if (execpath == NULL) | if (execpath == NULL) | ||||
res = ENOENT; | res = ENOENT; | ||||
else if (buf == NULL) | else if (buf == NULL) | ||||
res = EINVAL; | res = EINVAL; | ||||
else { | else { | ||||
if (strlcpy(buf, execpath, buflen) >= buflen) | if (strlcpy(buf, execpath, buflen_) >= buflen_) | ||||
res = EINVAL; | res = EINVAL; | ||||
else | else | ||||
res = 0; | res = 0; | ||||
} | } | ||||
break; | break; | ||||
case AT_HWCAP: | case AT_HWCAP: | ||||
if (hwcap_present && buflen == sizeof(u_long)) { | if (hwcap_present && buflen_ == sizeof(u_long)) { | ||||
*(u_long *)buf = hwcap; | *(u_long *)buf = hwcap; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
break; | break; | ||||
case AT_HWCAP2: | case AT_HWCAP2: | ||||
if (hwcap2_present && buflen == sizeof(u_long)) { | if (hwcap2_present && buflen_ == sizeof(u_long)) { | ||||
*(u_long *)buf = hwcap2; | *(u_long *)buf = hwcap2; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
break; | break; | ||||
case AT_PAGESIZES: | case AT_PAGESIZES: | ||||
if (pagesizes != NULL && pagesizes_len >= buflen) { | if (pagesizes != NULL && pagesizes_len >= buflen_) { | ||||
memcpy(buf, pagesizes, buflen); | memcpy(buf, pagesizes, buflen_); | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
break; | break; | ||||
case AT_PAGESZ: | case AT_PAGESZ: | ||||
if (buflen == sizeof(int)) { | if (buflen_ == sizeof(int)) { | ||||
if (pagesize != 0) { | if (pagesize != 0) { | ||||
*(int *)buf = pagesize; | *(int *)buf = pagesize; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
case AT_OSRELDATE: | case AT_OSRELDATE: | ||||
if (buflen == sizeof(int)) { | if (buflen_ == sizeof(int)) { | ||||
if (osreldate != 0) { | if (osreldate != 0) { | ||||
*(int *)buf = osreldate; | *(int *)buf = osreldate; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
case AT_NCPUS: | case AT_NCPUS: | ||||
if (buflen == sizeof(int)) { | if (buflen_ == sizeof(int)) { | ||||
if (ncpus != 0) { | if (ncpus != 0) { | ||||
*(int *)buf = ncpus; | *(int *)buf = ncpus; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
case AT_TIMEKEEP: | case AT_TIMEKEEP: | ||||
if (buflen == sizeof(void *)) { | if (buflen_ == sizeof(void *)) { | ||||
if (timekeep != NULL) { | if (timekeep != NULL) { | ||||
*(void **)buf = timekeep; | *(void **)buf = timekeep; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
case AT_BSDFLAGS: | case AT_BSDFLAGS: | ||||
if (buflen == sizeof(int)) { | if (buflen_ == sizeof(int)) { | ||||
*(int *)buf = bsdflags; | *(int *)buf = bsdflags; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
case AT_PS_STRINGS: | case AT_PS_STRINGS: | ||||
if (buflen == sizeof(void *)) { | if (buflen_ == sizeof(void *)) { | ||||
if (ps_strings != NULL) { | if (ps_strings != NULL) { | ||||
*(void **)buf = ps_strings; | *(void **)buf = ps_strings; | ||||
res = 0; | res = 0; | ||||
} else | } else | ||||
res = ENOENT; | res = ENOENT; | ||||
} else | } else | ||||
res = EINVAL; | res = EINVAL; | ||||
break; | break; | ||||
default: | default: | ||||
res = ENOENT; | res = ENOENT; | ||||
break; | break; | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } |