37 lines
1.1 KiB
C++
37 lines
1.1 KiB
C++
void __init_cpu_features_resolver(unsigned long hwcap,
|
|
const __ifunc_arg_t *arg) {
|
|
if (__aarch64_cpu_features.features)
|
|
return;
|
|
|
|
// ifunc resolvers don't have hwcaps in arguments on Android API lower
|
|
// than 30. If so, set feature detection done and keep all CPU features
|
|
// unsupported (zeros). To detect this case in runtime we check existence
|
|
// of memfd_create function from Standard C library which was introduced in
|
|
// Android API 30.
|
|
int memfd_create(const char *, unsigned int) __attribute__((weak));
|
|
if (!memfd_create)
|
|
return;
|
|
|
|
__init_cpu_features_constructor(hwcap, arg);
|
|
}
|
|
|
|
void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
|
|
// CPU features already initialized.
|
|
if (__aarch64_cpu_features.features)
|
|
return;
|
|
|
|
// Don't set any CPU features,
|
|
// detection could be wrong on Exynos 9810.
|
|
if (__isExynos9810())
|
|
return;
|
|
|
|
unsigned long hwcap = getauxval(AT_HWCAP);
|
|
unsigned long hwcap2 = getauxval(AT_HWCAP2);
|
|
|
|
__ifunc_arg_t arg;
|
|
arg._size = sizeof(__ifunc_arg_t);
|
|
arg._hwcap = hwcap;
|
|
arg._hwcap2 = hwcap2;
|
|
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
|
|
}
|