- if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
- {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
- return(0);
- }
- if ((str=BUF_strdup(name)) == NULL)
- {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
- return(0);
- }
- i=sk_push(app_locks,str);
- if (!i)
- OPENSSL_free(str);
- else
- i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
- return(i);
- }
-
-int CRYPTO_num_locks(void)
- {
- return CRYPTO_NUM_LOCKS;
- }
-
-int CRYPTO_get_new_dynlockid(void)
- {
- int i = 0;
- CRYPTO_dynlock *pointer = NULL;
-
- if (dynlock_create_callback == NULL)
- {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
- return(0);
- }
- CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
- if ((dyn_locks == NULL)
- && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
- {
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
- return(0);
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
- pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
- if (pointer == NULL)
- {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
- return(0);
- }
- pointer->references = 1;
- pointer->data = dynlock_create_callback(__FILE__,__LINE__);
- if (pointer->data == NULL)
- {
- OPENSSL_free(pointer);
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
- return(0);
- }
-
- CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
- /* First, try to find an existing empty slot */
- i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
- /* If there was none, push, thereby creating a new one */
- if (i == -1)
- i=sk_CRYPTO_dynlock_push(dyn_locks,pointer);
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
- if (!i)
- {
- dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
- OPENSSL_free(pointer);
- }
- else
- i += 1; /* to avoid 0 */
- return -i;
- }
-
-void CRYPTO_destroy_dynlockid(int i)
- {
- CRYPTO_dynlock *pointer = NULL;
- if (i)
- i = -i-1;
- if (dynlock_destroy_callback == NULL)
- return;
-
- CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
- if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
- {
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
- return;
- }
- pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
- if (pointer != NULL)
- {
- --pointer->references;
-#ifdef REF_CHECK
- if (pointer->references < 0)
- {
- fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
- abort();
- }
- else
-#endif
- if (pointer->references <= 0)
- {
- sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
- }
- else
- pointer = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
- if (pointer)
- {
- dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
- OPENSSL_free(pointer);
- }
- }
-
-struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
- {
- CRYPTO_dynlock *pointer = NULL;
- if (i)
- i = -i-1;
-
- CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
- if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
- pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
- if (pointer)
- pointer->references++;
-
- CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
- if (pointer)
- return pointer->data;
- return NULL;
- }
-
-struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
- (const char *file,int line)
- {
- return(dynlock_create_callback);
- }
-
-void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
- struct CRYPTO_dynlock_value *l, const char *file,int line)
- {
- return(dynlock_lock_callback);
- }
-
-void (*CRYPTO_get_dynlock_destroy_callback(void))
- (struct CRYPTO_dynlock_value *l, const char *file,int line)
- {
- return(dynlock_destroy_callback);
- }
-
-void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
- (const char *file, int line))
- {
- dynlock_create_callback=func;
- }
-
-void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
- struct CRYPTO_dynlock_value *l, const char *file, int line))
- {
- dynlock_lock_callback=func;
- }
-
-void CRYPTO_set_dynlock_destroy_callback(void (*func)
- (struct CRYPTO_dynlock_value *l, const char *file, int line))
- {
- dynlock_destroy_callback=func;
- }
-
-
-void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
- int line)
- {
- return(locking_callback);
- }
-
-int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
- const char *file,int line)
- {
- return(add_lock_callback);
- }
-
-void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
- const char *file,int line))
- {
- locking_callback=func;
- }
-
-void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
- const char *file,int line))
- {
- add_lock_callback=func;
- }
-
-unsigned long (*CRYPTO_get_id_callback(void))(void)
- {
- return(id_callback);
- }
-
-void CRYPTO_set_id_callback(unsigned long (*func)(void))
- {
- id_callback=func;
- }
-
-unsigned long CRYPTO_thread_id(void)
- {
- unsigned long ret=0;
-
- if (id_callback == NULL)
- {
-#ifdef OPENSSL_SYS_WIN16
- ret=(unsigned long)GetCurrentTask();
-#elif defined(OPENSSL_SYS_WIN32)
- ret=(unsigned long)GetCurrentThreadId();
-#elif defined(GETPID_IS_MEANINGLESS)
- ret=1L;
-#else
- ret=(unsigned long)getpid();
-#endif
- }
- else
- ret=id_callback();
- return(ret);
- }
-
-void CRYPTO_lock(int mode, int type, const char *file, int line)
- {
-#ifdef LOCK_DEBUG
- {
- char *rw_text,*operation_text;
-
- if (mode & CRYPTO_LOCK)
- operation_text="lock ";
- else if (mode & CRYPTO_UNLOCK)
- operation_text="unlock";
- else
- operation_text="ERROR ";
-
- if (mode & CRYPTO_READ)
- rw_text="r";
- else if (mode & CRYPTO_WRITE)
- rw_text="w";
- else
- rw_text="ERROR";
-
- fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
- CRYPTO_thread_id(), rw_text, operation_text,
- CRYPTO_get_lock_name(type), file, line);
- }
+# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#include <stdio.h>
+# define OPENSSL_CPUID_SETUP
+typedef uint64_t IA32CAP;
+void OPENSSL_cpuid_setup(void)
+{
+ static int trigger = 0;
+ IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
+ IA32CAP vec;
+ char *env;
+
+ if (trigger)
+ return;
+
+ trigger = 1;
+ if ((env = getenv("OPENSSL_ia32cap"))) {
+ int off = (env[0] == '~') ? 1 : 0;
+# if defined(_WIN32)
+ if (!sscanf(env + off, "%I64i", &vec))
+ vec = strtoul(env + off, NULL, 0);
+# else
+ if (!sscanf(env + off, "%lli", (long long *)&vec))
+ vec = strtoul(env + off, NULL, 0);
+# endif
+ if (off)
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
+ else if (env[0] == ':')
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+ OPENSSL_ia32cap_P[2] = 0;
+ if ((env = strchr(env, ':'))) {
+ unsigned int vecx;
+ env++;
+ off = (env[0] == '~') ? 1 : 0;
+ vecx = strtoul(env + off, NULL, 0);
+ if (off)
+ OPENSSL_ia32cap_P[2] &= ~vecx;
+ else
+ OPENSSL_ia32cap_P[2] = vecx;
+ }
+ } else
+ vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+ /*
+ * |(1<<10) sets a reserved bit to signal that variable
+ * was initialized already... This is to avoid interference
+ * with cpuid snippets in ELF .init segment.
+ */
+ OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+ OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+# else
+unsigned int OPENSSL_ia32cap_P[4];
+# endif