Skip to content

Commit 61962aa

Browse files
committed
[compiler-rt][AArch64] Correct how FMV use ifunc resolver abi.
The patch fixes second argument of Function Multi Versioning resolvers, it is pointer to an extendible struct containing hwcap and hwcap2 not a unsigned long hwcap2. Also fixes FMV features caching in resolver. Differential Revision: https://reviews.llvm.org/D155026
1 parent d3316bc commit 61962aa

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

compiler-rt/lib/builtins/cpu_model.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,17 @@ _Bool __aarch64_have_lse_atomics
847847
#if defined(__has_include)
848848
#if __has_include(<sys/auxv.h>)
849849
#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+
850861
#if __has_include(<asm/hwcap.h>)
851862
#include <asm/hwcap.h>
852863

@@ -858,6 +869,9 @@ _Bool __aarch64_have_lse_atomics
858869
#include <zircon/syscalls.h>
859870
#endif
860871

872+
#ifndef _IFUNC_ARG_HWCAP
873+
#define _IFUNC_ARG_HWCAP (1ULL << 62)
874+
#endif
861875
#ifndef AT_HWCAP
862876
#define AT_HWCAP 16
863877
#endif
@@ -1140,11 +1154,16 @@ struct {
11401154
// As features grows new fields could be added
11411155
} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
11421156

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) {
11441158
#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F
11451159
#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr))
11461160
#define extractBits(val, start, number) \
11471161
(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;
11481167
if (hwcap & HWCAP_CRC32)
11491168
setCPUFeature(FEAT_CRC);
11501169
if (hwcap & HWCAP_PMULL)
@@ -1320,6 +1339,7 @@ void init_cpu_features_resolver(unsigned long hwcap, unsigned long hwcap2) {
13201339
if (hwcap & HWCAP_SHA3)
13211340
setCPUFeature(FEAT_SHA3);
13221341
}
1342+
setCPUFeature(FEAT_MAX);
13231343
}
13241344

13251345
void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
@@ -1328,7 +1348,6 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
13281348
// CPU features already initialized.
13291349
if (__aarch64_cpu_features.features)
13301350
return;
1331-
setCPUFeature(FEAT_MAX);
13321351
#if defined(__FreeBSD__)
13331352
int res = 0;
13341353
res = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
@@ -1344,7 +1363,11 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
13441363
hwcap = getauxval(AT_HWCAP);
13451364
hwcap2 = getauxval(AT_HWCAP2);
13461365
#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);
13481371
#undef extractBits
13491372
#undef getCPUFeature
13501373
#undef setCPUFeature

0 commit comments

Comments
 (0)