Declare global arch arrays with contents (#1171)

This eliminates the need for archs_enable() and eliminates the racey
initialization.

This makes the architecture-specific init, option, and destroy functions
non-static so that they may be called from a different file.
diff --git a/arch/AArch64/AArch64Module.c b/arch/AArch64/AArch64Module.c
index 3894455..44965cf 100644
--- a/arch/AArch64/AArch64Module.c
+++ b/arch/AArch64/AArch64Module.c
@@ -8,8 +8,9 @@
 #include "AArch64Disassembler.h"
 #include "AArch64InstPrinter.h"
 #include "AArch64Mapping.h"
+#include "AArch64Module.h"
 
-static cs_err init(cs_struct *ud)
+cs_err AArch64_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -28,7 +29,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err AArch64_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	if (type == CS_OPT_MODE) {
 		handle->mode = (cs_mode)value;
@@ -37,19 +38,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void AArch64_destroy(cs_struct *handle)
 {
 }
 
-void AArch64_enable(void)
-{
-	cs_arch_init[CS_ARCH_ARM64] = init;
-	cs_arch_option[CS_ARCH_ARM64] = option;
-	cs_arch_destroy[CS_ARCH_ARM64] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_ARM64] = ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_BIG_ENDIAN);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_ARM64);
-}
-
 #endif
diff --git a/arch/AArch64/AArch64Module.h b/arch/AArch64/AArch64Module.h
new file mode 100644
index 0000000..e2b4a14
--- /dev/null
+++ b/arch/AArch64/AArch64Module.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_AARCH64_MODULE_H
+#define CS_AARCH64_MODULE_H
+
+#include "../../utils.h"
+
+cs_err AArch64_global_init(cs_struct *ud);
+cs_err AArch64_option(cs_struct *handle, cs_opt_type type, size_t value);
+void AArch64_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/ARM/ARMModule.c b/arch/ARM/ARMModule.c
index a342c77..3287fa9 100644
--- a/arch/ARM/ARMModule.c
+++ b/arch/ARM/ARMModule.c
@@ -8,8 +8,9 @@
 #include "ARMDisassembler.h"
 #include "ARMInstPrinter.h"
 #include "ARMMapping.h"
+#include "ARMModule.h"
 
-static cs_err init(cs_struct *ud)
+cs_err ARM_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -33,7 +34,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err ARM_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	switch(type) {
 		case CS_OPT_MODE:
@@ -56,21 +57,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void ARM_destroy(cs_struct *handle)
 {
 }
 
-void ARM_enable(void)
-{
-	cs_arch_init[CS_ARCH_ARM] = init;
-	cs_arch_option[CS_ARCH_ARM] = option;
-	cs_arch_destroy[CS_ARCH_ARM] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_ARM] = ~(CS_MODE_LITTLE_ENDIAN |
-		CS_MODE_ARM | CS_MODE_V8 | CS_MODE_MCLASS | CS_MODE_THUMB |
-		CS_MODE_BIG_ENDIAN);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_ARM);
-}
-
 #endif
diff --git a/arch/ARM/ARMModule.h b/arch/ARM/ARMModule.h
new file mode 100644
index 0000000..5761961
--- /dev/null
+++ b/arch/ARM/ARMModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_ARM_MODULE_H
+#define CS_ARM_MODULE_H
+
+#include "../../utils.h"
+
+cs_err ARM_global_init(cs_struct *ud);
+cs_err ARM_option(cs_struct *handle, cs_opt_type type, size_t value);
+void ARM_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/Mips/MipsModule.c b/arch/Mips/MipsModule.c
index 5936121..07740da 100644
--- a/arch/Mips/MipsModule.c
+++ b/arch/Mips/MipsModule.c
@@ -8,6 +8,7 @@
 #include "MipsDisassembler.h"
 #include "MipsInstPrinter.h"
 #include "MipsMapping.h"
+#include "MipsModule.h"
 
 // Returns mode value with implied bits set
 static inline cs_mode updated_mode(cs_mode mode)
@@ -19,7 +20,7 @@
 	return mode;
 }
 
-static cs_err init(cs_struct *ud)
+cs_err Mips_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -42,7 +43,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err Mips_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	if (type == CS_OPT_MODE) {
 		value = updated_mode((cs_mode)value);
@@ -56,21 +57,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void Mips_destroy(cs_struct *handle)
 {
 }
 
-void Mips_enable(void)
-{
-	cs_arch_init[CS_ARCH_MIPS] = init;
-	cs_arch_option[CS_ARCH_MIPS] = option;
-	cs_arch_destroy[CS_ARCH_MIPS] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_MIPS] = ~(CS_MODE_LITTLE_ENDIAN |
-		CS_MODE_32 | CS_MODE_64 | CS_MODE_MICRO | CS_MODE_MIPS32R6 |
-		CS_MODE_MIPSGP64 | CS_MODE_BIG_ENDIAN);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_MIPS);
-}
-
 #endif
diff --git a/arch/Mips/MipsModule.h b/arch/Mips/MipsModule.h
new file mode 100644
index 0000000..ffc5648
--- /dev/null
+++ b/arch/Mips/MipsModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_MIPS_MODULE_H
+#define CS_MIPS_MODULE_H
+
+#include "../../utils.h"
+
+cs_err Mips_global_init(cs_struct *ud);
+cs_err Mips_option(cs_struct *handle, cs_opt_type type, size_t value);
+void Mips_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/PowerPC/PPCModule.c b/arch/PowerPC/PPCModule.c
index 9c37ebe..7a29da0 100644
--- a/arch/PowerPC/PPCModule.c
+++ b/arch/PowerPC/PPCModule.c
@@ -8,8 +8,9 @@
 #include "PPCDisassembler.h"
 #include "PPCInstPrinter.h"
 #include "PPCMapping.h"
+#include "PPCModule.h"
 
-static cs_err init(cs_struct *ud)
+cs_err PPC_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = (MCRegisterInfo *) cs_mem_malloc(sizeof(*mri));
@@ -29,7 +30,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err PPC_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	if (type == CS_OPT_SYNTAX)
 		handle->syntax = (int) value;
@@ -41,20 +42,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void PPC_destroy(cs_struct *handle)
 {
 }
 
-void PPC_enable(void)
-{
-	cs_arch_init[CS_ARCH_PPC] = init;
-	cs_arch_option[CS_ARCH_PPC] = option;
-	cs_arch_destroy[CS_ARCH_PPC] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_PPC] = ~(CS_MODE_LITTLE_ENDIAN |
-		CS_MODE_32 | CS_MODE_64 | CS_MODE_BIG_ENDIAN);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_PPC);
-}
-
 #endif
diff --git a/arch/PowerPC/PPCModule.h b/arch/PowerPC/PPCModule.h
new file mode 100644
index 0000000..2de0ea5
--- /dev/null
+++ b/arch/PowerPC/PPCModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_POWERPC_MODULE_H
+#define CS_POWERPC_MODULE_H
+
+#include "../../utils.h"
+
+cs_err PPC_global_init(cs_struct *ud);
+cs_err PPC_option(cs_struct *handle, cs_opt_type type, size_t value);
+void PPC_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/Sparc/SparcModule.c b/arch/Sparc/SparcModule.c
index 5c025c4..566354e 100644
--- a/arch/Sparc/SparcModule.c
+++ b/arch/Sparc/SparcModule.c
@@ -8,8 +8,9 @@
 #include "SparcDisassembler.h"
 #include "SparcInstPrinter.h"
 #include "SparcMapping.h"
+#include "SparcModule.h"
 
-static cs_err init(cs_struct *ud)
+cs_err Sparc_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -29,7 +30,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err Sparc_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	if (type == CS_OPT_SYNTAX)
 		handle->syntax = (int) value;
@@ -41,20 +42,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void Sparc_destroy(cs_struct *handle)
 {
 }
 
-void Sparc_enable(void)
-{
-	cs_arch_init[CS_ARCH_SPARC] = init;
-	cs_arch_option[CS_ARCH_SPARC] = option;
-	cs_arch_destroy[CS_ARCH_SPARC] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_SPARC] =
-		~(CS_MODE_BIG_ENDIAN | CS_MODE_V9);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_SPARC);
-}
-
 #endif
diff --git a/arch/Sparc/SparcModule.h b/arch/Sparc/SparcModule.h
new file mode 100644
index 0000000..a383f28
--- /dev/null
+++ b/arch/Sparc/SparcModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_SPARC_MODULE_H
+#define CS_SPARC_MODULE_H
+
+#include "../../utils.h"
+
+cs_err Sparc_global_init(cs_struct *ud);
+cs_err Sparc_option(cs_struct *handle, cs_opt_type type, size_t value);
+void Sparc_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/SystemZ/SystemZModule.c b/arch/SystemZ/SystemZModule.c
index 17ee6fe..d3cf71c 100644
--- a/arch/SystemZ/SystemZModule.c
+++ b/arch/SystemZ/SystemZModule.c
@@ -8,8 +8,9 @@
 #include "SystemZDisassembler.h"
 #include "SystemZInstPrinter.h"
 #include "SystemZMapping.h"
+#include "SystemZModule.h"
 
-static cs_err init(cs_struct *ud)
+cs_err SystemZ_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -29,7 +30,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err SystemZ_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	if (type == CS_OPT_SYNTAX)
 		handle->syntax = (int) value;
@@ -40,19 +41,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void SystemZ_destroy(cs_struct *handle)
 {
 }
 
-void SystemZ_enable(void)
-{
-	cs_arch_init[CS_ARCH_SYSZ] = init;
-	cs_arch_option[CS_ARCH_SYSZ] = option;
-	cs_arch_destroy[CS_ARCH_SYSZ] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_SYSZ] = ~CS_MODE_BIG_ENDIAN;
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_SYSZ);
-}
-
 #endif
diff --git a/arch/SystemZ/SystemZModule.h b/arch/SystemZ/SystemZModule.h
new file mode 100644
index 0000000..f605d96
--- /dev/null
+++ b/arch/SystemZ/SystemZModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_SYSTEMZ_MODULE_H
+#define CS_SYSTEMZ_MODULE_H
+
+#include "../../utils.h"
+
+cs_err SystemZ_global_init(cs_struct *ud);
+cs_err SystemZ_option(cs_struct *handle, cs_opt_type type, size_t value);
+void SystemZ_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/X86/X86Module.c b/arch/X86/X86Module.c
index 7bd5777..8c51b91 100644
--- a/arch/X86/X86Module.c
+++ b/arch/X86/X86Module.c
@@ -8,8 +8,9 @@
 #include "X86Disassembler.h"
 #include "X86InstPrinter.h"
 #include "X86Mapping.h"
+#include "X86Module.h"
 
-static cs_err init(cs_struct *ud)
+cs_err X86_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -35,7 +36,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err X86_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	switch(type) {
 		default:
@@ -82,20 +83,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void X86_destroy(cs_struct *handle)
 {
 }
 
-void X86_enable(void)
-{
-	cs_arch_init[CS_ARCH_X86] = init;
-	cs_arch_option[CS_ARCH_X86] = option;
-	cs_arch_destroy[CS_ARCH_X86] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_X86] = ~(CS_MODE_LITTLE_ENDIAN |
-		CS_MODE_32 | CS_MODE_64 | CS_MODE_16);
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_X86);
-}
-
 #endif
diff --git a/arch/X86/X86Module.h b/arch/X86/X86Module.h
new file mode 100644
index 0000000..464ad9c
--- /dev/null
+++ b/arch/X86/X86Module.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_X86_MODULE_H
+#define CS_X86_MODULE_H
+
+#include "../../utils.h"
+
+cs_err X86_global_init(cs_struct *ud);
+cs_err X86_option(cs_struct *handle, cs_opt_type type, size_t value);
+void X86_destroy(cs_struct *handle);
+
+#endif
diff --git a/arch/XCore/XCoreModule.c b/arch/XCore/XCoreModule.c
index b0860b2..e475d75 100644
--- a/arch/XCore/XCoreModule.c
+++ b/arch/XCore/XCoreModule.c
@@ -8,8 +8,9 @@
 #include "XCoreDisassembler.h"
 #include "XCoreInstPrinter.h"
 #include "XCoreMapping.h"
+#include "XCoreModule.h"
 
-static cs_err init(cs_struct *ud)
+cs_err XCore_global_init(cs_struct *ud)
 {
 	MCRegisterInfo *mri;
 	mri = cs_mem_malloc(sizeof(*mri));
@@ -29,7 +30,7 @@
 	return CS_ERR_OK;
 }
 
-static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
+cs_err XCore_option(cs_struct *handle, cs_opt_type type, size_t value)
 {
 	// Do not set mode because only CS_MODE_BIG_ENDIAN is valid; we cannot
 	// test for CS_MODE_LITTLE_ENDIAN because it is 0
@@ -37,19 +38,8 @@
 	return CS_ERR_OK;
 }
 
-static void destroy(cs_struct *handle)
+void XCore_destroy(cs_struct *handle)
 {
 }
 
-void XCore_enable(void)
-{
-	cs_arch_init[CS_ARCH_XCORE] = init;
-	cs_arch_option[CS_ARCH_XCORE] = option;
-	cs_arch_destroy[CS_ARCH_XCORE] = destroy;
-	cs_arch_disallowed_mode_mask[CS_ARCH_XCORE] = ~CS_MODE_BIG_ENDIAN;
-
-	// support this arch
-	all_arch |= (1 << CS_ARCH_XCORE);
-}
-
 #endif
diff --git a/arch/XCore/XCoreModule.h b/arch/XCore/XCoreModule.h
new file mode 100644
index 0000000..3f2d608
--- /dev/null
+++ b/arch/XCore/XCoreModule.h
@@ -0,0 +1,13 @@
+/* Capstone Disassembly Engine */
+/* By Travis Finkenauer <tmfinken@gmail.com>, 2018 */
+
+#ifndef CS_XCORE_MODULE_H
+#define CS_XCORE_MODULE_H
+
+#include "../../utils.h"
+
+cs_err XCore_global_init(cs_struct *ud);
+cs_err XCore_option(cs_struct *handle, cs_opt_type type, size_t value);
+void XCore_destroy(cs_struct *handle);
+
+#endif
diff --git a/cs.c b/cs.c
index 661d730..f69cb42 100644
--- a/cs.c
+++ b/cs.c
@@ -52,57 +52,238 @@
 #define SKIPDATA_MNEM NULL
 #endif
 
-cs_err (*cs_arch_init[MAX_ARCH])(cs_struct *) = { NULL };
-cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t value) = { NULL };
-void (*cs_arch_destroy[MAX_ARCH]) (cs_struct *) = { NULL };
-cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH] = { 0 };
+#include "arch/AArch64/AArch64Module.h"
+#include "arch/ARM/ARMModule.h"
+#include "arch/Mips/MipsModule.h"
+#include "arch/PowerPC/PPCModule.h"
+#include "arch/Sparc/SparcModule.h"
+#include "arch/SystemZ/SystemZModule.h"
+#include "arch/X86/X86Module.h"
+#include "arch/XCore/XCoreModule.h"
 
-extern void ARM_enable(void);
-extern void AArch64_enable(void);
-extern void Mips_enable(void);
-extern void X86_enable(void);
-extern void PPC_enable(void);
-extern void Sparc_enable(void);
-extern void SystemZ_enable(void);
-extern void XCore_enable(void);
 
-static void archs_enable(void)
-{
-	static bool initialized = false;
-
-	if (initialized)
-		return;
-
+cs_err (*cs_arch_init[MAX_ARCH])(cs_struct *) = {
 #ifdef CAPSTONE_HAS_ARM
-	ARM_enable();
+	ARM_global_init,
+#else
+	NULL,
 #endif
 #ifdef CAPSTONE_HAS_ARM64
-	AArch64_enable();
+	AArch64_global_init,
+#else
+	NULL,
 #endif
 #ifdef CAPSTONE_HAS_MIPS
-	Mips_enable();
-#endif
-#ifdef CAPSTONE_HAS_POWERPC
-	PPC_enable();
-#endif
-#ifdef CAPSTONE_HAS_SPARC
-	Sparc_enable();
-#endif
-#ifdef CAPSTONE_HAS_SYSZ
-	SystemZ_enable();
+	Mips_global_init,
+#else
+	NULL,
 #endif
 #ifdef CAPSTONE_HAS_X86
-	X86_enable();
+	X86_global_init,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_POWERPC
+	PPC_global_init,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SPARC
+	Sparc_global_init,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SYSZ
+	SystemZ_global_init,
+#else
+	NULL,
 #endif
 #ifdef CAPSTONE_HAS_XCORE
-	XCore_enable();
+	XCore_global_init,
+#else
+	NULL,
 #endif
+};
 
+cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t value) = {
+#ifdef CAPSTONE_HAS_ARM
+	ARM_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_ARM64
+	AArch64_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_MIPS
+	Mips_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_X86
+	X86_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_POWERPC
+	PPC_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SPARC
+	Sparc_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SYSZ
+	SystemZ_option,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_XCORE
+	XCore_option,
+#else
+	NULL,
+#endif
+};
 
-	initialized = true;
-}
+void (*cs_arch_destroy[MAX_ARCH]) (cs_struct *) = {
+#ifdef CAPSTONE_HAS_ARM
+	ARM_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_ARM64
+	AArch64_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_MIPS
+	Mips_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_X86
+	X86_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_POWERPC
+	PPC_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SPARC
+	Sparc_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_SYSZ
+	SystemZ_destroy,
+#else
+	NULL,
+#endif
+#ifdef CAPSTONE_HAS_XCORE
+	XCore_destroy,
+#else
+	NULL,
+#endif
+};
 
-unsigned int all_arch = 0;
+cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH] = {
+#ifdef CAPSTONE_HAS_ARM
+	~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_V8 | CS_MODE_MCLASS | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_ARM64
+	~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_MIPS
+	~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | CS_MODE_MICRO | CS_MODE_MIPS32R6 | CS_MODE_MIPSGP64 |
+	  CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_X86
+	~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | CS_MODE_16),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_POWERPC
+	~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_SPARC
+	~(CS_MODE_BIG_ENDIAN | CS_MODE_V9),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_SYSZ
+	~(CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+#ifdef CAPSTONE_HAS_XCORE
+	~(CS_MODE_BIG_ENDIAN),
+#else
+	0,
+#endif
+};
+
+unsigned int all_arch =
+#ifdef CAPSTONE_HAS_ARM
+	(1 << CS_ARCH_ARM)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_ARM64
+	(1 << CS_ARCH_ARM64)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_MIPS
+	(1 << CS_ARCH_MIPS)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_X86
+	(1 << CS_ARCH_X86)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_POWERPC
+	(1 << CS_ARCH_PPC)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_SPARC
+	(1 << CS_ARCH_SPARC)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_SYSZ
+	(1 << CS_ARCH_SYSZ)
+#else
+	0
+#endif
+	|
+#ifdef CAPSTONE_HAS_XCORE
+	(1 << CS_ARCH_XCORE)
+#else
+	0
+#endif
+;
 
 #if defined(CAPSTONE_USE_SYS_DYN_MEM)
 #if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
@@ -144,8 +325,6 @@
 CAPSTONE_EXPORT
 unsigned int CAPSTONE_API cs_version(int *major, int *minor)
 {
-	archs_enable();
-
 	if (major != NULL && minor != NULL) {
 		*major = CS_API_MAJOR;
 		*minor = CS_API_MINOR;
@@ -157,8 +336,6 @@
 CAPSTONE_EXPORT
 bool CAPSTONE_API cs_support(int query)
 {
-	archs_enable();
-
 	if (query == CS_ARCH_ALL)
 		return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
 				(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
@@ -243,8 +420,6 @@
 		// with cs_option(CS_OPT_MEM)
 		return CS_ERR_MEMSETUP;
 
-	archs_enable();
-
 	if (arch < CS_ARCH_MAX && cs_arch_init[arch]) {
 		// verify if requested mode is valid
 		if (mode & cs_arch_disallowed_mode_mask[arch]) {
@@ -397,7 +572,6 @@
 cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
 {
 	struct cs_struct *handle;
-	archs_enable();
 
 	// cs_option() can be called with NULL handle just for CS_OPT_MEM
 	// This is supposed to be executed before all other APIs (even cs_open())