Hello,
I've been getting "undefined instruction" errors in my syslog caused by
the cpu features detection code
in armcap.c. These messages show up when CONFIG_DEBUG_USER is enabled
in the kernel.
To eliminate the errors I have updated the cpu detection code to use
/proc/self/auxv and /proc/cpuinfo
when compiled on Linux. Since the indentation style does not match the
original code, I will redo
the patch if you decide you want to roll it into your source tree.
Correct my if I'm wrong, but I'm pretty sure that ARMV7_TICK should be
enabled only on cortex processors.
--- ./crypto/armcap.c.orig 2011-11-14 13:58:00.000000000 -0700
+++ ./crypto/armcap.c 2012-07-05 14:23:26.629064351 -0600
@@ -9,6 +9,87 @@
unsigned int OPENSSL_armcap_P;
+#if defined(__linux__)
+
+#include <asm/hwcap.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <elf.h>
+
+static unsigned int
+linux_auxv()
+{
+ int fd;
+ Elf32_auxv_t aux;
+ unsigned int cap = 0;
+
+ fd = open ("/proc/self/auxv", O_RDONLY);
+ if (fd >= 0)
+ {
+ while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
+ {
+ if (aux.a_type == AT_HWCAP)
+ {
+ uint32_t hwcap = aux.a_un.a_val;
+ if ( (hwcap & HWCAP_NEON) )
+ cap |= ARMV7_NEON;
+ break;
+ }
+ }
+ close (fd);
+ }
+
+ return cap;
+}
+
+static unsigned int
+linux_cpuinfo()
+{
+ unsigned int cap = 0;
+ FILE *fp = fopen ("/proc/cpuinfo", "r");
+
+ if ( fp )
+ {
+ char *line = 0;
+ size_t len = 0;
+ ssize_t read;
+ unsigned int partNo = 0;
+
+ while ((read = getline(&line, &len, fp)) != -1)
+ {
+ if ( ! strncmp(line, "CPU part", 8) )
+ {
+ // "CPU part\t: 0x581" // marvell dove v7l
+ // "CPU part\t: 0xC05" // cortex a5
+ char *p = line + 11;
+
+ sscanf(p, "%x\n", &partNo);
+
+ if ( (partNo >> 16) == 0xC ) // cortex family
+ cap |= ARMV7_TICK;
+
+ break;
+ }
+ }
+
+ free(line);
+ fclose(fp);
+ }
+
+ return cap;
+}
+
+static unsigned int linux_set_capabilities(void)
+{
+ return linux_auxv() | linux_cpuinfo();
+}
+
+#else
+
static sigset_t all_masked;
static sigjmp_buf ill_jmp;
@@ -28,12 +109,16 @@ unsigned int OPENSSL_rdtsc(void)
else
return 0;
}
+#endif
#if defined(__GNUC__) && __GNUC__>=2
void OPENSSL_cpuid_setup(void) __attribute__((constructor));
#endif
void OPENSSL_cpuid_setup(void)
{
+#if defined(__linux__)
+ OPENSSL_armcap_P = linux_set_capabilities();
+#else
char *e;
struct sigaction ill_oact,ill_act;
sigset_t oset;
@@ -41,7 +126,7 @@ void OPENSSL_cpuid_setup(void)
if (trigger) return;
trigger=1;
-
+
if ((e=getenv("OPENSSL_armcap")))
{
OPENSSL_armcap_P=strtoul(e,NULL,0);
@@ -77,4 +162,5 @@ void OPENSSL_cpuid_setup(void)
sigaction (SIGILL,&ill_oact,NULL);
sigprocmask(SIG_SETMASK,&oset,NULL);
+#endif
}
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]