diff options
Diffstat (limited to 'src/lib/libcrypto/cryptlib.c')
| -rw-r--r-- | src/lib/libcrypto/cryptlib.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c index 24fe123e14..766ea8cac7 100644 --- a/src/lib/libcrypto/cryptlib.c +++ b/src/lib/libcrypto/cryptlib.c | |||
| @@ -409,6 +409,10 @@ int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, | |||
| 409 | void CRYPTO_set_locking_callback(void (*func)(int mode,int type, | 409 | void CRYPTO_set_locking_callback(void (*func)(int mode,int type, |
| 410 | const char *file,int line)) | 410 | const char *file,int line)) |
| 411 | { | 411 | { |
| 412 | /* Calling this here ensures initialisation before any threads | ||
| 413 | * are started. | ||
| 414 | */ | ||
| 415 | OPENSSL_init(); | ||
| 412 | locking_callback=func; | 416 | locking_callback=func; |
| 413 | } | 417 | } |
| 414 | 418 | ||
| @@ -661,28 +665,52 @@ const char *CRYPTO_get_lock_name(int type) | |||
| 661 | defined(__INTEL__) || \ | 665 | defined(__INTEL__) || \ |
| 662 | defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) | 666 | defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) |
| 663 | 667 | ||
| 664 | unsigned long OPENSSL_ia32cap_P=0; | 668 | unsigned int OPENSSL_ia32cap_P[2]; |
| 665 | unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } | 669 | unsigned long *OPENSSL_ia32cap_loc(void) |
| 670 | { if (sizeof(long)==4) | ||
| 671 | /* | ||
| 672 | * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] | ||
| 673 | * clear second element to maintain the illusion that vector | ||
| 674 | * is 32-bit. | ||
| 675 | */ | ||
| 676 | OPENSSL_ia32cap_P[1]=0; | ||
| 677 | return (unsigned long *)OPENSSL_ia32cap_P; | ||
| 678 | } | ||
| 666 | 679 | ||
| 667 | #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) | 680 | #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) |
| 668 | #define OPENSSL_CPUID_SETUP | 681 | #define OPENSSL_CPUID_SETUP |
| 682 | #if defined(_WIN32) | ||
| 683 | typedef unsigned __int64 IA32CAP; | ||
| 684 | #else | ||
| 685 | typedef unsigned long long IA32CAP; | ||
| 686 | #endif | ||
| 669 | void OPENSSL_cpuid_setup(void) | 687 | void OPENSSL_cpuid_setup(void) |
| 670 | { static int trigger=0; | 688 | { static int trigger=0; |
| 671 | unsigned long OPENSSL_ia32_cpuid(void); | 689 | IA32CAP OPENSSL_ia32_cpuid(void); |
| 690 | IA32CAP vec; | ||
| 672 | char *env; | 691 | char *env; |
| 673 | 692 | ||
| 674 | if (trigger) return; | 693 | if (trigger) return; |
| 675 | 694 | ||
| 676 | trigger=1; | 695 | trigger=1; |
| 677 | if ((env=getenv("OPENSSL_ia32cap"))) | 696 | if ((env=getenv("OPENSSL_ia32cap"))) { |
| 678 | OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10); | 697 | int off = (env[0]=='~')?1:0; |
| 698 | #if defined(_WIN32) | ||
| 699 | if (!sscanf(env+off,"%I64i",&vec)) vec = strtoul(env+off,NULL,0); | ||
| 700 | #else | ||
| 701 | if (!sscanf(env+off,"%lli",(long long *)&vec)) vec = strtoul(env+off,NULL,0); | ||
| 702 | #endif | ||
| 703 | if (off) vec = OPENSSL_ia32_cpuid()&~vec; | ||
| 704 | } | ||
| 679 | else | 705 | else |
| 680 | OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10); | 706 | vec = OPENSSL_ia32_cpuid(); |
| 681 | /* | 707 | /* |
| 682 | * |(1<<10) sets a reserved bit to signal that variable | 708 | * |(1<<10) sets a reserved bit to signal that variable |
| 683 | * was initialized already... This is to avoid interference | 709 | * was initialized already... This is to avoid interference |
| 684 | * with cpuid snippets in ELF .init segment. | 710 | * with cpuid snippets in ELF .init segment. |
| 685 | */ | 711 | */ |
| 712 | OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10); | ||
| 713 | OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32); | ||
| 686 | } | 714 | } |
| 687 | #endif | 715 | #endif |
| 688 | 716 | ||
