[PATCH] armcap.c: use getauxv on glibc to find caps

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] armcap.c: use getauxv on glibc to find caps

Kyle McMartin
More reliable than playing games with signal handling in libraries.

--- a/crypto/armcap.c
+++ b/crypto/armcap.c
@@ -9,11 +9,6 @@
 
 unsigned int OPENSSL_armcap_P;
 
-static sigset_t all_masked;
-
-static sigjmp_buf ill_jmp;
-static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
-
 /*
  * Following subroutines could have been inlined, but it's not all
  * ARM compilers support inline assembler...
@@ -29,24 +24,26 @@ unsigned int OPENSSL_rdtsc(void)
  return 0;
  }
 
-#if defined(__GNUC__) && __GNUC__>=2
-void OPENSSL_cpuid_setup(void) __attribute__((constructor));
-#endif
-void OPENSSL_cpuid_setup(void)
+#if defined(__GLIBC__) && __GLIBC__>=2 && __GLIBC_MINOR__>=16
+#include <sys/auxv.h>
+
+void OPENSSL_cpuid_find(void)
+ {
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ char *plat = (char *)getauxval(AT_PLATFORM);
+
+ OPENSSL_armcap_P |= hwcap & HWCAP_ARM_NEON ? ARMV7_NEON : 0;
+ OPENSSL_armcap_P |= plat ? (plat[1] == '7' ? ARMV7_TICK : 0) : 0;
+ }
+#else
+static sigset_t all_masked;
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+void OPENSSL_cpuid_find(void)
  {
- char *e;
  struct sigaction ill_oact,ill_act;
  sigset_t oset;
- static int trigger=0;
-
- if (trigger) return;
- trigger=1;
-
- if ((e=getenv("OPENSSL_armcap")))
- {
- OPENSSL_armcap_P=strtoul(e,NULL,0);
- return;
- }
 
  sigfillset(&all_masked);
  sigdelset(&all_masked,SIGILL);
@@ -55,8 +52,6 @@ void OPENSSL_cpuid_setup(void)
  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;
@@ -78,3 +73,25 @@ void OPENSSL_cpuid_setup(void)
  sigaction (SIGILL,&ill_oact,NULL);
  sigprocmask(SIG_SETMASK,&oset,NULL);
  }
+#endif
+
+#if defined(__GNUC__) && __GNUC__>=2
+void OPENSSL_cpuid_setup(void) __attribute__((constructor));
+#endif
+void OPENSSL_cpuid_setup(void)
+ {
+ char *e;
+ static int trigger=0;
+
+ if (trigger) return;
+ trigger=1;
+
+ if ((e=getenv("OPENSSL_armcap")))
+ {
+ OPENSSL_armcap_P=strtoul(e,NULL,0);
+ return;
+ }
+
+ OPENSSL_armcap_P = 0;
+ OPENSSL_cpuid_find();
+ }
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Yuriy Kaminskiy
Kyle McMartin wrote:

> More reliable than playing games with signal handling in libraries.
>
> --- a/crypto/armcap.c
> +++ b/crypto/armcap.c
> @@ -9,11 +9,6 @@
>  
>  unsigned int OPENSSL_armcap_P;
>  
> -static sigset_t all_masked;
> -
> -static sigjmp_buf ill_jmp;
> -static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
> -
>  /*
>   * Following subroutines could have been inlined, but it's not all
>   * ARM compilers support inline assembler...
> @@ -29,24 +24,26 @@ unsigned int OPENSSL_rdtsc(void)
>   return 0;
>   }
>  
> -#if defined(__GNUC__) && __GNUC__>=2
> -void OPENSSL_cpuid_setup(void) __attribute__((constructor));
> -#endif
> -void OPENSSL_cpuid_setup(void)
> +#if defined(__GLIBC__) && __GLIBC__>=2 && __GLIBC_MINOR__>=16

This will break on glibc-3.0.

#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)

> +#include <sys/auxv.h>
> +
> +void OPENSSL_cpuid_find(void)
> + {
> + unsigned long hwcap = getauxval(AT_HWCAP);
> + char *plat = (char *)getauxval(AT_PLATFORM);
> +
> + OPENSSL_armcap_P |= hwcap & HWCAP_ARM_NEON ? ARMV7_NEON : 0;
> + OPENSSL_armcap_P |= plat ? (plat[1] == '7' ? ARMV7_TICK : 0) : 0;
> + }
> +#else
> +static sigset_t all_masked;
> +static sigjmp_buf ill_jmp;
> +static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
> +
> +void OPENSSL_cpuid_find(void)
>   {
> - char *e;
>   struct sigaction ill_oact,ill_act;
>   sigset_t oset;
> - static int trigger=0;
> -
> - if (trigger) return;
> - trigger=1;
> -
> - if ((e=getenv("OPENSSL_armcap")))
> - {
> - OPENSSL_armcap_P=strtoul(e,NULL,0);
> - return;
> - }
>  
>   sigfillset(&all_masked);
>   sigdelset(&all_masked,SIGILL);
> @@ -55,8 +52,6 @@ void OPENSSL_cpuid_setup(void)
>   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;
> @@ -78,3 +73,25 @@ void OPENSSL_cpuid_setup(void)
>   sigaction (SIGILL,&ill_oact,NULL);
>   sigprocmask(SIG_SETMASK,&oset,NULL);
>   }
> +#endif
> +
> +#if defined(__GNUC__) && __GNUC__>=2
> +void OPENSSL_cpuid_setup(void) __attribute__((constructor));
> +#endif
> +void OPENSSL_cpuid_setup(void)
> + {
> + char *e;
> + static int trigger=0;
> +
> + if (trigger) return;
> + trigger=1;
> +
> + if ((e=getenv("OPENSSL_armcap")))
> + {
> + OPENSSL_armcap_P=strtoul(e,NULL,0);
> + return;
> + }
> +
> + OPENSSL_armcap_P = 0;
> + OPENSSL_cpuid_find();
> + }
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       [hidden email]
> Automated List Manager                           [hidden email]
>
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Mike Frysinger
In reply to this post by Kyle McMartin
On Wednesday 11 September 2013 10:49:36 Kyle McMartin wrote:
> +#if defined(__GNUC__) && __GNUC__>=2
> +void OPENSSL_cpuid_setup(void) __attribute__((constructor));
> +#endif
> +void OPENSSL_cpuid_setup(void)

this can be made simpler:
        #if defined(__GNUC__) && __GNUC__>=2
        __attribute__((constructor))
        #endif
        void OPENSSL_cpuid_setup(void)
-mike

signature.asc (853 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Cristian Rodríguez
In reply to this post by Yuriy Kaminskiy
El 12/09/13 14:17, Yuriy Kaminskiy escribió:

> This will break on glibc-3.0.
>
> #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)

Yes, that is the correct way, but ensure <features.h> is being included.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: [PATCH] armcap.c: use getauxv on glibc to find caps

Green, Paul
Cristian Rodríguez wrote:
> El 12/09/13 14:17, Yuriy Kaminskiy escribió:
>
>> This will break on glibc-3.0.
>> #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)
>
>Yes, that is the correct way, but ensure <features.h> is being included.

As a compiler implementer, I must object. The universal convention is that symbols starting with a double-underscore are for the implementation's use, not for use by end-user software. Please stop reading the headers and trying to figure out how the implementation-specific macros work. Stay with the documented macros.

If you are concerned about compiler or runtime bugs, write a configure test for them, like any other feature. Don't put these hacks into the source code.

PG
:��I"Ϯ��r�m���� (���Z+�7�zZ)���1���x ��h���W^��^��%����&jם.+-1�ځ��j:+v�������h�
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Mike Frysinger
On Friday 13 September 2013 16:27:03 Green, Paul wrote:

> Cristian Rodríguez wrote:
> > El 12/09/13 14:17, Yuriy Kaminskiy escribió:
> >> This will break on glibc-3.0.
> >> #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)
> >
> >Yes, that is the correct way, but ensure <features.h> is being included.
>
> As a compiler implementer, I must object. The universal convention is that
> symbols starting with a double-underscore are for the implementation's
> use, not for use by end-user software. Please stop reading the headers and
> trying to figure out how the implementation-specific macros work. Stay
> with the documented macros.
>
> If you are concerned about compiler or runtime bugs, write a configure test
> for them, like any other feature. Don't put these hacks into the source
> code.
it isn't a compiler feature, it's a C library feature

that said, a simple check for the sys/auxv.h header is sufficient.  if openssl
even has the build tooling to support headers like that.
-mike

signature.asc (853 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Yuriy Kaminskiy
In reply to this post by Cristian Rodríguez
Cristian Rodríguez wrote:
> El 12/09/13 14:17, Yuriy Kaminskiy escribió:
>
>> This will break on glibc-3.0.
>>
>> #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)
>
> Yes, that is the correct way, but ensure <features.h> is being included.

(it seems this patch will be rejected for different reasons anyway, but to avoid
replicating bad recipes...)

... unfortunately, condition above won't work properly too, sorry :-(

When __GLIBC_PREREQ is not defined, preprocessor will error out. So, it should
be either

#if defined(__GLIBC__) && ((__GLIBC__<<16) | __GLIBC_MINOR__) >= ((2<<16) | 16)

or, indeed, replaced with configure check for <sys/auxv.h> header (but openssl's
[cC]onfigure lacks infrastructure for header presence checks).
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] armcap.c: use getauxv on glibc to find caps

Mike Frysinger
On Sunday 15 September 2013 18:30:32 Yuriy Kaminskiy wrote:

> Cristian Rodríguez wrote:
> > El 12/09/13 14:17, Yuriy Kaminskiy escribió:
> >> This will break on glibc-3.0.
> >>
> >> #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 16)
> >
> > Yes, that is the correct way, but ensure <features.h> is being included.
>
> (it seems this patch will be rejected for different reasons anyway, but to
> avoid replicating bad recipes...)
>
> ... unfortunately, condition above won't work properly too, sorry :-(
>
> When __GLIBC_PREREQ is not defined, preprocessor will error out. So, it
> should be either
>
> #if defined(__GLIBC__) && ((__GLIBC__<<16) | __GLIBC_MINOR__) >= ((2<<16) |
> 16)
or nest the ifdefs
#ifdef __GLIBC_PREREQ
# if __GLIBC_PREREQ(...)
-mike

signature.asc (853 bytes) Download Attachment