diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c index fbba80f0..22880efa 100644 --- a/arch/AArch64/AArch64Disassembler.c +++ b/arch/AArch64/AArch64Disassembler.c @@ -238,7 +238,7 @@ static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI, MI->flat_insn->detail->arm64.operands[i].vector_index = -1; } - if (ud->big_endian) + if (MODE_IS_BIG_ENDIAN(ud->mode)) insn = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | ((uint32_t) code[0] << 24); else diff --git a/arch/AArch64/AArch64Module.c b/arch/AArch64/AArch64Module.c index 67a1e12b..7fc5ddf4 100644 --- a/arch/AArch64/AArch64Module.c +++ b/arch/AArch64/AArch64Module.c @@ -8,15 +8,11 @@ #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; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_BIG_ENDIAN)) - return CS_ERR_MODE; - mri = cs_mem_malloc(sizeof(*mri)); AArch64_init(mri); @@ -36,22 +32,13 @@ static cs_err init(cs_struct *ud) 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->big_endian = (((cs_mode)value & CS_MODE_BIG_ENDIAN) != 0); + handle->mode = (cs_mode)value; } return CS_ERR_OK; } -void AArch64_enable(void) -{ - cs_arch_init[CS_ARCH_ARM64] = init; - cs_arch_option[CS_ARCH_ARM64] = option; - - // 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 00000000..73a132de --- /dev/null +++ b/arch/AArch64/AArch64Module.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c index 30a699f8..2851e0c0 100644 --- a/arch/ARM/ARMDisassembler.c +++ b/arch/ARM/ARMDisassembler.c @@ -482,7 +482,7 @@ static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t } } - if (ud->big_endian) + if (MODE_IS_BIG_ENDIAN(ud->mode)) insn = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | @@ -725,7 +725,7 @@ static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8 } } - if (ud->big_endian) + if (MODE_IS_BIG_ENDIAN(ud->mode)) insn16 = (code[0] << 8) | code[1]; else insn16 = (code[1] << 8) | code[0]; @@ -776,7 +776,7 @@ static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8 // not enough data return MCDisassembler_Fail; - if (ud->big_endian) + if (MODE_IS_BIG_ENDIAN(ud->mode)) insn32 = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | diff --git a/arch/ARM/ARMModule.c b/arch/ARM/ARMModule.c index f22a4b2c..0ecadd80 100644 --- a/arch/ARM/ARMModule.c +++ b/arch/ARM/ARMModule.c @@ -8,16 +8,11 @@ #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; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_V8 | - CS_MODE_MCLASS | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN)) - return CS_ERR_MODE; - mri = cs_mem_malloc(sizeof(*mri)); ARM_init(mri); @@ -42,7 +37,7 @@ static cs_err init(cs_struct *ud) 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: @@ -52,7 +47,6 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) handle->disasm = ARM_getInstruction; handle->mode = (cs_mode)value; - handle->big_endian = ((handle->mode & CS_MODE_BIG_ENDIAN) != 0); break; case CS_OPT_SYNTAX: @@ -66,13 +60,4 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) return CS_ERR_OK; } -void ARM_enable(void) -{ - cs_arch_init[CS_ARCH_ARM] = init; - cs_arch_option[CS_ARCH_ARM] = option; - - // 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 00000000..f8449721 --- /dev/null +++ b/arch/ARM/ARMModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/EVM/EVMModule.c b/arch/EVM/EVMModule.c index faf809e0..ec84fe22 100644 --- a/arch/EVM/EVMModule.c +++ b/arch/EVM/EVMModule.c @@ -7,8 +7,9 @@ #include "EVMDisassembler.h" #include "EVMInstPrinter.h" #include "EVMMapping.h" +#include "EVMModule.h" -static cs_err init(cs_struct *ud) +cs_err EVM_global_init(cs_struct *ud) { // verify if requested mode is valid if (ud->mode) @@ -24,18 +25,9 @@ static cs_err init(cs_struct *ud) return CS_ERR_OK; } -static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) +cs_err EVM_option(cs_struct *handle, cs_opt_type type, size_t value) { return CS_ERR_OK; } -void EVM_enable(void) -{ - cs_arch_init[CS_ARCH_EVM] = init; - cs_arch_option[CS_ARCH_EVM] = option; - - // support this arch - all_arch |= (1 << CS_ARCH_EVM); -} - #endif diff --git a/arch/EVM/EVMModule.h b/arch/EVM/EVMModule.h new file mode 100644 index 00000000..0bc6d0a5 --- /dev/null +++ b/arch/EVM/EVMModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 2018 */ + +#ifndef CS_EVM_MODULE_H +#define CS_EVM_MODULE_H + +#include "../../utils.h" + +cs_err EVM_global_init(cs_struct *ud); +cs_err EVM_option(cs_struct *handle, cs_opt_type type, size_t value); + +#endif diff --git a/arch/M680X/M680XModule.c b/arch/M680X/M680XModule.c index de45d482..3b89463d 100644 --- a/arch/M680X/M680XModule.c +++ b/arch/M680X/M680XModule.c @@ -8,8 +8,9 @@ #include "M680XDisassembler.h" #include "M680XDisassemblerInternals.h" #include "M680XInstPrinter.h" +#include "M680XModule.h" -static cs_err init(cs_struct *ud) +cs_err M680X_global_init(cs_struct *ud) { m680x_info *info; cs_err errcode; @@ -66,20 +67,11 @@ static cs_err init(cs_struct *ud) return CS_ERR_OK; } -static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) +cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value) { //TODO return CS_ERR_OK; } -void M680X_enable(void) -{ - cs_arch_init[CS_ARCH_M680X] = init; - cs_arch_option[CS_ARCH_M680X] = option; - - // support this arch - all_arch |= (1 << CS_ARCH_M680X); -} - #endif diff --git a/arch/M680X/M680XModule.h b/arch/M680X/M680XModule.h new file mode 100644 index 00000000..6672eb28 --- /dev/null +++ b/arch/M680X/M680XModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 2018 */ + +#ifndef CS_M680X_MODULE_H +#define CS_M680X_MODULE_H + +#include "../../utils.h" + +cs_err M680X_global_init(cs_struct *ud); +cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value); + +#endif diff --git a/arch/M68K/M68KModule.c b/arch/M68K/M68KModule.c index bce596a1..03e73f7b 100644 --- a/arch/M68K/M68KModule.c +++ b/arch/M68K/M68KModule.c @@ -7,8 +7,9 @@ #include "../../MCRegisterInfo.h" #include "M68KDisassembler.h" #include "M68KInstPrinter.h" +#include "M68KModule.h" -static cs_err init(cs_struct *ud) +cs_err M68K_global_init(cs_struct *ud) { m68k_info *info; @@ -32,19 +33,10 @@ static cs_err init(cs_struct *ud) return CS_ERR_OK; } -static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) +cs_err M68K_option(cs_struct *handle, cs_opt_type type, size_t value) { return CS_ERR_OK; } -void M68K_enable(void) -{ - cs_arch_init[CS_ARCH_M68K] = init; - cs_arch_option[CS_ARCH_M68K] = option; - - // support this arch - all_arch |= (1 << CS_ARCH_M68K); -} - #endif diff --git a/arch/M68K/M68KModule.h b/arch/M68K/M68KModule.h new file mode 100644 index 00000000..65b20bd7 --- /dev/null +++ b/arch/M68K/M68KModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 2018 */ + +#ifndef CS_M68K_MODULE_H +#define CS_M68K_MODULE_H + +#include "../../utils.h" + +cs_err M68K_global_init(cs_struct *ud); +cs_err M68K_option(cs_struct *handle, cs_opt_type type, size_t value); + +#endif diff --git a/arch/Mips/MipsDisassembler.c b/arch/Mips/MipsDisassembler.c index 0b7d90e9..f374d27b 100644 --- a/arch/Mips/MipsDisassembler.c +++ b/arch/Mips/MipsDisassembler.c @@ -509,7 +509,7 @@ bool Mips_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *i DecodeStatus status = MipsDisassembler_getInstruction(handle->mode, instr, code, code_len, size, - address, handle->big_endian, (MCRegisterInfo *)info); + address, MODE_IS_BIG_ENDIAN(handle->mode), (MCRegisterInfo *)info); return status == MCDisassembler_Success; } diff --git a/arch/Mips/MipsModule.c b/arch/Mips/MipsModule.c index a113b744..93c60506 100644 --- a/arch/Mips/MipsModule.c +++ b/arch/Mips/MipsModule.c @@ -8,18 +8,22 @@ #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) +{ + if (mode & CS_MODE_MIPS32R6) { + mode |= CS_MODE_32; + } + + return mode; +} -static cs_err init(cs_struct *ud) +cs_err Mips_global_init(cs_struct *ud) { MCRegisterInfo *mri; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | - CS_MODE_MICRO | CS_MODE_MIPS32R6 | CS_MODE_BIG_ENDIAN | - CS_MODE_MIPS2 | CS_MODE_MIPS3)) - return CS_ERR_MODE; - mri = cs_mem_malloc(sizeof(*mri)); Mips_init(mri); @@ -36,24 +40,14 @@ static cs_err init(cs_struct *ud) 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) { - handle->mode = (cs_mode)value; - handle->big_endian = ((handle->mode & CS_MODE_BIG_ENDIAN) != 0); + handle->mode = updated_mode(value); return CS_ERR_OK; } return CS_ERR_OPTION; } -void Mips_enable(void) -{ - cs_arch_init[CS_ARCH_MIPS] = init; - cs_arch_option[CS_ARCH_MIPS] = option; - - // 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 00000000..d1aa2cff --- /dev/null +++ b/arch/Mips/MipsModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/PowerPC/PPCDisassembler.c b/arch/PowerPC/PPCDisassembler.c index dde43b6d..12e59ebe 100644 --- a/arch/PowerPC/PPCDisassembler.c +++ b/arch/PowerPC/PPCDisassembler.c @@ -363,7 +363,7 @@ static DecodeStatus getInstruction(MCInst *MI, } // The instruction is big-endian encoded. - if (MI->csh->mode & CS_MODE_BIG_ENDIAN) + if (MODE_IS_BIG_ENDIAN(MI->csh->mode)) insn = ((uint32_t) code[0] << 24) | (code[1] << 16) | (code[2] << 8) | (code[3] << 0); else diff --git a/arch/PowerPC/PPCModule.c b/arch/PowerPC/PPCModule.c index 0bba212a..794b9a81 100644 --- a/arch/PowerPC/PPCModule.c +++ b/arch/PowerPC/PPCModule.c @@ -8,16 +8,11 @@ #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; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | - CS_MODE_BIG_ENDIAN | CS_MODE_QPX)) - return CS_ERR_MODE; - mri = (MCRegisterInfo *) cs_mem_malloc(sizeof(*mri)); PPC_init(mri); @@ -35,25 +30,16 @@ static cs_err init(cs_struct *ud) 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; if (type == CS_OPT_MODE) { - handle->big_endian = (((cs_mode)value & CS_MODE_BIG_ENDIAN) != 0); + handle->mode = (cs_mode)value; } return CS_ERR_OK; } -void PPC_enable(void) -{ - cs_arch_init[CS_ARCH_PPC] = init; - cs_arch_option[CS_ARCH_PPC] = option; - - // 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 00000000..079cf600 --- /dev/null +++ b/arch/PowerPC/PPCModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/Sparc/SparcModule.c b/arch/Sparc/SparcModule.c index 614234d5..88a0a9e8 100644 --- a/arch/Sparc/SparcModule.c +++ b/arch/Sparc/SparcModule.c @@ -8,15 +8,11 @@ #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; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_BIG_ENDIAN | CS_MODE_V9)) - return CS_ERR_MODE; - mri = cs_mem_malloc(sizeof(*mri)); Sparc_init(mri); @@ -34,25 +30,16 @@ static cs_err init(cs_struct *ud) 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; if (type == CS_OPT_MODE) { - handle->big_endian = (((cs_mode)value & CS_MODE_BIG_ENDIAN) != 0); + handle->mode = (cs_mode)value; } return CS_ERR_OK; } -void Sparc_enable(void) -{ - cs_arch_init[CS_ARCH_SPARC] = init; - cs_arch_option[CS_ARCH_SPARC] = option; - - // 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 00000000..1caaac1a --- /dev/null +++ b/arch/Sparc/SparcModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/SystemZ/SystemZModule.c b/arch/SystemZ/SystemZModule.c index c35315ce..bc510688 100644 --- a/arch/SystemZ/SystemZModule.c +++ b/arch/SystemZ/SystemZModule.c @@ -8,11 +8,11 @@ #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)); SystemZ_init(mri); @@ -30,21 +30,15 @@ static cs_err init(cs_struct *ud) 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; + // Do not set mode because only CS_MODE_BIG_ENDIAN is valid; we cannot + // test for CS_MODE_LITTLE_ENDIAN because it is 0 + return CS_ERR_OK; } -void SystemZ_enable(void) -{ - cs_arch_init[CS_ARCH_SYSZ] = init; - cs_arch_option[CS_ARCH_SYSZ] = option; - - // 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 00000000..ad403baf --- /dev/null +++ b/arch/SystemZ/SystemZModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/TMS320C64x/TMS320C64xModule.c b/arch/TMS320C64x/TMS320C64xModule.c index 2d6620ad..ff678c7c 100644 --- a/arch/TMS320C64x/TMS320C64xModule.c +++ b/arch/TMS320C64x/TMS320C64xModule.c @@ -8,8 +8,9 @@ #include "TMS320C64xDisassembler.h" #include "TMS320C64xInstPrinter.h" #include "TMS320C64xMapping.h" +#include "TMS320C64xModule.h" -static cs_err init(cs_struct *ud) +cs_err TMS320C64x_global_init(cs_struct *ud) { MCRegisterInfo *mri; @@ -30,17 +31,9 @@ static cs_err init(cs_struct *ud) return CS_ERR_OK; } -static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) +cs_err TMS320C64x_option(cs_struct *handle, cs_opt_type type, size_t value) { return CS_ERR_OK; } -void TMS320C64x_enable(void) -{ - cs_arch_init[CS_ARCH_TMS320C64X] = init; - cs_arch_option[CS_ARCH_TMS320C64X] = option; - - all_arch |= (1 << CS_ARCH_TMS320C64X); -} - #endif diff --git a/arch/TMS320C64x/TMS320C64xModule.h b/arch/TMS320C64x/TMS320C64xModule.h new file mode 100644 index 00000000..f1c53120 --- /dev/null +++ b/arch/TMS320C64x/TMS320C64xModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 2018 */ + +#ifndef CS_TMS320C64X_MODULE_H +#define CS_TMS320C64X_MODULE_H + +#include "../../utils.h" + +cs_err TMS320C64x_global_init(cs_struct *ud); +cs_err TMS320C64x_option(cs_struct *handle, cs_opt_type type, size_t value); + +#endif diff --git a/arch/X86/X86Module.c b/arch/X86/X86Module.c index 77a021c1..98c6e47f 100644 --- a/arch/X86/X86Module.c +++ b/arch/X86/X86Module.c @@ -8,15 +8,11 @@ #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; - - // verify if requested mode is valid - if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | CS_MODE_16)) - return CS_ERR_MODE; - mri = cs_mem_malloc(sizeof(*mri)); X86_init(mri); @@ -43,7 +39,7 @@ static cs_err init(cs_struct *ud) 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: @@ -95,13 +91,4 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) return CS_ERR_OK; } -void X86_enable(void) -{ - cs_arch_init[CS_ARCH_X86] = init; - cs_arch_option[CS_ARCH_X86] = option; - - // 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 00000000..53d13ede --- /dev/null +++ b/arch/X86/X86Module.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/arch/XCore/XCoreModule.c b/arch/XCore/XCoreModule.c index 0e416877..90940d48 100644 --- a/arch/XCore/XCoreModule.c +++ b/arch/XCore/XCoreModule.c @@ -8,11 +8,11 @@ #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)); XCore_init(mri); @@ -30,18 +30,12 @@ static cs_err init(cs_struct *ud) 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 + return CS_ERR_OK; } -void XCore_enable(void) -{ - cs_arch_init[CS_ARCH_XCORE] = init; - cs_arch_option[CS_ARCH_XCORE] = option; - - // 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 00000000..c4a7d2b2 --- /dev/null +++ b/arch/XCore/XCoreModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Travis Finkenauer , 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); + +#endif diff --git a/cs.c b/cs.c index 4f181c2a..d2ffecc7 100644 --- a/cs.c +++ b/cs.c @@ -52,72 +52,259 @@ #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 }; - -extern void ARM_enable(void); -extern void AArch64_enable(void); -extern void M680X_enable(void); -extern void M68K_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); -extern void TMS320C64x_enable(void); -extern void EVM_enable(void); - -static void archs_enable(void) -{ - static bool initialized = false; - - if (initialized) - return; +#include "arch/AArch64/AArch64Module.h" +#include "arch/ARM/ARMModule.h" +#include "arch/EVM/EVMModule.h" +#include "arch/M680X/M680XModule.h" +#include "arch/M68K/M68KModule.h" +#include "arch/Mips/MipsModule.h" +#include "arch/PowerPC/PPCModule.h" +#include "arch/Sparc/SparcModule.h" +#include "arch/SystemZ/SystemZModule.h" +#include "arch/TMS320C64x/TMS320C64xModule.h" +#include "arch/X86/X86Module.h" +#include "arch/XCore/XCoreModule.h" +// constructor initialization for all archs +static 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(); -#endif -#ifdef CAPSTONE_HAS_M680X - M680X_enable(); -#endif -#ifdef CAPSTONE_HAS_M68K - M68K_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 +#ifdef CAPSTONE_HAS_M68K + M68K_global_init, +#else + NULL, #endif #ifdef CAPSTONE_HAS_TMS320C64X - TMS320C64x_enable(); + TMS320C64x_global_init, +#else + NULL, +#endif +#ifdef CAPSTONE_HAS_M680X + M680X_global_init, +#else + NULL, #endif #ifdef CAPSTONE_HAS_EVM - EVM_enable(); + EVM_global_init, +#else + NULL, #endif +}; +// support cs_option() for all archs +static 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 +#ifdef CAPSTONE_HAS_M68K + M68K_option, +#else + NULL, +#endif +#ifdef CAPSTONE_HAS_TMS320C64X + TMS320C64x_option, +#else + NULL, +#endif +#ifdef CAPSTONE_HAS_M680X + M680X_option, +#else + NULL, +#endif +#ifdef CAPSTONE_HAS_EVM + EVM_option, +#else + NULL, +#endif +}; - initialized = true; -} +// bitmask for finding disallowed modes for an arch: +// to be called in cs_open()/cs_option() +static 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_BIG_ENDIAN | CS_MODE_MIPS2 | CS_MODE_MIPS3), +#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 + | CS_MODE_QPX), +#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 +#ifdef CAPSTONE_HAS_M68K + ~(CS_MODE_BIG_ENDIAN | CS_MODE_M68K_000 | CS_MODE_M68K_010 | CS_MODE_M68K_020 + | CS_MODE_M68K_030 | CS_MODE_M68K_040 | CS_MODE_M68K_060), +#else + 0, +#endif +#ifdef CAPSTONE_HAS_TMS320C64X + ~(CS_MODE_BIG_ENDIAN), +#else + 0, +#endif +#ifdef CAPSTONE_HAS_M680X + ~(CS_MODE_M680X_6301 | CS_MODE_M680X_6309 | CS_MODE_M680X_6800 + | CS_MODE_M680X_6801 | CS_MODE_M680X_6805 | CS_MODE_M680X_6808 + | CS_MODE_M680X_6809 | CS_MODE_M680X_6811 | CS_MODE_M680X_CPU12 + | CS_MODE_M680X_HCS08), +#else + 0, +#endif +#ifdef CAPSTONE_HAS_EVM + 0, +#else + 0, +#endif +}; + +// bitmask of enabled architectures +static uint32_t all_arch = 0 +#ifdef CAPSTONE_HAS_ARM + | (1 << CS_ARCH_ARM) +#endif +#ifdef CAPSTONE_HAS_ARM64 + | (1 << CS_ARCH_ARM64) +#endif +#ifdef CAPSTONE_HAS_MIPS + | (1 << CS_ARCH_MIPS) +#endif +#ifdef CAPSTONE_HAS_X86 + | (1 << CS_ARCH_X86) +#endif +#ifdef CAPSTONE_HAS_POWERPC + | (1 << CS_ARCH_PPC) +#endif +#ifdef CAPSTONE_HAS_SPARC + | (1 << CS_ARCH_SPARC) +#endif +#ifdef CAPSTONE_HAS_SYSZ + | (1 << CS_ARCH_SYSZ) +#endif +#ifdef CAPSTONE_HAS_XCORE + | (1 << CS_ARCH_XCORE) +#endif +#ifdef CAPSTONE_HAS_M68K + | (1 << CS_ARCH_M68K) +#endif +#ifdef CAPSTONE_HAS_TMS320C64X + | (1 << CS_ARCH_TMS320C64X) +#endif +#ifdef CAPSTONE_HAS_M680X + | (1 << CS_ARCH_M680X) +#endif +#ifdef CAPSTONE_HAS_EVM + | (1 << CS_ARCH_EVM) +#endif +; -unsigned int all_arch = 0; #if defined(CAPSTONE_USE_SYS_DYN_MEM) #if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE) @@ -171,8 +358,6 @@ cs_vsnprintf_t cs_vsnprintf = NULL; 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; @@ -184,8 +369,6 @@ unsigned int CAPSTONE_API cs_version(int *major, int *minor) 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) | @@ -278,9 +461,13 @@ cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle) // 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]) { + *handle = 0; + return CS_ERR_MODE; + } + ud = cs_mem_calloc(1, sizeof(*ud)); if (!ud) { // memory insufficient @@ -290,7 +477,6 @@ cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle) ud->errnum = CS_ERR_OK; ud->arch = arch; ud->mode = mode; - ud->big_endian = (mode & CS_MODE_BIG_ENDIAN) != 0; // by default, do not break instruction into details ud->detail = CS_OPT_OFF; @@ -464,8 +650,6 @@ cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value) struct cs_struct *handle; cs_opt_mnem *opt; - 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()) if (type == CS_OPT_MEM) { @@ -566,6 +750,13 @@ cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value) } } return CS_ERR_OK; + + case CS_OPT_MODE: + // verify if requested mode is valid + if (value & cs_arch_disallowed_mode_mask[handle->arch]) { + return CS_ERR_OPTION; + } + break; } return cs_arch_option[handle->arch](handle, type, value); diff --git a/cs_priv.h b/cs_priv.h index c0c4eccb..0aa07386 100644 --- a/cs_priv.h +++ b/cs_priv.h @@ -55,7 +55,6 @@ struct cs_struct { void *printer_info; // aux info for printer Disasm_t disasm; // disassembler void *getinsn_info; // auxiliary info for printer - bool big_endian; GetName_t reg_name; GetName_t insn_name; GetName_t group_name; @@ -78,13 +77,8 @@ struct cs_struct { #define MAX_ARCH CS_ARCH_MAX -// constructor initialization for all archs -extern cs_err (*cs_arch_init[MAX_ARCH]) (cs_struct *); - -// support cs_option() for all archs -extern cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct*, cs_opt_type, size_t value); - -extern unsigned int all_arch; +// Returns a bool (0 or 1) whether big endian is enabled for a mode +#define MODE_IS_BIG_ENDIAN(mode) (((mode) & CS_MODE_BIG_ENDIAN) != 0) extern cs_malloc_t cs_mem_malloc; extern cs_calloc_t cs_mem_calloc;