ClickHouse/base/glibc-compatibility/musl/getauxval.c

71 lines
1.7 KiB
C
Raw Normal View History

#include <sys/auxv.h>
2022-01-29 22:09:15 +00:00
#include "atomic.h"
#include <unistd.h> // __environ
2020-11-14 08:36:44 +00:00
#include <errno.h>
2022-01-29 22:09:15 +00:00
// We don't have libc struct available here. Compute aux vector manually.
static unsigned long * __auxv = NULL;
static unsigned long __auxv_secure = 0;
2020-11-14 08:36:44 +00:00
2022-01-29 22:09:15 +00:00
static size_t __find_auxv(unsigned long type)
{
size_t i;
for (i = 0; __auxv[i]; i += 2)
{
if (__auxv[i] == type)
return i + 1;
}
return (size_t) -1;
}
unsigned long __getauxval(unsigned long type)
2020-11-14 08:36:44 +00:00
{
if (type == AT_SECURE)
return __auxv_secure;
2022-01-29 22:09:15 +00:00
if (__auxv)
2020-11-14 08:36:44 +00:00
{
2022-01-29 22:09:15 +00:00
size_t index = __find_auxv(type);
if (index != ((size_t) -1))
return __auxv[index];
2020-11-14 08:36:44 +00:00
}
2022-01-29 22:09:15 +00:00
errno = ENOENT;
return 0;
2020-11-14 08:36:44 +00:00
}
static void * volatile getauxval_func;
static unsigned long __auxv_init(unsigned long type)
{
2022-01-29 22:09:15 +00:00
if (!__environ)
{
2022-01-29 22:09:15 +00:00
// __environ is not initialized yet so we can't initialize __auxv right now.
// That's normally occurred only when getauxval() is called from some sanitizer's internal code.
errno = ENOENT;
return 0;
}
2022-01-29 22:09:15 +00:00
// Initialize __auxv and __auxv_secure.
size_t i;
for (i = 0; __environ[i]; i++);
__auxv = (unsigned long *) (__environ + i + 1);
size_t secure_idx = __find_auxv(AT_SECURE);
if (secure_idx != ((size_t) -1))
__auxv_secure = __auxv[secure_idx];
// Now we've initialized __auxv, next time getauxval() will only call __get_auxval().
a_cas_p(&getauxval_func, (void *)__auxv_init, (void *)__getauxval);
return __getauxval(type);
}
// First time getauxval() will call __auxv_init().
static void * volatile getauxval_func = (void *)__auxv_init;
unsigned long getauxval(unsigned long type)
{
return ((unsigned long (*)(unsigned long))getauxval_func)(type);
}