add diet compile option (CAPSTONE_DIET option in config.mk). This reduces binary size by around 40%

_v3_old
Nguyen Anh Quynh 11 years ago
parent 491469155e
commit fc83a439e5
  1. 17
      Makefile
  2. 2
      SStream.c
  3. 8
      arch/AArch64/AArch64GenAsmWriter.inc
  4. 18963
      arch/AArch64/AArch64Mapping.c
  5. 8
      arch/ARM/ARMGenAsmWriter.inc
  6. 15179
      arch/ARM/ARMMapping.c
  7. 3
      arch/ARM/ARMMapping.h
  8. 8
      arch/Mips/MipsGenAsmWriter.inc
  9. 8970
      arch/Mips/MipsMapping.c
  10. 8
      arch/PowerPC/PPCGenAsmWriter.inc
  11. 5281
      arch/PowerPC/PPCMapping.c
  12. 3
      arch/PowerPC/PPCMapping.h
  13. 8
      arch/X86/X86GenAsmWriter.inc
  14. 8
      arch/X86/X86GenAsmWriter1.inc
  15. 35174
      arch/X86/X86Mapping.c
  16. 3
      arch/X86/X86Mapping.h
  17. 13
      config.mk
  18. 2
      cs.c
  19. 14
      include/capstone.h
  20. 2
      utils.h

@ -126,15 +126,28 @@ PKGCFGF = $(LIBNAME).pc
VERSION=$(shell echo `grep -e PKG_MAJOR -e PKG_MINOR CONFIG | grep -v = | awk '{print $$3}'` | awk '{print $$1"."$$2}')
.PHONY: all clean install uninstall
.PHONY: all clean install uninstall diet
all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
$(MAKE) -C tests
$(INSTALL_DATA) lib$(LIBNAME).$(EXT) tests
$(LIBRARY): $(LIBOBJ)
$(LIBRARY): diet $(LIBOBJ)
$(CC) $(LDFLAGS) $(LIBOBJ) -o $(LIBRARY)
# generate include/diet.h
diet:
@echo "#ifndef CAPSTONE_DIET_H" > include/diet.h
@echo "#define CAPSTONE_DIET_H" >> include/diet.h
@echo "" >> include/diet.h
@echo "// File auto-generated by Makefile for Capstone framework. DO NOT MODIFY!" >> include/diet.h
@echo "" >> include/diet.h
ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
@echo "#define CAPSTONE_DIET" >> include/diet.h
@echo "" >> include/diet.h
endif
@echo "#endif" >> include/diet.h
$(ARCHIVE): $(LIBOBJ)
rm -f $(ARCHIVE)
$(AR) q $(ARCHIVE) $(LIBOBJ)

@ -16,12 +16,14 @@ void SStream_Init(SStream *ss)
void SStream_concat(SStream *ss, const char *fmt, ...)
{
#ifndef CAPSTONE_DIET
va_list ap;
va_start(ap, fmt);
int ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
va_end(ap);
ss->index += ret;
#endif
}
/*

@ -5587,6 +5587,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 's', 'h', 'a', '1', 's', 'u', '0', 9, 0,
/* 9 */ 's', 'h', 'a', '2', '5', '6', 's', 'u', '0', 9, 0,
@ -5994,13 +5995,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 2804 */ 'd', 'r', 'p', 's', 0,
/* 2809 */ 'e', 'r', 'e', 't', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 4095)-1);
#endif
// Fragment 0 encoded into 8 bits for 159 unique commands.
@ -8523,6 +8527,7 @@ static char *getRegisterName(unsigned RegNo)
{
// assert(RegNo && RegNo < 420 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'D', '7', '_', 'D', '8', '_', 'D', '9', '_', 'D', '1', '0', 0,
/* 13 */ 'Q', '7', '_', 'Q', '8', '_', 'Q', '9', '_', 'Q', '1', '0', 0,
@ -8854,6 +8859,9 @@ static char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

File diff suppressed because it is too large Load Diff

@ -5689,6 +5689,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 's', 'h', 'a', '1', 's', 'u', '0', '.', '3', '2', 9, 0,
/* 12 */ 's', 'h', 'a', '2', '5', '6', 's', 'u', '0', '.', '3', '2', 9, 0,
@ -6132,13 +6133,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 3019 */ 'v', 'c', 'l', 'z', 0,
/* 3024 */ 'v', 'r', 'i', 'n', 't', 'z', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 4095)-1);
#endif
// Fragment 0 encoded into 5 bits for 29 unique commands.
@ -8185,6 +8189,7 @@ static char *getRegisterName(unsigned RegNo)
{
// assert(RegNo && RegNo < 289 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'D', '4', '_', 'D', '6', '_', 'D', '8', '_', 'D', '1', '0', 0,
/* 13 */ 'D', '7', '_', 'D', '8', '_', 'D', '9', '_', 'D', '1', '0', 0,
@ -8406,6 +8411,9 @@ static char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

File diff suppressed because it is too large Load Diff

@ -16,9 +16,6 @@ void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *ARM_insn_name(csh handle, unsigned int id);
// map instruction name to instruction ID
arm_reg ARM_map_insn(const char *name);
// check if this insn is relative branch
bool ARM_rel_branch(cs_struct *h, unsigned int insn_id);

@ -2989,6 +2989,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'j', 'a', 'l', 'r', 'c', 32, 9, 0,
/* 8 */ 'd', 'm', 'f', 'c', '0', 9, 0,
@ -3882,13 +3883,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 7918 */ 'd', 'e', 'r', 'e', 't', 0,
/* 7924 */ 'w', 'a', 'i', 't', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 8191)-1);
#endif
// Fragment 0 encoded into 3 bits for 5 unique commands.
@ -4235,6 +4239,7 @@ static char *getRegisterName(unsigned RegNo)
{
// assert(RegNo && RegNo < 317 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'f', '1', '0', 0,
/* 4 */ 'w', '1', '0', 0,
@ -4391,6 +4396,9 @@ static char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

File diff suppressed because it is too large Load Diff

@ -1794,6 +1794,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ '#', 'E', 'H', '_', 'S', 'j', 'L', 'j', '_', 'S', 'e', 't', 'u', 'p', 9, 0,
/* 16 */ 'b', 'd', 'z', 'l', 'a', '+', 32, 0,
@ -2454,13 +2455,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 5695 */ 'b', 'd', 'n', 'z', 'l', 'r', 0,
/* 5702 */ 'b', 'c', 't', 'r', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 8191)-1);
#endif
// Fragment 0 encoded into 4 bits for 13 unique commands.
@ -2868,6 +2872,7 @@ static const char *getRegisterName(unsigned RegNo)
{
//assert(RegNo && RegNo < 182 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static const char AsmStrs[] = {
/* 0 */ '*', '*', 'R', 'O', 'U', 'N', 'D', 'I', 'N', 'G', 32, 'M', 'O', 'D', 'E', '*', '*', 0,
/* 18 */ '*', '*', 'F', 'R', 'A', 'M', 'E', 32, 'P', 'O', 'I', 'N', 'T', 'E', 'R', '*', '*', 0,
@ -2997,6 +3002,9 @@ static const char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

File diff suppressed because it is too large Load Diff

@ -15,9 +15,6 @@ void PPC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *PPC_insn_name(csh handle, unsigned int id);
// map instruction name to instruction ID
ppc_reg PPC_map_insn(const char *name);
// map internal raw register to 'public' register
ppc_reg PPC_map_register(unsigned int r);

@ -10781,6 +10781,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'v', 'm', 'o', 'v', 'd', 'q', 'u', '3', '2', 32, 9, 0,
/* 12 */ 'v', 'm', 'o', 'v', 'd', 'q', 'u', '6', '4', 32, 9, 0,
@ -12340,13 +12341,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 15407 */ 'f', 'n', 'c', 'l', 'e', 'x', 0,
/* 15414 */ 'f', 'l', 'd', 'z', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
#endif
// Fragment 0 encoded into 7 bits for 78 unique commands.
@ -13428,6 +13432,7 @@ static char *getRegisterName(unsigned RegNo)
{
// assert(RegNo && RegNo < 233 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 's', 't', '(', '0', ')', 0,
/* 6 */ 's', 't', '(', '1', ')', 0,
@ -13662,6 +13667,9 @@ static char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

@ -10781,6 +10781,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
0U
};
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 'v', 'm', 'o', 'v', 'd', 'q', 'u', '3', '2', 32, 9, 0,
/* 12 */ 'v', 'm', 'o', 'v', 'd', 'q', 'u', '6', '4', 32, 9, 0,
@ -12051,13 +12052,16 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
/* 12905 */ 'f', 'n', 'c', 'l', 'e', 'x', 0,
/* 12912 */ 'f', 'l', 'd', 'z', 0,
};
#endif
// Emit the opcode for the instruction.
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
#endif
// Fragment 0 encoded into 6 bits for 45 unique commands.
@ -12939,6 +12943,7 @@ static char *getRegisterName(unsigned RegNo)
{
// assert(RegNo && RegNo < 233 && "Invalid register number!");
#ifndef CAPSTONE_DIET
static char AsmStrs[] = {
/* 0 */ 's', 't', '(', '0', ')', 0,
/* 6 */ 's', 't', '(', '1', ')', 0,
@ -13173,6 +13178,9 @@ static char *getRegisterName(unsigned RegNo)
// printf("%s = %u\n", AsmStrs+RegAsmOffset[i], i + 1);
//printf("*************************\n");
return AsmStrs+RegAsmOffset[RegNo-1];
#else
return NULL;
#endif
}
#ifdef PRINT_ALIAS_INSTR

File diff suppressed because it is too large Load Diff

@ -29,9 +29,6 @@ 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);
// return insn id, given insn mnemonic
x86_reg X86_map_insn(const char *mnem);
// post printer for X86.
void X86_post_printer(csh handle, cs_insn *pub_insn, char *insn_asm);

@ -1,9 +1,22 @@
################################################################################
# Change 'CAPSTONE_DIET = no' to 'CAPSTONE_DIET = yes' to make the library
# more compact.
# This setup will remove all the mnemonic & op_str data, thus reduces the binary
# size by around 200KB.
# NOTE: we still keep @mnemonic & @op_str fields in cs_insn structure regardless,
# but they will not be updated (i.e blank) at the output of disassemble APIs.
CAPSTONE_DIET = no
################################################################################
# Comment out the line below 'USE_SYS_DYN_MEM = yes' if you do not want to use
# system's malloc()/calloc()/realloc()/free() for internal dynamic memory management.
# NOTE: in that case, your program must specify your own malloc/calloc/realloc/free
# functions with cs_option(), using CS_OPT_MEM option type.
USE_SYS_DYN_MEM = yes
################################################################################
# Specify which archs you want to compile in
# DO NOT touch the line below.
CAPSTONE_ARCHS =

@ -230,6 +230,7 @@ static void fill_insn(struct cs_struct *handle, cs_insn *insn, char *buffer, MCI
if (postprinter)
postprinter((csh)handle, insn, buffer);
#ifndef CAPSTONE_DIET
// fill in mnemonic & operands
// find first space or tab
char *sp = buffer;
@ -248,6 +249,7 @@ static void fill_insn(struct cs_struct *handle, cs_insn *insn, char *buffer, MCI
strncpy(insn->mnemonic, buffer, sizeof(insn->mnemonic) - 1);
insn->mnemonic[sizeof(insn->mnemonic) - 1] = '\0';
#endif
}
cs_err cs_option(csh ud, cs_opt_type type, size_t value)

@ -14,6 +14,8 @@ extern "C" {
#include <stdbool.h>
#include <stdlib.h>
#include "diet.h"
#ifdef _MSC_VER
#pragma warning(disable:4201)
#pragma warning(disable:4100)
@ -305,6 +307,9 @@ void cs_free(cs_insn *insn, size_t count);
Return friendly name of regiser in a string
Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
NOTE: when CAPTONE_DIET is defined, this API is irrelevant because engine does not
store register name.
@handle: handle returned by cs_open()
@reg: register id
@return: string name of the register, or NULL if @reg_id is invalid.
@ -315,6 +320,9 @@ const char *cs_reg_name(csh handle, unsigned int reg_id);
Return friendly name of an instruction in a string
Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
NOTE: when CAPTONE_DIET is defined, this API is irrelevant because engine does not
store instruction name.
@handle: handle returned by cs_open()
@insn: instruction id
@ -328,6 +336,8 @@ const char *cs_insn_name(csh handle, unsigned int insn_id);
Internally, this simply verifies if @group_id matches any member of insn->groups array.
NOTE: this API is only valid when detail option is ON (which is OFF by default)
Besides, when CAPTONE_DIET is defined, this API is irrelevant because engine does not
update @groups array.
@handle: handle returned by cs_open()
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_ex()
@ -343,6 +353,8 @@ bool cs_insn_group(csh handle, cs_insn *insn, unsigned int group_id);
Internally, this simply verifies if @reg_id matches any member of insn->regs_read array.
NOTE: this API is only valid when detail option is ON (which is OFF by default)
Besides, when CAPTONE_DIET is defined, this API is irrelevant because engine does not
update @regs_read array.
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_ex()
@reg_id: register that you want to check if this instruction used it.
@ -357,6 +369,8 @@ bool cs_reg_read(csh handle, cs_insn *insn, unsigned int reg_id);
Internally, this simply verifies if @reg_id matches any member of insn->regs_write array.
NOTE: this API is only valid when detail option is ON (which is OFF by default)
Besides, when CAPTONE_DIET is defined, this API is irrelevant because engine does not
update @regs_write array.
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_ex()
@reg_id: register that you want to check if this instruction modified it.

@ -14,11 +14,13 @@
typedef struct insn_map {
unsigned short id;
unsigned short mapid;
#ifndef CAPSTONE_DIET
unsigned char regs_use[12]; // list of implicit registers used by this instruction
unsigned char regs_mod[20]; // list of implicit registers modified by this instruction
unsigned char groups[8]; // list of group this instruction belong to
bool branch; // branch instruction?
bool indirect_branch; // indirect branch instruction?
#endif
} insn_map;
// return the position of a string in a list of strings

Loading…
Cancel
Save