Improve ARM detection

Unify detection of all armv* architecture subtypes,
add support for armv8hcnl (+crypto extensions) detection

Signed-off-by: Bernhard Rosenkränzer <bero@lindev.ch>
This commit is contained in:
Bernhard Rosenkränzer 2018-04-10 17:18:12 +02:00 committed by Panu Matilainen
parent 0e2b8a390e
commit 8c3a7b8fa9
1 changed files with 28 additions and 9 deletions

View File

@ -82,6 +82,7 @@ struct rpmOption {
static struct rpmat_s {
const char *platform;
uint64_t hwcap;
uint64_t hwcap2;
} rpmat;
typedef struct defaultEntry_s {
@ -950,6 +951,9 @@ static int is_geode(void)
#if defined(__linux__)
#ifndef AT_HWCAP2 /* glibc < 2.18 */
#define AT_HWCAP2 26
#endif
/**
* Populate rpmat structure with auxv values
*/
@ -963,6 +967,7 @@ static void read_auxv(void)
if (!rpmat.platform)
rpmat.platform = "";
rpmat.hwcap = getauxval(AT_HWCAP);
rpmat.hwcap2 = getauxval(AT_HWCAP2);
#else
rpmat.platform = "";
int fd = open("/proc/self/auxv", O_RDONLY);
@ -984,6 +989,9 @@ static void read_auxv(void)
case AT_HWCAP:
rpmat.hwcap = auxv.a_un.a_val;
break;
case AT_HWCAP2:
rpmat.hwcap2 = auxv.a_un.a_val;
break;
}
}
close(fd);
@ -1217,16 +1225,27 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
# if !defined(HWCAP_ARM_VFPv3)
# define HWCAP_ARM_VFPv3 (1 << 13)
# endif
if (rstreq(un.machine, "armv7l")) {
if (rpmat.hwcap & HWCAP_ARM_VFPv3) {
# if !defined(HWCAP2_AES)
# define HWCAP2_AES (1 << 0)
# endif
/*
* un.machine is armvXE, where X is version number and E is
* endianness (b or l)
*/
if (rstreqn(un.machine, "armv", 4)) {
char endian = un.machine[strlen(un.machine)-1];
char *modifier = un.machine + 5;
/* keep armv7, armv8, armv9, armv10, ... */
while(risdigit(*modifier))
modifier++;
if (rpmat.hwcap & HWCAP_ARM_VFPv3)
*modifier++ = 'h';
if (rpmat.hwcap2 & HWCAP2_AES)
*modifier++ = 'c';
if (rpmat.hwcap & HWCAP_ARM_NEON)
strcpy(un.machine, "armv7hnl");
else
strcpy(un.machine, "armv7hl");
}
} else if (rstreq(un.machine, "armv6l")) {
if (rpmat.hwcap & HWCAP_ARM_VFP)
strcpy(un.machine, "armv6hl");
*modifier++ = 'n';
*modifier++ = endian;
*modifier++ = 0;
}
# endif /* arm*-linux */