Skip to content

Commit

Permalink
Merge branch 'master' into v3
Browse files Browse the repository at this point in the history
  • Loading branch information
aquynh committed Jun 22, 2015
2 parents dcc54ca + 901f407 commit 2bb3933
Show file tree
Hide file tree
Showing 14 changed files with 327 additions and 69 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

# python
bindings/python/build/
bindings/python/capstone.egg-info/
*.pyc

# java
Expand Down Expand Up @@ -87,5 +88,8 @@ xcode/Capstone.xcodeproj/project.xcworkspace/xcuserdata
# suite/
test_arm_regression
test_arm_regression.o
fuzz_harness
fuzz_harness.o


*.s
5 changes: 4 additions & 1 deletion COMPILE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
(5) Cross-compile for Android

To cross-compile for Android (smartphone/tablet), Android NDK is required.
NOTE: Only ARM and ARM64 are currently supported.

$ ./make.sh cross-android
$ NDK=/android/android-ndk-r10e ./make.sh cross-android arm
or
$ NDK=/android/android-ndk-r10e ./make.sh cross-android arm64

Resulted files libcapstone.so, libcapstone.a & tests/test* can then
be used on Android devices.
Expand Down
1 change: 1 addition & 0 deletions CREDITS.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ Benoit Lecocq: OpenBSD package.
Christophe Avoinne (Hlide): Improve memory management for better performance.
Michael Cohen & Nguyen Tan Cong: Python module installer.
Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
Felix Gröbert (Google): fuzz testing harness.
2 changes: 2 additions & 0 deletions arch/Mips/MipsDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
} //else llvm_unreachable("Invalid encoding");

//assert(NSize != 0 && RegDecoder != nullptr);
if (NSize == 0 || RegDecoder == NULL)
return MCDisassembler_Fail;

if (RegDecoder == NULL)
return MCDisassembler_Fail;
Expand Down
43 changes: 0 additions & 43 deletions arch/Mips/MipsMapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -9213,54 +9213,11 @@ static insn_map insns[] = {
},
};

static insn_map alias_insns[] = {
{
(unsigned short)-2, MIPS_INS_NOP,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { 0 }, 0, 0
#endif
},
{
Mips_SUBu, MIPS_INS_NEGU,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { MIPS_GRP_STDENC, 0 }, 0, 0
#endif
},
};

// given internal insn id, return public instruction info
void Mips_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{
unsigned int i;

// consider alias insn first
for (i = 0; i < ARR_SIZE(alias_insns); i++) {
if (alias_insns[i].id == id) {
insn->id = alias_insns[i].mapid;

if (h->detail) {
#ifndef CAPSTONE_DIET
memcpy(insn->detail->regs_read, alias_insns[i].regs_use, sizeof(alias_insns[i].regs_use));
insn->detail->regs_read_count = (uint8_t)count_positive(alias_insns[i].regs_use);

memcpy(insn->detail->regs_write, alias_insns[i].regs_mod, sizeof(alias_insns[i].regs_mod));
insn->detail->regs_write_count = (uint8_t)count_positive(alias_insns[i].regs_mod);

memcpy(insn->detail->groups, alias_insns[i].groups, sizeof(alias_insns[i].groups));
insn->detail->groups_count = (uint8_t)count_positive(alias_insns[i].groups);

if (alias_insns[i].branch || alias_insns[i].indirect_branch) {
// this insn also belongs to JUMP group. add JUMP group
insn->detail->groups[insn->detail->groups_count] = MIPS_GRP_JUMP;
insn->detail->groups_count++;
}

#endif
}
return;
}
}

i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
if (i != 0) {
insn->id = insns[i].mapid;
Expand Down
4 changes: 4 additions & 0 deletions arch/PowerPC/PPCDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ static DecodeStatus decodeMemRIOperands(MCInst *Inst, uint64_t Imm,
uint64_t Disp = Imm & 0xFFFF;

// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;

switch (MCInst_getOpcode(Inst)) {
default: break;
Expand Down Expand Up @@ -316,6 +318,8 @@ static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,

unsigned Zeros = CountTrailingZeros_64(Imm);
// assert(Zeros < 8 && "Invalid CR bit value");
if (Zeros >=8)
return MCDisassembler_Fail;

MCOperand_CreateReg0(Inst, CRRegs[7 - Zeros]);
return MCDisassembler_Success;
Expand Down
15 changes: 15 additions & 0 deletions arch/X86/X86ATTInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,19 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
SStream_concat(O, "$-%"PRIu64, -imm);
}
break;

case X86_INS_AND:
case X86_INS_OR:
case X86_INS_XOR:
// do not print number in negative form
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "$%u", imm);
else {
imm = arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm;
SStream_concat(O, "$0x%"PRIx64, imm);
}
break;

case X86_INS_RET:
// RET imm16
if (imm >= 0 && imm <= HEX_THRESHOLD)
Expand All @@ -607,12 +620,14 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
MI->has_imm = true;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;

if (opsize > 0)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
else if (MI->op1_size > 0)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->op1_size;
else
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;

MI->flat_insn->detail->x86.op_count++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion arch/X86/X86DisassemblerDecoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ static int readPrefixes(struct InternalInstruction *insn)

/* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
if (consumeByte(insn, &byte))
break;
return -1;

if (insn->readerCursor - 1 == insn->startLocation
&& (byte == 0xf2 || byte == 0xf3)) {
Expand Down
6 changes: 4 additions & 2 deletions arch/X86/X86IntelInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,10 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
// do not print number in negative form
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "%u", imm);
else
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm);
else {
imm = arch_masks[MI->op1_size? MI->op1_size : MI->imm_size] & imm;
SStream_concat(O, "0x%"PRIx64, imm);
}
break;
case X86_INS_RET:
// RET imm16
Expand Down
11 changes: 7 additions & 4 deletions bindings/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import stat
import sys

from site import getusersitepackages
from distutils import log
from distutils import dir_util
from distutils.command.build_clib import build_clib
Expand All @@ -26,10 +25,14 @@
VERSION = '3.0.4'
SYSTEM = sys.platform

# virtualenv breaks import, but get_python_lib() will work.
SITE_PACKAGES = os.path.join(get_python_lib(), "capstone")
if "--user" in sys.argv:
SITE_PACKAGES = os.path.join(getusersitepackages(), "capstone")
else:
SITE_PACKAGES = os.path.join(get_python_lib(), "capstone")
try:
from site import getusersitepackages
SITE_PACKAGES = os.path.join(getusersitepackages(), "capstone")
except ImportError:
pass


SETUP_DATA_FILES = []
Expand Down
79 changes: 61 additions & 18 deletions make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,45 @@ function build_iOS {
CC="$IOS_CC" CFLAGS="$IOS_CFLAGS" LDFLAGS="$IOS_LDFLAGS" LIBARCHS="$IOS_ARCHS" ${MAKE}
}

# build Android lib for only one supported architecture
function build_android {
if [ -z "$NDK" ]; then
echo "ERROR! Please set \$NDK to point at your Android NDK directory."
exit 1
fi
HOSTOS=$(uname -s | tr 'LD' 'ld')
HOSTARCH=$(uname -m)

TARGARCH="$1"
shift

case "$TARGARCH" in
arm)
[ -n "$APILEVEL" ] || APILEVEL="android-14" # default to ICS
[ -n "$GCCVER" ] || GCCVER="4.8"
CROSS=arm-linux-androideabi-
;;
arm64)
[ -n "$APILEVEL" ] || APILEVEL="android-21" # first with arm64
[ -n "$GCCVER" ] || GCCVER="4.9"
CROSS=aarch64-linux-android-
;;

*)
echo "ERROR! Building for Android on $1 is not currently supported."
exit 1
;;
esac

TOOLCHAIN="$NDK/toolchains/$CROSS$GCCVER/prebuilt/$HOSTOS-$HOSTARCH"
PLATFORM="$NDK/platforms/$APILEVEL/arch-$TARGARCH"

${MAKE} clean

CROSS="$TOOLCHAIN/bin/$CROSS" CFLAGS="--sysroot=$PLATFORM" LDFLAGS="--sysroot=$PLATFORM" ${MAKE} $*
}


function build {
if [ $(uname -s) = Darwin ]; then
export LIBARCHS="i386 x86_64"
Expand All @@ -30,9 +69,9 @@ function build {
${MAKE} clean

if [ ${CC}x != x ]; then
${MAKE} CC=$CC
${MAKE} CC=$CC $*
else
${MAKE}
${MAKE} $*
fi
}

Expand Down Expand Up @@ -109,22 +148,26 @@ if [[ "$(uname)" == *BSD* ]]; then
export PREFIX=/usr/local
fi

case "$1" in
"" ) build;;
"default" ) build;;
TARGET="$1"
shift

case "$TARGET" in
"" ) build $*;;
"default" ) build $*;;
"debug" ) CAPSTONE_USE_SYS_DYN_MEM=yes CAPSTONE_STATIC=yes CFLAGS='-O0 -g -fsanitize=address' LDFLAGS='-fsanitize=address' build $*;;
"install" ) install;;
"uninstall" ) uninstall;;
"nix32" ) CFLAGS=-m32 LDFLAGS=-m32 build;;
"cross-win32" ) CROSS=i686-w64-mingw32- build;;
"cross-win64" ) CROSS=x86_64-w64-mingw32- build;;
"cygwin-mingw32" ) CROSS=i686-pc-mingw32- build;;
"cygwin-mingw64" ) CROSS=x86_64-w64-mingw32- build;;
"cross-android" ) CROSS=arm-linux-androideabi- build;;
"clang" ) CC=clang build;;
"gcc" ) CC=gcc build;;
"ios" ) build_iOS;;
"ios_armv7" ) build_iOS armv7;;
"ios_armv7s" ) build_iOS armv7s;;
"ios_arm64" ) build_iOS arm64;;
* ) echo "Usage: make.sh [nix32|cross-win32|cross-win64|cygwin-mingw32|cygwin-mingw64|ios|ios_armv7|ios_armv7s|ios_arm64|cross-android|clang|gcc|install|uninstall]"; exit 1;;
"nix32" ) CFLAGS=-m32 LDFLAGS=-m32 build $*;;
"cross-win32" ) CROSS=i686-w64-mingw32- build $*;;
"cross-win64" ) CROSS=x86_64-w64-mingw32- build $*;;
"cygwin-mingw32" ) CROSS=i686-pc-mingw32- build $*;;
"cygwin-mingw64" ) CROSS=x86_64-w64-mingw32- build $*;;
"cross-android" ) build_android $*;;
"clang" ) CC=clang build $*;;
"gcc" ) CC=gcc build $*;;
"ios" ) build_iOS $*;;
"ios_armv7" ) build_iOS armv7 $*;;
"ios_armv7s" ) build_iOS armv7s $*;;
"ios_arm64" ) build_iOS arm64 $*;;
* ) echo "Usage: make.sh [nix32|cross-win32|cross-win64|cygwin-mingw32|cygwin-mingw64|ios|ios_armv7|ios_armv7s|ios_arm64|cross-android arm|cross-android arm64|clang|gcc|install|uninstall]"; exit 1;;
esac
10 changes: 10 additions & 0 deletions suite/fuzz/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
LIBNAME = capstone

fuzz_harness: fuzz_harness.o
${CC} $< -O3 -Wall -l$(LIBNAME) -o $@

%.o: %.c
${CC} -c -I../../include $< -o $@

clean:
rm -rf *.o fuzz_harness
2 changes: 2 additions & 0 deletions suite/fuzz/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This directory contains a fuzz testing harness for Capstone.
Run "make" to compile this code.
Loading

0 comments on commit 2bb3933

Please sign in to comment.