From cc7d686d82fa565ff885e2015cca4f3f77475ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 30 Dec 2021 01:05:28 +0100 Subject: [PATCH] Add partial support for an ultra-lightweight profile Where Capstone only understands the small subset of instructions that Frida needs for its relocators. --- .gitignore | 3 ++ arch/AArch64/AArch64Disassembler.c | 22 +++++++++ arch/AArch64/AArch64InstPrinter.c | 13 +++++ arch/AArch64/AArch64Mapping.c | 35 +++++++++++-- arch/AArch64/AArch64Module.c | 8 +-- arch/ARM/ARMDisassembler.c | 79 ++++++++++++++++++++++++++++++ arch/ARM/ARMInstPrinter.c | 11 +++++ arch/ARM/ARMMapping.c | 30 +++++++++++- arch/ARM/ARMModule.c | 6 ++- arch/PowerPC/PPCMapping.c | 2 + arch/X86/X86Disassembler.c | 35 +++++++++++++ arch/X86/X86DisassemblerDecoder.c | 2 +- arch/X86/X86InstPrinterCommon.c | 2 +- arch/X86/X86IntelInstPrinter.c | 10 ++++ arch/X86/X86Mapping.c | 11 +++++ arch/X86/X86Module.c | 8 +-- cs.c | 16 +++++- cs_priv.h | 2 + meson.build | 20 +++++++- meson_options.txt | 18 ++++--- subprojects/fadec.wrap | 7 +++ utils.c | 4 ++ 22 files changed, 320 insertions(+), 24 deletions(-) create mode 100644 subprojects/fadec.wrap diff --git a/.gitignore b/.gitignore index 2ffc794f2b2..b1a1b13542d 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,6 @@ android-ndk-* # python virtual env .venv/ + +# Meson +/subprojects/fadec/ diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c index 93bf9510921..c136bb1e136 100644 --- a/arch/AArch64/AArch64Disassembler.c +++ b/arch/AArch64/AArch64Disassembler.c @@ -42,6 +42,8 @@ #include "AArch64Linkage.h" #include "AArch64Mapping.h" +#ifndef CAPSTONE_TINY + #define GET_INSTRINFO_MC_DESC #include "AArch64GenInstrInfo.inc" @@ -2157,3 +2159,23 @@ static DecodeStatus DecodePRFMRegInstruction(MCInst *Inst, uint32_t insn, return Success; } + +#else + +DecodeStatus AArch64_LLVM_getInstruction(csh handle, const uint8_t *Bytes, + size_t ByteLen, MCInst *MI, uint16_t *Size, uint64_t Address, + void *Info) +{ + if (ByteLen < 4) { + // not enough data + *Size = 0; + return MCDisassembler_Fail; + } + + MCInst_setOpcode(MI, AArch64_INS_ALIAS_END); + *Size = 4; + + return MCDisassembler_Success; +} + +#endif diff --git a/arch/AArch64/AArch64InstPrinter.c b/arch/AArch64/AArch64InstPrinter.c index 9fcd856d2b7..0600f5b221e 100644 --- a/arch/AArch64/AArch64InstPrinter.c +++ b/arch/AArch64/AArch64InstPrinter.c @@ -43,6 +43,8 @@ #include "AArch64Linkage.h" #include "AArch64Mapping.h" +#ifndef CAPSTONE_TINY + #define GET_BANKEDREG_IMPL #include "AArch64GenSystemOperands.inc" @@ -2792,3 +2794,14 @@ const char *AArch64_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) { void AArch64_LLVM_printInstruction(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) { printInst(MI, MI->address, "", O); } + +#else + +const char *AArch64_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) { + return NULL; +} + +void AArch64_LLVM_printInstruction(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) { +} + +#endif diff --git a/arch/AArch64/AArch64Mapping.c b/arch/AArch64/AArch64Mapping.c index 08d3ba3b4b5..3bf5ca4f645 100644 --- a/arch/AArch64/AArch64Mapping.c +++ b/arch/AArch64/AArch64Mapping.c @@ -19,6 +19,8 @@ #include "AArch64Linkage.h" #include "AArch64Mapping.h" +#ifndef CAPSTONE_TINY + #ifndef CAPSTONE_DIET static aarch64_reg aarch64_flag_regs[] = { AArch64_REG_NZCV, @@ -86,7 +88,7 @@ void AArch64_init_mri(MCRegisterInfo *MRI) AArch64RegDiffLists, 0, AArch64SubRegIdxLists, ARR_SIZE(AArch64SubRegIdxLists), 0); } -const insn_map aarch64_insns[] = { +static const insn_map aarch64_insns[] = { #include "AArch64GenCSMappingInsn.inc" }; @@ -223,6 +225,8 @@ const char *AArch64_reg_name(csh handle, unsigned int reg) return AArch64_LLVM_getRegisterName(reg, AArch64_NoRegAltName); } +#endif + void AArch64_setup_op(cs_aarch64_op *op) { memset(op, 0, sizeof(cs_aarch64_op)); @@ -241,6 +245,8 @@ void AArch64_init_cs_detail(MCInst *MI) } } +#ifndef CAPSTONE_TINY + /// Unfortunately, the AArch64 definitions do not indicate in any way /// (exception are the instruction identifiers), if memory accesses /// is post- or pre-indexed. @@ -625,12 +631,12 @@ aarch64_insn AArch64_map_insn(const char *name) return AArch64_INS_INVALID; } -#ifndef CAPSTONE_DIET - static const map_insn_ops insn_operands[] = { #include "AArch64GenCSMappingInsnOp.inc" }; +#ifndef CAPSTONE_DIET + void AArch64_reg_access(const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count) @@ -1420,7 +1426,9 @@ static void add_cs_detail_template_1(MCInst *MI, aarch64_op_group op_group, } AArch64_get_detail_op(MI, 0)->type = AArch64_OP_IMM; AArch64_get_detail_op(MI, 0)->imm = prfop; +#ifndef CAPSTONE_DIET AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum); +#endif AArch64_inc_op_count(MI); break; } @@ -2300,4 +2308,25 @@ void AArch64_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Imm) insert_op(MI, index, op); } +#else + +void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) +{ +} + +void AArch64_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) +{ +} + +bool AArch64_getInstruction(csh handle, const uint8_t *code, size_t code_len, + MCInst *MI, uint16_t *size, uint64_t address, + void *info) +{ + AArch64_init_cs_detail(MI); + return AArch64_LLVM_getInstruction(handle, code, code_len, MI, size, address, + info) != MCDisassembler_Fail; +} + +#endif + #endif diff --git a/arch/AArch64/AArch64Module.c b/arch/AArch64/AArch64Module.c index 0340f9240da..45d72c5c72d 100644 --- a/arch/AArch64/AArch64Module.c +++ b/arch/AArch64/AArch64Module.c @@ -11,19 +11,21 @@ cs_err AArch64_global_init(cs_struct *ud) { +#ifndef CAPSTONE_TINY MCRegisterInfo *mri; mri = cs_mem_malloc(sizeof(*mri)); AArch64_init_mri(mri); - ud->printer = AArch64_printer; 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->group_name = AArch64_group_name; ud->post_printer = NULL; +#endif + ud->printer = AArch64_printer; + ud->disasm = AArch64_getInstruction; + ud->insn_id = AArch64_get_insn_id; #ifndef CAPSTONE_DIET ud->reg_access = AArch64_reg_access; #endif diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c index 43d81e87c37..7124cd2e1f1 100644 --- a/arch/ARM/ARMDisassembler.c +++ b/arch/ARM/ARMDisassembler.c @@ -40,6 +40,8 @@ #include "ARMDisassemblerExtension.h" #include "ARMMapping.h" +#ifndef CAPSTONE_TINY + #define GET_INSTRINFO_MC_DESC #include "ARMGenInstrInfo.inc" @@ -1200,11 +1202,15 @@ DecodeStatus getThumbInstruction(csh ud, const uint8_t *Bytes, size_t BytesLen, return MCDisassembler_Fail; } +#endif + static const uint16_t GPRDecoderTable[] = { ARM_R0, ARM_R1, ARM_R2, ARM_R3, ARM_R4, ARM_R5, ARM_R6, ARM_R7, ARM_R8, ARM_R9, ARM_R10, ARM_R11, ARM_R12, ARM_SP, ARM_LR, ARM_PC }; +#ifndef CAPSTONE_TINY + static const uint16_t CLRMGPRDecoderTable[] = { ARM_R0, ARM_R1, ARM_R2, ARM_R3, ARM_R4, ARM_R5, ARM_R6, ARM_R7, ARM_R8, ARM_R9, ARM_R10, ARM_R11, ARM_R12, 0, ARM_LR, ARM_APSR @@ -7344,3 +7350,76 @@ DecodeStatus ARM_LLVM_getInstruction(csh handle, const uint8_t *code, return getInstruction(handle, code, code_len, instr, size, address, info); } + +#else + +DecodeStatus ARM_LLVM_getInstruction(csh handle, const uint8_t *code, + size_t code_len, MCInst *instr, + uint16_t *size, uint64_t address, + void *info) +{ + cs_struct *ud = (cs_struct *)handle; + cs_insn *ci = instr->flat_insn; + cs_arm *arm = ci->detail ? &ci->detail->arm : NULL; + uint32_t insn; + + *size = 0; + + if (instr->csh->mode & CS_MODE_THUMB) + return MCDisassembler_Fail; + + if (code_len < 4) + return MCDisassembler_Fail; + + if (MODE_IS_BIG_ENDIAN(ud->mode)) + insn = (code[3] << 0) | (code[2] << 8) | + (code[1] << 16) | ((uint32_t) code[0] << 24); + else + insn = ((uint32_t) code[3] << 24) | (code[2] << 16) | + (code[1] << 8) | (code[0] << 0); + + MCInst_setOpcode(instr, ARM_INS_ENDING); + *size = 4; + + // + // LDR (literal) + // + // E.g. e51fc01c => LDR r12, [pc, #-28] + // + // Cond P U W Rt Imm12 + // 1110 010 1 0 0 0 11111 1100 000000011100 + // + // => Pattern + // 0000 010 1 0 0 0 11111 0000 000000000000 + // + // => Mask + // 0000 111 1 0 1 1 11111 0000 000000000000 + // + if ((insn & 0xf7f0000) == 0x51f0000) { + MCInst_setOpcode(instr, ARM_INS_LDR); + + if (arm) { + unsigned u, rt; + int imm12; + cs_arm_op *dst = &arm->operands[0]; + cs_arm_op *src = &arm->operands[1]; + + u = (insn >> 23) & 1; + rt = (insn >> 12) & 0xf; + imm12 = insn & 0xfff; + + arm->op_count = 2; + + dst->type = ARM_OP_REG; + dst->reg = GPRDecoderTable[rt]; + + src->type = ARM_OP_MEM; + src->mem.base = ARM_REG_PC; + src->mem.disp = (u == 1) ? imm12 : -imm12; + } + } + + return true; +} + +#endif diff --git a/arch/ARM/ARMInstPrinter.c b/arch/ARM/ARMInstPrinter.c index 212887d1c44..e136432fcb0 100644 --- a/arch/ARM/ARMInstPrinter.c +++ b/arch/ARM/ARMInstPrinter.c @@ -42,6 +42,8 @@ #include "ARMLinkage.h" #include "ARMMapping.h" +#ifndef CAPSTONE_TINY + #define GET_BANKEDREG_IMPL #include "ARMGenSystemRegister.inc" @@ -1973,3 +1975,12 @@ void ARM_LLVM_printInstruction(MCInst *MI, SStream *O, { printInst(MI, O, info); } + +#else + +void ARM_LLVM_printInstruction(MCInst *MI, SStream *O, + void * /* MCRegisterInfo* */ info) +{ +} + +#endif diff --git a/arch/ARM/ARMMapping.c b/arch/ARM/ARMMapping.c index 24f044d3539..8aaaaa71ac6 100644 --- a/arch/ARM/ARMMapping.c +++ b/arch/ARM/ARMMapping.c @@ -22,6 +22,8 @@ #include "ARMInstPrinter.h" #include "ARMMapping.h" +#ifndef CAPSTONE_TINY + static const name_map insn_alias_mnem_map[] = { #include "ARMGenCSAliasMnemMap.inc" { ARM_INS_ALIAS_ASR, "asr" }, @@ -89,7 +91,7 @@ const char *ARM_reg_name(csh handle, unsigned int reg) return ARM_LLVM_getRegisterName(reg, ARM_RegNamesRaw); } -const insn_map arm_insns[] = { +static const insn_map arm_insns[] = { #include "ARMGenCSMappingInsn.inc" }; @@ -814,6 +816,8 @@ void ARM_reg_access(const cs_insn *insn, cs_regs regs_read, } #endif +#endif + void ARM_setup_op(cs_arm_op *op) { memset(op, 0, sizeof(cs_arm_op)); @@ -837,6 +841,8 @@ void ARM_init_cs_detail(MCInst *MI) } } +#ifndef CAPSTONE_TINY + static uint64_t t_add_pc(MCInst *MI, uint64_t v) { int32_t imm = (int32_t)v; @@ -2126,4 +2132,26 @@ void ARM_set_detail_op_float(MCInst *MI, unsigned OpNum, uint64_t Imm) ARM_inc_op_count(MI); } +#else + +void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) +{ +} + +void ARM_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) +{ +} + +bool ARM_getInstruction(csh handle, const uint8_t *code, size_t code_len, + MCInst *instr, uint16_t *size, uint64_t address, + void *info) +{ + ARM_init_cs_detail(instr); + return ARM_LLVM_getInstruction(handle, code, code_len, instr, + size, address, + info) != MCDisassembler_Fail; +} + +#endif + #endif diff --git a/arch/ARM/ARMModule.c b/arch/ARM/ARMModule.c index 4fe40422b80..abfd901ac23 100644 --- a/arch/ARM/ARMModule.c +++ b/arch/ARM/ARMModule.c @@ -12,18 +12,20 @@ cs_err ARM_global_init(cs_struct *ud) { +#ifndef CAPSTONE_TINY MCRegisterInfo *mri; mri = cs_mem_malloc(sizeof(*mri)); ARM_init_mri(mri); - ud->printer = ARM_printer; ud->printer_info = mri; ud->reg_name = ARM_reg_name; - ud->insn_id = ARM_get_insn_id; ud->insn_name = ARM_insn_name; ud->group_name = ARM_group_name; ud->post_printer = NULL; +#endif + ud->printer = ARM_printer; + ud->insn_id = ARM_get_insn_id; #ifndef CAPSTONE_DIET ud->reg_access = ARM_reg_access; #endif diff --git a/arch/PowerPC/PPCMapping.c b/arch/PowerPC/PPCMapping.c index 1e7b9227e6f..4d24bff05d4 100644 --- a/arch/PowerPC/PPCMapping.c +++ b/arch/PowerPC/PPCMapping.c @@ -221,8 +221,10 @@ void PPC_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) MI->fillDetailOps = detail_is_set(MI); MI->flat_insn->usesAliasDetails = map_use_alias_details(MI); PPC_LLVM_printInst(MI, MI->address, "", O); +#ifndef CAPSTONE_DIET map_set_alias_id(MI, O, insn_alias_mnem_map, ARR_SIZE(insn_alias_mnem_map)); +#endif } bool PPC_getInstruction(csh handle, const uint8_t *bytes, size_t bytes_len, diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c index 79a756fca5f..c57133bb83b 100644 --- a/arch/X86/X86Disassembler.c +++ b/arch/X86/X86Disassembler.c @@ -101,6 +101,8 @@ #include "../../utils.h" #include "X86Mapping.h" +#ifndef CAPSTONE_TINY + #define GET_REGINFO_ENUM #define GET_REGINFO_MC_DESC #include "X86GenRegisterInfo.inc" @@ -1030,4 +1032,37 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len, } } +#else + +#include + +void X86_init(MCRegisterInfo *MRI) +{ +} + +bool X86_getInstruction(csh opaque_ud, const uint8_t *code, size_t code_len, + MCInst *instr, uint16_t *size, uint64_t address, void *_info) +{ + cs_struct *ud = (cs_struct *)(uintptr_t)opaque_ud; + cs_insn *ci = instr->flat_insn; + int mode, res; + FdInstr fi; + + if (ci->detail) + memset(ci->detail, 0, offsetof(cs_detail, x86) + sizeof(cs_x86)); + + mode = (ud->mode & CS_MODE_32) ? 32 : 64; + + res = fd_decode(code, code_len, mode, 0, &fi); + if (res < 0) + return false; + + MCInst_setOpcode(instr, X86_INS_ENDING); + *size = res; + + return true; +} + +#endif + #endif diff --git a/arch/X86/X86DisassemblerDecoder.c b/arch/X86/X86DisassemblerDecoder.c index 22acab36e5a..9f1375404eb 100644 --- a/arch/X86/X86DisassemblerDecoder.c +++ b/arch/X86/X86DisassemblerDecoder.c @@ -16,7 +16,7 @@ /* Capstone Disassembly Engine */ /* By Nguyen Anh Quynh , 2013-2019 */ -#ifdef CAPSTONE_HAS_X86 +#if defined(CAPSTONE_HAS_X86) && !defined(CAPSTONE_TINY) #include /* for va_*() */ #if defined(CAPSTONE_HAS_OSXKERNEL) diff --git a/arch/X86/X86InstPrinterCommon.c b/arch/X86/X86InstPrinterCommon.c index d8401c9b239..39394e6ccb5 100644 --- a/arch/X86/X86InstPrinterCommon.c +++ b/arch/X86/X86InstPrinterCommon.c @@ -42,7 +42,7 @@ #include "X86InstPrinterCommon.h" #include "X86Mapping.h" -#ifndef CAPSTONE_X86_REDUCE +#if !defined(CAPSTONE_TINY) && !defined(CAPSTONE_X86_REDUCE) void printSSEAVXCC(MCInst *MI, unsigned Op, SStream *O) { uint8_t Imm = (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f); diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c index cb1167e31da..95abee06b6e 100644 --- a/arch/X86/X86IntelInstPrinter.c +++ b/arch/X86/X86IntelInstPrinter.c @@ -45,6 +45,8 @@ #include "X86Mapping.h" #include "X86InstPrinterCommon.h" +#ifndef CAPSTONE_TINY + #define GET_INSTRINFO_ENUM #ifdef CAPSTONE_X86_REDUCE #include "X86GenInstrInfo_reduce.inc" @@ -1060,4 +1062,12 @@ static void printanymem(MCInst *MI, unsigned OpNo, SStream *O) #include "X86GenRegisterName1.inc" +#else + +void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info) +{ +} + +#endif + #endif diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c index d23340d771e..faec7cadd19 100644 --- a/arch/X86/X86Mapping.c +++ b/arch/X86/X86Mapping.c @@ -948,6 +948,8 @@ const char *X86_group_name(csh handle, unsigned int id) #endif } +#ifndef CAPSTONE_TINY + #define GET_INSTRINFO_ENUM #ifdef CAPSTONE_X86_REDUCE #include "X86GenInstrInfo_reduce.inc" @@ -2244,4 +2246,13 @@ unsigned short X86_register_map(unsigned short id) return 0; } +#else + +void X86_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) +{ + insn->id = id; +} + +#endif + #endif diff --git a/arch/X86/X86Module.c b/arch/X86/X86Module.c index 2ec5625de4e..9d4278f82ea 100644 --- a/arch/X86/X86Module.c +++ b/arch/X86/X86Module.c @@ -12,20 +12,22 @@ cs_err X86_global_init(cs_struct *ud) { +#ifndef CAPSTONE_TINY MCRegisterInfo *mri; mri = cs_mem_malloc(sizeof(*mri)); X86_init(mri); // by default, we use Intel syntax + ud->printer_info = mri; + ud->reg_name = X86_reg_name; + ud->group_name = X86_group_name; +#endif ud->printer = X86_Intel_printInst; ud->syntax = CS_OPT_SYNTAX_INTEL; - ud->printer_info = mri; ud->disasm = X86_getInstruction; - ud->reg_name = X86_reg_name; ud->insn_id = X86_get_insn_id; ud->insn_name = X86_insn_name; - ud->group_name = X86_group_name; ud->post_printer = NULL; #ifndef CAPSTONE_DIET ud->reg_access = X86_reg_access; diff --git a/cs.c b/cs.c index 0362395ddcd..0909891d979 100644 --- a/cs.c +++ b/cs.c @@ -336,11 +336,13 @@ cs_malloc_t cs_mem_malloc = malloc; cs_calloc_t cs_mem_calloc = calloc; cs_realloc_t cs_mem_realloc = realloc; cs_free_t cs_mem_free = free; +#ifndef CAPSTONE_TINY #if defined(_WIN32_WCE) cs_vsnprintf_t cs_vsnprintf = _vsnprintf; #else cs_vsnprintf_t cs_vsnprintf = vsnprintf; #endif // defined(_WIN32_WCE) +#endif #elif defined(_KERNEL_MODE) // Windows driver @@ -348,7 +350,9 @@ cs_malloc_t cs_mem_malloc = cs_winkernel_malloc; cs_calloc_t cs_mem_calloc = cs_winkernel_calloc; cs_realloc_t cs_mem_realloc = cs_winkernel_realloc; cs_free_t cs_mem_free = cs_winkernel_free; +#ifndef CAPSTONE_TINY cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf; +#endif #else // OSX kernel extern void* kern_os_malloc(size_t size); @@ -364,7 +368,9 @@ cs_malloc_t cs_mem_malloc = kern_os_malloc; cs_calloc_t cs_mem_calloc = cs_kern_os_calloc; cs_realloc_t cs_mem_realloc = kern_os_realloc; cs_free_t cs_mem_free = kern_os_free; +#ifndef CAPSTONE_TINY cs_vsnprintf_t cs_vsnprintf = vsnprintf; +#endif #endif // !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE) #else // User-defined @@ -372,7 +378,9 @@ cs_malloc_t cs_mem_malloc = NULL; cs_calloc_t cs_mem_calloc = NULL; cs_realloc_t cs_mem_realloc = NULL; cs_free_t cs_mem_free = NULL; +#ifndef CAPSTONE_TINY cs_vsnprintf_t cs_vsnprintf = NULL; +#endif #endif // defined(CAPSTONE_USE_SYS_DYN_MEM) @@ -482,7 +490,11 @@ cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle) { cs_err err; struct cs_struct *ud; - if (!cs_mem_malloc || !cs_mem_calloc || !cs_mem_realloc || !cs_mem_free || !cs_vsnprintf) + if (!cs_mem_malloc || !cs_mem_calloc || !cs_mem_realloc || !cs_mem_free +#ifndef CAPSTONE_TINY + || !cs_vsnprintf +#endif + ) // Error: before cs_open(), dynamic memory management must be initialized // with cs_option(CS_OPT_MEM) return CS_ERR_MEMSETUP; @@ -755,7 +767,9 @@ cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value) cs_mem_calloc = mem->calloc; cs_mem_realloc = mem->realloc; cs_mem_free = mem->free; +#ifndef CAPSTONE_TINY cs_vsnprintf = mem->vsnprintf; +#endif return CS_ERR_OK; } diff --git a/cs_priv.h b/cs_priv.h index c4866ddfd5c..7f1d0180876 100644 --- a/cs_priv.h +++ b/cs_priv.h @@ -99,7 +99,9 @@ extern cs_malloc_t cs_mem_malloc; extern cs_calloc_t cs_mem_calloc; extern cs_realloc_t cs_mem_realloc; extern cs_free_t cs_mem_free; +#ifndef CAPSTONE_TINY extern cs_vsnprintf_t cs_vsnprintf; +#endif // By defining CAPSTONE_DEBUG assertions can be used. // For any release build CAPSTONE_DEBUG has to be undefined. diff --git a/meson.build b/meson.build index ac5d11f5cd9..d88fde3eecb 100644 --- a/meson.build +++ b/meson.build @@ -81,12 +81,27 @@ foreach arch_id : desired_archs endforeach defines = [] +deps = [] +profile = get_option('profile') +if profile != 'full' + defines += '-DCAPSTONE_DIET' +endif +if profile == 'tiny' + defines += '-DCAPSTONE_TINY' + if 'x86' in desired_archs + fadec_options = [ + 'archmode=' + ((host_machine.cpu_family() == 'x86_64') ? 'only64' : 'only32'), + 'with_encode=false', + 'tests=false', + ] + deps += dependency('fadec', default_options: fadec_options) + endif +endif foreach arch_id : desired_archs defines += '-DCAPSTONE_HAS_' + arch_id.to_upper() endforeach available_flags = [ 'use_sys_dyn_mem', - 'diet', 'x86_reduce', 'x86_att_disable', 'has_osxkernel', @@ -108,6 +123,7 @@ include_dirs = include_directories('include') capstone = library('capstone', sources, c_args: defines, include_directories: include_dirs, + dependencies: deps, install: true, ) capstone_dep = declare_dependency( @@ -128,7 +144,7 @@ meson.override_dependency('capstone', capstone_dep) cli_option = get_option('cli') if cli_option.auto() - cli_enabled = not meson.is_subproject() + cli_enabled = profile == 'full' and not meson.is_subproject() else cli_enabled = cli_option.enabled() endif diff --git a/meson_options.txt b/meson_options.txt index 3bc5e2bc040..5f9f29e941b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,14 @@ +option('profile', + type: 'combo', + choices: [ + 'full', + 'slim', + 'tiny', + ], + value: 'full', + description: 'Feature profile' +) + option('archs', type: 'array', choices: [ @@ -32,13 +43,6 @@ option('use_sys_dyn_mem', description: 'Use malloc/calloc/realloc/free/vsnprintf() provided by the system for internal memory management' ) -option('diet', - type: 'boolean', - value: false, - yield: true, - description: 'Make the library more compact: use less memory & smaller in binary size' -) - option('x86_reduce', type: 'boolean', value: false, diff --git a/subprojects/fadec.wrap b/subprojects/fadec.wrap new file mode 100644 index 00000000000..7f5d3b0cac1 --- /dev/null +++ b/subprojects/fadec.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/frida/fadec.git +revision = main +depth = 1 + +[provide] +dependency_names = fadec diff --git a/utils.c b/utils.c index c97902e5b6b..6c54ae8ddd0 100644 --- a/utils.c +++ b/utils.c @@ -48,6 +48,7 @@ char *cs_strdup(const char *str) // we need this since Windows doesn't have snprintf() int cs_snprintf(char *buffer, size_t size, const char *fmt, ...) { +#ifndef CAPSTONE_TINY int ret; va_list ap; @@ -56,6 +57,9 @@ int cs_snprintf(char *buffer, size_t size, const char *fmt, ...) va_end(ap); return ret; +#else + return -1; +#endif } bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)