From 34d49d935b7ea89a82c6165d5cf3db6638f34c17 Mon Sep 17 00:00:00 2001 From: danghvu Date: Thu, 19 Dec 2013 12:10:24 -0600 Subject: [PATCH] Support compilation of individual arch --- Makefile | 22 +++- arch.h | 21 ++++ arch/AArch64/include.h | 26 +++++ arch/ARM/include.h | 30 +++++ arch/Mips/include.h | 29 +++++ arch/X86/include.h | 23 ++++ cs.c | 244 ++++++++++++++--------------------------- 7 files changed, 232 insertions(+), 163 deletions(-) create mode 100644 arch.h create mode 100644 arch/AArch64/include.h create mode 100644 arch/ARM/include.h create mode 100644 arch/Mips/include.h create mode 100644 arch/X86/include.h diff --git a/Makefile b/Makefile index e4e4fd53..0fa86a64 100644 --- a/Makefile +++ b/Makefile @@ -19,12 +19,26 @@ INSTALL_LIBRARY ?= install -m0755 LIBNAME = capstone +CAPSTONE_ARCHS = arm x86 mips aarch64 + LIBOBJ = LIBOBJ += cs.o utils.o SStream.o MCInstrDesc.o MCRegisterInfo.o -LIBOBJ += arch/Mips/MipsDisassembler.o arch/Mips/MipsInstPrinter.o arch/Mips/mapping.o -LIBOBJ += arch/AArch64/AArch64BaseInfo.o arch/AArch64/AArch64Disassembler.o arch/AArch64/AArch64InstPrinter.o arch/AArch64/mapping.o -LIBOBJ += arch/ARM/ARMDisassembler.o arch/ARM/ARMInstPrinter.o arch/ARM/mapping.o -LIBOBJ += arch/X86/X86DisassemblerDecoder.o arch/X86/X86Disassembler.o arch/X86/X86IntelInstPrinter.o arch/X86/X86ATTInstPrinter.o arch/X86/mapping.o +ifneq (,$(findstring arm,$(CAPSTONE_ARCHS))) + LIBOBJ += arch/ARM/ARMDisassembler.o arch/ARM/ARMInstPrinter.o arch/ARM/mapping.o + CFLAGS += -DCS_SUPPORT_ARM +endif +ifneq (,$(findstring x86,$(CAPSTONE_ARCHS))) + LIBOBJ += arch/X86/X86DisassemblerDecoder.o arch/X86/X86Disassembler.o arch/X86/X86IntelInstPrinter.o arch/X86/X86ATTInstPrinter.o arch/X86/mapping.o + CFLAGS += -DCS_SUPPORT_X86 +endif +ifneq (,$(findstring mips,$(CAPSTONE_ARCHS))) + LIBOBJ += arch/Mips/MipsDisassembler.o arch/Mips/MipsInstPrinter.o arch/Mips/mapping.o + CFLAGS += -DCS_SUPPORT_AARCH64 +endif +ifneq (,$(findstring aarch64,$(CAPSTONE_ARCHS))) + LIBOBJ += arch/AArch64/AArch64BaseInfo.o arch/AArch64/AArch64Disassembler.o arch/AArch64/AArch64InstPrinter.o arch/AArch64/mapping.o + CFLAGS += -DCS_SUPPORT_MIPS +endif LIBOBJ += MCInst.o EXT = so diff --git a/arch.h b/arch.h new file mode 100644 index 00000000..ee9573b0 --- /dev/null +++ b/arch.h @@ -0,0 +1,21 @@ +#ifndef __ARCH_H__ +#define __ARCH_H__ + +#define MAX_ARCH 32 + +void (*init_arch[MAX_ARCH]) (cs_struct *); + +#ifdef CS_SUPPORT_X86 +#include "arch/X86/include.h" +#endif +#ifdef CS_SUPPORT_ARM +#include "arch/ARM/include.h" +#endif +#ifdef CS_SUPPORT_AARCH64 +#include "arch/AArch64/include.h" +#endif +#ifdef CS_SUPPORT_MIPS +#include "arch/Mips/include.h" +#endif + +#endif diff --git a/arch/AArch64/include.h b/arch/AArch64/include.h new file mode 100644 index 00000000..ef775e4a --- /dev/null +++ b/arch/AArch64/include.h @@ -0,0 +1,26 @@ +#ifndef __ARM64_INCLUDE_H__ +#define __ARM64_INCLUDE_H__ + +#include "AArch64Disassembler.h" +#include "AArch64InstPrinter.h" +#include "mapping.h" + +void init_arm64(cs_struct *ud) { + MCRegisterInfo *mri = malloc(sizeof(*mri)); + + AArch64_init(mri); + ud->printer = AArch64_printInst; + ud->printer_info = mri; + ud->getinsn_info = mri; + ud->disasm = AArch64_getInstruction; + ud->reg_name = AArch64_reg_name; + ud->insn_id = AArch64_get_insn_id; + ud->insn_name = AArch64_insn_name; + ud->post_printer = AArch64_post_printer; +} + +void __attribute__ ((constructor)) __init_arm64__() { + init_arch[CS_ARCH_ARM64] = init_arm64; +} + +#endif diff --git a/arch/ARM/include.h b/arch/ARM/include.h new file mode 100644 index 00000000..ae43281a --- /dev/null +++ b/arch/ARM/include.h @@ -0,0 +1,30 @@ +#ifndef __ARM_INCLUDE_H__ +#define __ARM_INCLUDE_H__ + +#include "ARMDisassembler.h" +#include "ARMInstPrinter.h" +#include "mapping.h" + +void init_arm(cs_struct *ud) { + MCRegisterInfo *mri = malloc(sizeof(*mri)); + + ARM_init(mri); + + ud->printer = ARM_printInst; + ud->printer_info = mri; + ud->reg_name = ARM_reg_name; + ud->insn_id = ARM_get_insn_id; + ud->insn_name = ARM_insn_name; + ud->post_printer = ARM_post_printer; + + if (ud->mode & CS_MODE_THUMB) + ud->disasm = Thumb_getInstruction; + else + ud->disasm = ARM_getInstruction; +} + +void __attribute__ ((constructor)) __init_arm__() { + init_arch[CS_ARCH_ARM] = init_arm; +} + +#endif diff --git a/arch/Mips/include.h b/arch/Mips/include.h new file mode 100644 index 00000000..6a1158eb --- /dev/null +++ b/arch/Mips/include.h @@ -0,0 +1,29 @@ +#ifndef __MIPS_INCLUDE_H__ +#define __MIPS_INCLUDE_H__ + +#include "MipsDisassembler.h" +#include "MipsInstPrinter.h" +#include "mapping.h" + +void init_mips(cs_struct *ud) { + MCRegisterInfo *mri = malloc(sizeof(*mri)); + + Mips_init(mri); + ud->printer = Mips_printInst; + ud->printer_info = mri; + ud->getinsn_info = mri; + ud->reg_name = Mips_reg_name; + ud->insn_id = Mips_get_insn_id; + ud->insn_name = Mips_insn_name; + + if (ud->mode & CS_MODE_32) + ud->disasm = Mips_getInstruction; + else + ud->disasm = Mips64_getInstruction; +} + +void __attribute__ ((constructor)) __init_mips__() { + init_arch[CS_ARCH_MIPS] = init_mips; +} + +#endif diff --git a/arch/X86/include.h b/arch/X86/include.h new file mode 100644 index 00000000..ee942981 --- /dev/null +++ b/arch/X86/include.h @@ -0,0 +1,23 @@ +#ifndef __X86_INCLUDE_H__ +#define __X86_INCLUDE_H__ + +#include "X86Disassembler.h" +#include "X86InstPrinter.h" +#include "mapping.h" + +void init_x86(cs_struct *ud) { + // by default, we use Intel syntax + ud->printer = X86_Intel_printInst; + ud->printer_info = NULL; + ud->disasm = X86_getInstruction; + ud->reg_name = X86_reg_name; + ud->insn_id = X86_get_insn_id; + ud->insn_name = X86_insn_name; + ud->post_printer = X86_post_printer; +} + +void __attribute__ ((constructor)) __init_x86__() { + init_arch[CS_ARCH_X86] = init_x86; +} + +#endif diff --git a/cs.c b/cs.c index e69febb3..32d4c676 100644 --- a/cs.c +++ b/cs.c @@ -10,25 +10,9 @@ #include "MCRegisterInfo.h" -#include "arch/X86/X86Disassembler.h" -#include "arch/X86/X86InstPrinter.h" -#include "arch/X86/mapping.h" - -#include "arch/ARM/ARMDisassembler.h" -#include "arch/ARM/ARMInstPrinter.h" -#include "arch/ARM/mapping.h" - -#include "arch/Mips/MipsDisassembler.h" -#include "arch/Mips/MipsInstPrinter.h" -#include "arch/Mips/mapping.h" - -#include "arch/AArch64/AArch64Disassembler.h" -#include "arch/AArch64/AArch64InstPrinter.h" -#include "arch/AArch64/mapping.h" - +#include "arch.h" #include "utils.h" - void cs_version(int *major, int *minor) { *major = CS_API_MAJOR; @@ -47,90 +31,26 @@ cs_err cs_errno(csh handle) cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) { - cs_struct *ud; + cs_struct *ud; - ud = calloc(1, sizeof(*ud)); - if (!ud) { - // memory insufficient - return CS_ERR_MEM; - } + ud = calloc(1, sizeof(*ud)); + if (!ud) { + // memory insufficient + return CS_ERR_MEM; + } - ud->errnum = CS_ERR_OK; - ud->arch = arch; - ud->mode = mode; - ud->big_endian = mode & CS_MODE_BIG_ENDIAN; - ud->reg_name = NULL; - ud->detail = CS_OPT_ON; // by default break instruction into details + ud->errnum = CS_ERR_OK; + ud->arch = arch; + ud->mode = mode; + ud->big_endian = mode & CS_MODE_BIG_ENDIAN; + ud->reg_name = NULL; + ud->detail = CS_OPT_ON; // by default break instruction into details - switch (ud->arch) { - case CS_ARCH_X86: - // by default, we use Intel syntax - ud->printer = X86_Intel_printInst; - ud->printer_info = NULL; - ud->disasm = X86_getInstruction; - ud->reg_name = X86_reg_name; - ud->insn_id = X86_get_insn_id; - ud->insn_name = X86_insn_name; - ud->post_printer = X86_post_printer; - break; - case CS_ARCH_ARM: { - MCRegisterInfo *mri = malloc(sizeof(*mri)); - - ARM_init(mri); - - ud->printer = ARM_printInst; - ud->printer_info = mri; - ud->reg_name = ARM_reg_name; - ud->insn_id = ARM_get_insn_id; - ud->insn_name = ARM_insn_name; - ud->post_printer = ARM_post_printer; - - if (ud->mode & CS_MODE_THUMB) - ud->disasm = Thumb_getInstruction; - else - ud->disasm = ARM_getInstruction; - break; - } - case CS_ARCH_MIPS: { - MCRegisterInfo *mri = malloc(sizeof(*mri)); - - Mips_init(mri); - ud->printer = Mips_printInst; - ud->printer_info = mri; - ud->getinsn_info = mri; - ud->reg_name = Mips_reg_name; - ud->insn_id = Mips_get_insn_id; - ud->insn_name = Mips_insn_name; - - if (ud->mode & CS_MODE_32) - ud->disasm = Mips_getInstruction; - else - ud->disasm = Mips64_getInstruction; - - break; - } - case CS_ARCH_ARM64: { - MCRegisterInfo *mri = malloc(sizeof(*mri)); - - AArch64_init(mri); - ud->printer = AArch64_printInst; - ud->printer_info = mri; - ud->getinsn_info = mri; - ud->disasm = AArch64_getInstruction; - ud->reg_name = AArch64_reg_name; - ud->insn_id = AArch64_get_insn_id; - ud->insn_name = AArch64_insn_name; - ud->post_printer = AArch64_post_printer; - break; - } - default: // unsupported architecture - free(ud); - return CS_ERR_ARCH; - } + init_arch[ud->arch](ud); - *handle = (uintptr_t)ud; + *handle = (uintptr_t)ud; - return CS_ERR_OK; + return CS_ERR_OK; } cs_err cs_close(csh handle) @@ -209,69 +129,75 @@ static void fill_insn(cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mc cs_err cs_option(csh ud, cs_opt_type type, size_t value) { - cs_struct *handle = (cs_struct *)(uintptr_t)ud; - if (!handle) - return CS_ERR_CSH; - - switch(type) { - default: - break; - case CS_OPT_DETAIL: - handle->detail = value; - return CS_ERR_OK; - case CS_OPT_SYNTAX: - switch (handle->arch) { - default: - // only selected archs care about CS_OPT_SYNTAX - handle->errnum = CS_ERR_OPTION; - return CS_ERR_OPTION; - - case CS_ARCH_X86: - switch(value) { - default: - // wrong syntax value - handle->errnum = CS_ERR_OPTION; - return CS_ERR_OPTION; - - case CS_OPT_SYNTAX_INTEL: - handle->printer = X86_Intel_printInst; - break; - - case CS_OPT_SYNTAX_ATT: - handle->printer = X86_ATT_printInst; - break; - } - break; - } - break; - - case CS_OPT_MODE: // change engine's mode at run-time - handle->mode = value; - switch (handle->arch) { - default: - // only selected archs care about CS_OPT_SYNTAX - break; - case CS_ARCH_ARM: - if (value & CS_MODE_THUMB) - handle->disasm = Thumb_getInstruction; - else - handle->disasm = ARM_getInstruction; - - handle->mode = value; - break; - case CS_ARCH_MIPS: - if (value & CS_MODE_32) - handle->disasm = Mips_getInstruction; - else - handle->disasm = Mips64_getInstruction; - - handle->mode = value; - break; - } - break; - } - - return CS_ERR_OK; + cs_struct *handle = (cs_struct *)(uintptr_t)ud; + if (!handle) + return CS_ERR_CSH; + + switch(type) { + default: + break; + case CS_OPT_DETAIL: + handle->detail = value; + return CS_ERR_OK; + case CS_OPT_SYNTAX: + switch (handle->arch) { + default: + // only selected archs care about CS_OPT_SYNTAX + handle->errnum = CS_ERR_OPTION; + return CS_ERR_OPTION; + +#ifdef CS_SUPPORT_X86 + case CS_ARCH_X86: + switch(value) { + default: + // wrong syntax value + handle->errnum = CS_ERR_OPTION; + return CS_ERR_OPTION; + + case CS_OPT_SYNTAX_INTEL: + handle->printer = X86_Intel_printInst; + break; + + case CS_OPT_SYNTAX_ATT: + handle->printer = X86_ATT_printInst; + break; + } + break; +#endif + } + break; + + case CS_OPT_MODE: // change engine's mode at run-time + handle->mode = value; + switch (handle->arch) { + default: + // only selected archs care about CS_OPT_SYNTAX + break; +#ifdef CS_SUPPORT_ARM + case CS_ARCH_ARM: + if (value & CS_MODE_THUMB) + handle->disasm = Thumb_getInstruction; + else + handle->disasm = ARM_getInstruction; + + handle->mode = value; + break; +#endif +#ifdef CS_SUPPORT_AARCH64 + case CS_ARCH_MIPS: + if (value & CS_MODE_32) + handle->disasm = Mips_getInstruction; + else + handle->disasm = Mips64_getInstruction; + + handle->mode = value; + break; +#endif + } + break; + } + + return CS_ERR_OK; } size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn *insn)