Commit 5f40dd15 authored by Richard Levitte's avatar Richard Levitte
Browse files

crypto/armcap.c, crypto/ppccap.c: stricter use of getauxval()



Having a weak getauxval() and only depending on GNU C without looking
at the library we build against meant that it got picked up where not
really expected.

So we change this to check for the glibc version, and since we know it
exists from that version, there's no real need to make it weak.

Reviewed-by: default avatarBernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/8028)
parent aefb980c
Loading
Loading
Loading
Loading
+41 −36
Original line number Diff line number Diff line
@@ -62,14 +62,12 @@ uint32_t OPENSSL_rdtsc(void)
# if defined(__GNUC__) && __GNUC__>=2
void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
# endif
/*
 * Use a weak reference to getauxval() so we can use it if it is available but
 * don't break the build if it is not.
 */
# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__)
extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
# else
static unsigned long (*getauxval) (unsigned long) = NULL;

# if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
#  if __GLIBC_PREREQ(2, 16)
#   include <sys/auxv.h>
#   define OSSL_IMPLEMENT_GETAUXVAL
#  endif
# endif

/*
@@ -134,23 +132,9 @@ void OPENSSL_cpuid_setup(void)
     */
# endif

    sigfillset(&all_masked);
    sigdelset(&all_masked, SIGILL);
    sigdelset(&all_masked, SIGTRAP);
    sigdelset(&all_masked, SIGFPE);
    sigdelset(&all_masked, SIGBUS);
    sigdelset(&all_masked, SIGSEGV);

    OPENSSL_armcap_P = 0;

    memset(&ill_act, 0, sizeof(ill_act));
    ill_act.sa_handler = ill_handler;
    ill_act.sa_mask = all_masked;

    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

    if (getauxval != NULL) {
# ifdef OSSL_IMPLEMENT_GETAUXVAL
    if (getauxval(HWCAP) & HWCAP_NEON) {
        unsigned long hwcap = getauxval(HWCAP_CE);

@@ -173,7 +157,25 @@ void OPENSSL_cpuid_setup(void)
            OPENSSL_armcap_P |= ARMV8_SHA512;
#  endif
    }
    } else if (sigsetjmp(ill_jmp, 1) == 0) {
# endif

    sigfillset(&all_masked);
    sigdelset(&all_masked, SIGILL);
    sigdelset(&all_masked, SIGTRAP);
    sigdelset(&all_masked, SIGFPE);
    sigdelset(&all_masked, SIGBUS);
    sigdelset(&all_masked, SIGSEGV);

    memset(&ill_act, 0, sizeof(ill_act));
    ill_act.sa_handler = ill_handler;
    ill_act.sa_mask = all_masked;

    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
    sigaction(SIGILL, &ill_act, &ill_oact);

    /* If we used getauxval, we already have all the values */
# ifndef OSSL_IMPLEMENT_GETAUXVAL
    if (sigsetjmp(ill_jmp, 1) == 0) {
        _armv7_neon_probe();
        OPENSSL_armcap_P |= ARMV7_NEON;
        if (sigsetjmp(ill_jmp, 1) == 0) {
@@ -198,6 +200,9 @@ void OPENSSL_cpuid_setup(void)
        }
#  endif
    }
# endif

    /* Things that getauxval didn't tell us */
    if (sigsetjmp(ill_jmp, 1) == 0) {
        _armv7_tick();
        OPENSSL_armcap_P |= ARMV7_TICK;
+8 −11
Original line number Diff line number Diff line
@@ -168,16 +168,11 @@ void OPENSSL_altivec_probe(void);
void OPENSSL_crypto207_probe(void);
void OPENSSL_madd300_probe(void);

/*
 * Use a weak reference to getauxval() so we can use it if it is available
 * but don't break the build if it is not. Note that this is *link-time*
 * feature detection, not *run-time*. In other words if we link with
 * symbol present, it's expected to be present even at run-time.
 */
#if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__)
extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
#else
static unsigned long (*getauxval) (unsigned long) = NULL;
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
# if __GLIBC_PREREQ(2, 16)
#  include <sys/auxv.h>
#  define OSSL_IMPLEMENT_GETAUXVAL
# endif
#endif

/* I wish <sys/auxv.h> was universally available */
@@ -277,7 +272,8 @@ void OPENSSL_cpuid_setup(void)
    }
#endif

    if (getauxval != NULL) {
#ifdef OSSL_IMPLEMENT_GETAUXVAL
    {
        unsigned long hwcap = getauxval(HWCAP);

        if (hwcap & HWCAP_FPU) {
@@ -307,6 +303,7 @@ void OPENSSL_cpuid_setup(void)

        return;
    }
#endif

    sigfillset(&all_masked);
    sigdelset(&all_masked, SIGILL);