diff --git a/arch/AArch64/mapping.c b/arch/AArch64/mapping.c index 73ad3003..3c773733 100644 --- a/arch/AArch64/mapping.c +++ b/arch/AArch64/mapping.c @@ -2991,18 +2991,16 @@ static insn_map alias_insns[] = { // { AArch64_SUBSxxx_lsl, ARM64_INS_NEGS, { 0 }, { ARM64_REG_NZCV, 0 }, { 0 } }, }; -static unsigned short *insn_cache = NULL; - // given internal insn id, return public instruction info -void AArch64_get_insn_id(cs_insn *insn, unsigned int id, int detail) +void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) { - int i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) { insn->id = insns[i].mapid; - if (detail) { + if (h->detail) { cs_struct handle; - handle.detail = detail; + handle.detail = h->detail; memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); insn->detail->regs_read_count = count_positive(insns[i].regs_use); @@ -3527,9 +3525,8 @@ arm64_reg AArch64_map_insn(const char *name) return (i != -1)? i : ARM64_REG_INVALID; } -void AArch64_free_cache(void) +void AArch64_free_cache(cs_struct *h) { - my_free(insn_cache); - - insn_cache = NULL; + my_free(h->insn_cache); + h->insn_cache = NULL; } diff --git a/arch/AArch64/mapping.h b/arch/AArch64/mapping.h index 4bcd40df..402ee83a 100644 --- a/arch/AArch64/mapping.h +++ b/arch/AArch64/mapping.h @@ -11,7 +11,7 @@ const char *AArch64_reg_name(csh handle, unsigned int reg); // given internal insn id, return public instruction info -void AArch64_get_insn_id(cs_insn *insn, unsigned int id, int detail); +void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); // given public insn id, return internal instruction ID unsigned int AArch64_get_insn_id2(unsigned int id); @@ -22,6 +22,6 @@ const char *AArch64_insn_name(csh handle, unsigned int id); arm64_reg AArch64_map_insn(const char *name); // free insn cache -void AArch64_free_cache(void); +void AArch64_free_cache(cs_struct *h); #endif diff --git a/arch/AArch64/module.c b/arch/AArch64/module.c index 60f96549..9d288893 100644 --- a/arch/AArch64/module.c +++ b/arch/AArch64/module.c @@ -32,7 +32,7 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) static void destroy(cs_struct *handle) { - AArch64_free_cache(); + AArch64_free_cache(handle); } static void __attribute__ ((constructor)) __init_arm64__() diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c index e3f7d49f..07ef651c 100644 --- a/arch/ARM/ARMInstPrinter.c +++ b/arch/ARM/ARMInstPrinter.c @@ -563,7 +563,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) // to reflect absolute address. // Note: in ARM, PC is always 2 instructions ahead, so we have to // add 8 in ARM mode, or 4 in Thumb mode - if (ARM_rel_branch(MCInst_getOpcode(MI))) { + if (ARM_rel_branch(MI->csh, MCInst_getOpcode(MI))) { // only do this for relative branch if (MI->csh->mode & CS_MODE_THUMB) imm += MI->address + 4; diff --git a/arch/ARM/mapping.c b/arch/ARM/mapping.c index 1a1e5d1d..042fd8f4 100644 --- a/arch/ARM/mapping.c +++ b/arch/ARM/mapping.c @@ -2301,17 +2301,15 @@ static insn_map insns[] = { }; -static unsigned short *insn_cache = NULL; - -void ARM_get_insn_id(cs_insn *insn, unsigned int id, int detail) +void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) { - int i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) { insn->id = insns[i].mapid; - if (detail) { + if (h->detail) { cs_struct handle; - handle.detail = detail; + handle.detail = h->detail; memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); insn->detail->regs_read_count = count_positive(insns[i].regs_use); @@ -2791,9 +2789,9 @@ arm_reg ARM_map_insn(const char *name) return (i != -1)? i : ARM_REG_INVALID; } -bool ARM_rel_branch(unsigned int id) +bool ARM_rel_branch(cs_struct *h, unsigned int id) { - int i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) return (insns[i].branch && !insns[i].indirect_branch); else { @@ -2802,9 +2800,8 @@ bool ARM_rel_branch(unsigned int id) } } -void ARM_free_cache(void) +void ARM_free_cache(cs_struct *h) { - my_free(insn_cache); - - insn_cache = NULL; + my_free(h->insn_cache); + h->insn_cache = NULL; } diff --git a/arch/ARM/mapping.h b/arch/ARM/mapping.h index 62b8d92e..4aebd1dc 100644 --- a/arch/ARM/mapping.h +++ b/arch/ARM/mapping.h @@ -12,7 +12,7 @@ const char *ARM_reg_name(csh handle, unsigned int reg); // given internal insn id, return public instruction ID -void ARM_get_insn_id(cs_insn *insn, unsigned int id, int detail); +void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); // given public insn id, return internal instruction info unsigned int ARM_get_insn_id2(unsigned int id); @@ -23,9 +23,9 @@ const char *ARM_insn_name(csh handle, unsigned int id); arm_reg ARM_map_insn(const char *name); // check if this insn is relative branch -bool ARM_rel_branch(unsigned int insn_id); +bool ARM_rel_branch(cs_struct *h, unsigned int insn_id); // free insn cache -void ARM_free_cache(void); +void ARM_free_cache(cs_struct *h); #endif diff --git a/arch/ARM/module.c b/arch/ARM/module.c index e5f4131a..dde4b5f4 100644 --- a/arch/ARM/module.c +++ b/arch/ARM/module.c @@ -45,7 +45,7 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) static void destroy(cs_struct *handle) { - ARM_free_cache(); + ARM_free_cache(handle); } static void __attribute__ ((constructor)) __init_arm__() diff --git a/arch/Mips/mapping.c b/arch/Mips/mapping.c index 3975da73..a2fa1ae5 100644 --- a/arch/Mips/mapping.c +++ b/arch/Mips/mapping.c @@ -1388,10 +1388,8 @@ static insn_map alias_insns[] = { { Mips_SUBu, MIPS_INS_NEGU, { 0 }, { 0 }, { MIPS_GRP_STDENC, 0 }, 0, 0 }, }; -static unsigned short *insn_cache = NULL; - // given internal insn id, return public instruction info -void Mips_get_insn_id(cs_insn *insn, unsigned int id, int detail) +void Mips_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) { int i; @@ -1400,7 +1398,7 @@ void Mips_get_insn_id(cs_insn *insn, unsigned int id, int detail) if (alias_insns[i].id == id) { insn->id = alias_insns[i].mapid; - if (detail) { + if (h->detail) { memcpy(insn->detail->regs_read, alias_insns[i].regs_use, sizeof(alias_insns[i].regs_use)); insn->detail->regs_read_count = count_positive(alias_insns[i].regs_use); @@ -1421,11 +1419,11 @@ void Mips_get_insn_id(cs_insn *insn, unsigned int id, int detail) } } - i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) { insn->id = insns[i].mapid; - if (detail) { + if (h->detail) { memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); insn->detail->regs_read_count = count_positive(insns[i].regs_use); @@ -2035,9 +2033,8 @@ mips_reg Mips_map_register(unsigned int r) return 0; } -void Mips_free_cache(void) +void Mips_free_cache(cs_struct *h) { - my_free(insn_cache); - - insn_cache = NULL; + my_free(h->insn_cache); + h->insn_cache = NULL; } diff --git a/arch/Mips/mapping.h b/arch/Mips/mapping.h index 7d9e74cf..3c1eb2cc 100644 --- a/arch/Mips/mapping.h +++ b/arch/Mips/mapping.h @@ -11,7 +11,7 @@ const char *Mips_reg_name(csh handle, unsigned int reg); // given internal insn id, return public instruction info -void Mips_get_insn_id(cs_insn *insn, unsigned int id, int detail); +void Mips_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); // given public insn id, return internal insn id unsigned int Mips_get_insn_id2(unsigned int id); @@ -26,6 +26,6 @@ mips_reg Mips_map_insn(const char *name); mips_reg Mips_map_register(unsigned int r); // free insn cache -void Mips_free_cache(void); +void Mips_free_cache(cs_struct *h); #endif diff --git a/arch/Mips/module.c b/arch/Mips/module.c index 13fbd671..21c193f3 100644 --- a/arch/Mips/module.c +++ b/arch/Mips/module.c @@ -43,7 +43,7 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) static void destroy(cs_struct *handle) { - Mips_free_cache(); + Mips_free_cache(handle); } static void __attribute__ ((constructor)) __init_mips__() diff --git a/arch/PowerPC/mapping.c b/arch/PowerPC/mapping.c index f63331ee..a61e6d26 100644 --- a/arch/PowerPC/mapping.c +++ b/arch/PowerPC/mapping.c @@ -917,10 +917,8 @@ static insn_map insns[] = { static insn_map alias_insns[] = { }; -static unsigned short *insn_cache = NULL; - // given internal insn id, return public instruction info -void PPC_get_insn_id(cs_insn *insn, unsigned int id, int detail) +void PPC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) { int i; @@ -929,9 +927,9 @@ void PPC_get_insn_id(cs_insn *insn, unsigned int id, int detail) if (alias_insns[i].id == id) { insn->id = alias_insns[i].mapid; - if (detail) { + if (h->detail) { cs_struct handle; - handle.detail = detail; + handle.detail = h->detail; memcpy(insn->detail->regs_read, alias_insns[i].regs_use, sizeof(alias_insns[i].regs_use)); insn->detail->regs_read_count = count_positive(alias_insns[i].regs_use); @@ -954,13 +952,13 @@ void PPC_get_insn_id(cs_insn *insn, unsigned int id, int detail) } } - i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) { insn->id = insns[i].mapid; - if (detail) { + if (h->detail) { cs_struct handle; - handle.detail = detail; + handle.detail = h->detail; memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); insn->detail->regs_read_count = count_positive(insns[i].regs_use); @@ -1516,9 +1514,8 @@ ppc_reg PPC_map_register(unsigned int r) return 0; } -void PPC_free_cache(void) +void PPC_free_cache(cs_struct *h) { - my_free(insn_cache); - - insn_cache = NULL; + my_free(h->insn_cache); + h->insn_cache = NULL; } diff --git a/arch/PowerPC/mapping.h b/arch/PowerPC/mapping.h index 13c886bc..0eb19d4e 100644 --- a/arch/PowerPC/mapping.h +++ b/arch/PowerPC/mapping.h @@ -11,7 +11,7 @@ const char *PPC_reg_name(csh handle, unsigned int reg); // given internal insn id, return public instruction info -void PPC_get_insn_id(cs_insn *insn, unsigned int id, int detail); +void PPC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); // given public insn id, return internal insn id unsigned int PPC_get_insn_id2(unsigned int id); @@ -26,7 +26,7 @@ ppc_reg PPC_map_insn(const char *name); ppc_reg PPC_map_register(unsigned int r); // free insn cache -void PPC_free_cache(void); +void PPC_free_cache(cs_struct *); #endif diff --git a/arch/PowerPC/module.c b/arch/PowerPC/module.c index 9ab62116..90f7fa7a 100644 --- a/arch/PowerPC/module.c +++ b/arch/PowerPC/module.c @@ -36,7 +36,7 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) static void destroy(cs_struct *handle) { - PPC_free_cache(); + PPC_free_cache(handle); } static void __attribute__ ((constructor)) __init_mips__() diff --git a/arch/X86/mapping.c b/arch/X86/mapping.c index eb0f6a12..953907dd 100644 --- a/arch/X86/mapping.c +++ b/arch/X86/mapping.c @@ -6605,16 +6605,14 @@ void X86_post_printer(csh handle, cs_insn *insn, char *insn_asm) } } -static unsigned short *insn_cache = NULL; - // given internal insn id, return public instruction info -void X86_get_insn_id(cs_insn *insn, unsigned int id, int detail) +void X86_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) { - int i = insn_find(insns, ARR_SIZE(insns), id, &insn_cache); + int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); if (i != 0) { insn->id = insns[i].mapid; - if (detail) { + if (h->detail) { memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); insn->detail->regs_read_count = count_positive(insns[i].regs_use); @@ -6639,8 +6637,8 @@ unsigned int X86_get_insn_id2(unsigned int id) return insn_reverse_id(insns, ARR_SIZE(insns), id); } -void X86_free_cache(void) +void X86_free_cache(cs_struct *h) { - my_free(insn_cache); - insn_cache = NULL; + my_free(h->insn_cache); + h->insn_cache = NULL; } diff --git a/arch/X86/mapping.h b/arch/X86/mapping.h index 10656268..d164bb98 100644 --- a/arch/X86/mapping.h +++ b/arch/X86/mapping.h @@ -6,6 +6,7 @@ #include "../../include/capstone.h" #include "../../include/x86.h" +#include "../../cs_priv.h" // map sib_base to x86_reg x86_reg x86_map_sib_base(int r); @@ -23,7 +24,7 @@ x86_reg x86_map_regname(const char *reg); const char *X86_reg_name(csh handle, unsigned int reg); // given internal insn id, return public instruction info -void X86_get_insn_id(cs_insn *insn, unsigned int id, int detail); +void X86_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); // return insn name, given insn id const char *X86_insn_name(csh handle, unsigned int id); @@ -38,6 +39,6 @@ unsigned int X86_get_insn_id2(unsigned int insn_id); void X86_post_printer(csh handle, cs_insn *pub_insn, char *insn_asm); // free insn cache -void X86_free_cache(void); +void X86_free_cache(cs_struct *h); #endif diff --git a/arch/X86/module.c b/arch/X86/module.c index eab9f4c5..428373a1 100644 --- a/arch/X86/module.c +++ b/arch/X86/module.c @@ -46,7 +46,7 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) static void destroy(cs_struct *handle) { - X86_free_cache(); + X86_free_cache(handle); } static void __attribute__ ((constructor)) __init_x86__() diff --git a/bindings/python/test.py b/bindings/python/test.py index 37555b1b..4e911c28 100755 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -28,7 +28,7 @@ all_tests = ( (CS_ARCH_ARM, CS_MODE_THUMB, THUMB_CODE, "THUMB", 0), (CS_ARCH_MIPS, CS_MODE_32 + CS_MODE_BIG_ENDIAN, MIPS_CODE, "MIPS-32 (Big-endian)", 0), (CS_ARCH_MIPS, CS_MODE_64+ CS_MODE_LITTLE_ENDIAN, MIPS_CODE2, "MIPS-64-EL (Little-endian)", 0), - (CS_ARCH_ARM64, CS_MODE_ARM, ARM64_CODE, "ARM-64", 0), + (CS_ARCH_ARM64, CS_MODE_ARM, ARM64_CODE, "ARM-64", 0), (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64", 0), ) diff --git a/cs.c b/cs.c index 8ee19fec..5e424d7a 100644 --- a/cs.c +++ b/cs.c @@ -138,8 +138,7 @@ cs_err cs_close(csh handle) return CS_ERR_HANDLE; } - if (arch_destroy[ud->arch]) - arch_destroy[ud->arch](ud); + arch_destroy[ud->arch](ud); memset(ud, 0, sizeof(*ud)); my_free(ud); @@ -174,7 +173,7 @@ static void fill_insn(cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mc // map internal instruction opcode to public insn ID if (handle->insn_id) - handle->insn_id(insn, MCInst_getOpcode(mci), handle->detail); + handle->insn_id(handle, insn, MCInst_getOpcode(mci)); // alias instruction might have ID saved in OpcodePub if (MCInst_getOpcodePub(mci)) diff --git a/cs_priv.h b/cs_priv.h index 56b98a4a..eb7e3793 100644 --- a/cs_priv.h +++ b/cs_priv.h @@ -19,7 +19,7 @@ typedef bool (*Disasm_t)(csh handle, const uint8_t *code, size_t code_len, MCIns typedef const char *(*GetName_t)(csh handle, unsigned int reg); -typedef void (*GetID_t)(cs_insn *insn, unsigned int id, int detail); +typedef void (*GetID_t)(cs_struct *h, cs_insn *insn, unsigned int id); // for ARM only typedef struct ARM_ITStatus { @@ -44,6 +44,7 @@ struct cs_struct { cs_opt_value detail; int syntax; // asm syntax for simple printer such as PPC bool doing_mem; // handling memory operand in InstPrinter code + unsigned short *insn_cache; // index caching for mapping.c }; #define MAX_ARCH 8