Fix duplicate lock IDs & simplify lock ID maintenance.

* Eliminate the possibility of multiple lock IDs having the same
  value (CRYPTO_LOCK_FIPS2 and CRYPTO_LOCK_OBJ were both 40 prior to
  this commit).
* Remove unused lock IDs.
* Automatically guarantee that lock IDs and lock names stay in sync.

Change-Id: If20e462db1285fa891595a7e52404ad011ff16f6
Reviewed-on: https://boringssl-review.googlesource.com/3923
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/thread.c b/crypto/thread.c
index f18bc13..fcf249e 100644
--- a/crypto/thread.c
+++ b/crypto/thread.c
@@ -66,27 +66,18 @@
 #endif
 
 #include <openssl/mem.h>
-#include <openssl/type_check.h>
 
 
+#define CRYPTO_LOCK_ITEM(x) #x
+
 /* lock_names contains the names of all the locks defined in thread.h. */
 static const char *const lock_names[] = {
-    "<<ERROR>>",    "err",          "ex_data",       "x509",
-    "x509_info",    "x509_pkey",    "x509_crl",      "x509_req",
-    "dsa",          "rsa",          "evp_pkey",      "x509_store",
-    "ssl_ctx",      "ssl_cert",     "ssl_session",   "ssl_sess_cert",
-    "ssl",          "ssl_method",   "rand",          "rand2",
-    "debug_malloc", "BIO",          "gethostbyname", "getservbyname",
-    "readdir",      "RSA_blinding", "dh",            "debug_malloc2",
-    "dso",          "dynlock",      "engine",        "ui",
-    "ecdsa",        "ec",           "ecdh",          "bn",
-    "ec_pre_comp",  "store",        "comp",          "fips",
-    "fips2",        "obj",
+  CRYPTO_LOCK_LIST
 };
 
-OPENSSL_COMPILE_ASSERT(CRYPTO_NUM_LOCKS ==
-                           sizeof(lock_names) / sizeof(lock_names[0]),
-                       CRYPTO_NUM_LOCKS_inconsistent);
+#undef CRYPTO_LOCK_ITEM
+
+#define CRYPTO_NUM_LOCKS (sizeof(lock_names) / sizeof(lock_names[0]))
 
 static void (*locking_callback)(int mode, int lock_num, const char *file,
                                 int line) = 0;
diff --git a/include/openssl/thread.h b/include/openssl/thread.h
index ea65405..453d4b4 100644
--- a/include/openssl/thread.h
+++ b/include/openssl/thread.h
@@ -178,50 +178,39 @@
 /* CRYPTO_THREADID_hash returns a hash of the numeric value of |id|. */
 uint32_t CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
 
-/* These are the locks used by OpenSSL. These values should match up with the
- * table in thread.c. */
-#define CRYPTO_LOCK_ERR 1
-#define CRYPTO_LOCK_EX_DATA 2
-#define CRYPTO_LOCK_X509 3
-#define CRYPTO_LOCK_X509_INFO 4
-#define CRYPTO_LOCK_X509_PKEY 5
-#define CRYPTO_LOCK_X509_CRL 6
-#define CRYPTO_LOCK_X509_REQ 7
-#define CRYPTO_LOCK_DSA 8
-#define CRYPTO_LOCK_RSA 9
-#define CRYPTO_LOCK_EVP_PKEY 10
-#define CRYPTO_LOCK_X509_STORE 11
-#define CRYPTO_LOCK_SSL_CTX 12
-#define CRYPTO_LOCK_SSL_CERT 13
-#define CRYPTO_LOCK_SSL_SESSION 14
-#define CRYPTO_LOCK_SSL_SESS_CERT 15
-#define CRYPTO_LOCK_SSL 16
-#define CRYPTO_LOCK_SSL_METHOD 17
-#define CRYPTO_LOCK_RAND 18
-#define CRYPTO_LOCK_RAND2 19
-#define CRYPTO_LOCK_MALLOC 20
-#define CRYPTO_LOCK_BIO 21
-#define CRYPTO_LOCK_GETHOSTBYNAME 22
-#define CRYPTO_LOCK_GETSERVBYNAME 23
-#define CRYPTO_LOCK_READDIR 24
-#define CRYPTO_LOCK_RSA_BLINDING 25
-#define CRYPTO_LOCK_DH 26
-#define CRYPTO_LOCK_MALLOC2 27
-#define CRYPTO_LOCK_DSO 28
-#define CRYPTO_LOCK_DYNLOCK 29
-#define CRYPTO_LOCK_ENGINE 30
-#define CRYPTO_LOCK_UI 31
-#define CRYPTO_LOCK_ECDSA 32
-#define CRYPTO_LOCK_EC 33
-#define CRYPTO_LOCK_ECDH 34
-#define CRYPTO_LOCK_BN 35
-#define CRYPTO_LOCK_EC_PRE_COMP 36
-#define CRYPTO_LOCK_STORE 37
-#define CRYPTO_LOCK_COMP 38
-#define CRYPTO_LOCK_FIPS 39
-#define CRYPTO_LOCK_FIPS2 40
-#define CRYPTO_LOCK_OBJ 40
-#define CRYPTO_NUM_LOCKS 42
+/* Lock IDs start from 1. CRYPTO_LOCK_INVALID_LOCK is an unused placeholder
+* used to ensure no lock has ID 0. */
+#define CRYPTO_LOCK_LIST \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_INVALID_LOCK), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_BIO), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_DH), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_DSA), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EC), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EC_PRE_COMP), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_ERR), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EVP_PKEY), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EX_DATA), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_OBJ), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RAND), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_READDIR), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RSA), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RSA_BLINDING), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_SSL_CTX), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_SSL_SESSION), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_INFO), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_PKEY), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_CRL), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_REQ), \
+  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_STORE), \
+
+#define CRYPTO_LOCK_ITEM(x) x
+
+enum {
+  CRYPTO_LOCK_LIST
+};
+
+#undef CRYPTO_LOCK_ITEM
 
 #define CRYPTO_LOCK 1
 #define CRYPTO_UNLOCK 2