@@ -847,6 +847,17 @@ _Bool __aarch64_have_lse_atomics
847
847
#if defined(__has_include )
848
848
#if __has_include (< sys /auxv .h > )
849
849
#include <sys/auxv.h>
850
+
851
+ #if __has_include (< sys /ifunc .h > )
852
+ #include <sys/ifunc.h>
853
+ #else
854
+ typedef struct __ifunc_arg_t {
855
+ unsigned long _size ;
856
+ unsigned long _hwcap ;
857
+ unsigned long _hwcap2 ;
858
+ } __ifunc_arg_t ;
859
+ #endif // __has_include(<sys/ifunc.h>)
860
+
850
861
#if __has_include (< asm /hwcap .h > )
851
862
#include <asm/hwcap.h>
852
863
@@ -858,6 +869,9 @@ _Bool __aarch64_have_lse_atomics
858
869
#include <zircon/syscalls.h>
859
870
#endif
860
871
872
+ #ifndef _IFUNC_ARG_HWCAP
873
+ #define _IFUNC_ARG_HWCAP (1ULL << 62)
874
+ #endif
861
875
#ifndef AT_HWCAP
862
876
#define AT_HWCAP 16
863
877
#endif
@@ -1140,11 +1154,16 @@ struct {
1140
1154
// As features grows new fields could be added
1141
1155
} __aarch64_cpu_features __attribute__((visibility ("hidden" ), nocommon ));
1142
1156
1143
- void init_cpu_features_resolver (unsigned long hwcap , unsigned long hwcap2 ) {
1157
+ void init_cpu_features_resolver (unsigned long hwcap , const __ifunc_arg_t * arg ) {
1144
1158
#define setCPUFeature (F ) __aarch64_cpu_features.features |= 1ULL << F
1145
1159
#define getCPUFeature (id , ftr ) __asm__("mrs %0, " #id : "=r"(ftr))
1146
1160
#define extractBits (val , start , number ) \
1147
1161
(val & ((1ULL << number) - 1ULL) << start) >> start
1162
+ if (__aarch64_cpu_features .features )
1163
+ return ;
1164
+ unsigned long hwcap2 = 0 ;
1165
+ if (hwcap & _IFUNC_ARG_HWCAP )
1166
+ hwcap2 = arg -> _hwcap2 ;
1148
1167
if (hwcap & HWCAP_CRC32 )
1149
1168
setCPUFeature (FEAT_CRC );
1150
1169
if (hwcap & HWCAP_PMULL )
@@ -1320,6 +1339,7 @@ void init_cpu_features_resolver(unsigned long hwcap, unsigned long hwcap2) {
1320
1339
if (hwcap & HWCAP_SHA3 )
1321
1340
setCPUFeature (FEAT_SHA3 );
1322
1341
}
1342
+ setCPUFeature (FEAT_MAX );
1323
1343
}
1324
1344
1325
1345
void CONSTRUCTOR_ATTRIBUTE init_cpu_features (void ) {
@@ -1328,7 +1348,6 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
1328
1348
// CPU features already initialized.
1329
1349
if (__aarch64_cpu_features .features )
1330
1350
return ;
1331
- setCPUFeature (FEAT_MAX );
1332
1351
#if defined(__FreeBSD__ )
1333
1352
int res = 0 ;
1334
1353
res = elf_aux_info (AT_HWCAP , & hwcap , sizeof hwcap );
@@ -1344,7 +1363,11 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
1344
1363
hwcap = getauxval (AT_HWCAP );
1345
1364
hwcap2 = getauxval (AT_HWCAP2 );
1346
1365
#endif // defined(__FreeBSD__)
1347
- init_cpu_features_resolver (hwcap , hwcap2 );
1366
+ __ifunc_arg_t arg ;
1367
+ arg ._size = sizeof (__ifunc_arg_t );
1368
+ arg ._hwcap = hwcap ;
1369
+ arg ._hwcap2 = hwcap2 ;
1370
+ init_cpu_features_resolver (hwcap | _IFUNC_ARG_HWCAP , & arg );
1348
1371
#undef extractBits
1349
1372
#undef getCPUFeature
1350
1373
#undef setCPUFeature
0 commit comments