Commit 32bd2432 authored by Sophie Brun's avatar Sophie Brun

Imported Upstream version 2.1.2

parent c56001d3
......@@ -54,3 +54,6 @@ capstone.pc
# local files
_*
# freebsd ports: generated file with "make makesum" command
packages/freebsd/ports/devel/capstone/distinfo
......@@ -75,7 +75,28 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
(4) Compile on Windows with Cygwin
(4) Cross-compile iOS from Mac OSX.
To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required.
- To cross-compile for ArmV7 (iPod 4, iPad 1/2/3, iPhone4, iPhone4S), run:
$ ./make.sh ios_armv7
- To cross-compile for ArmV7s (iPad 4, iPhone 5C, iPad mini), run:
$ ./make.sh ios_armv7s
- To cross-compile for Arm64 (iPhone 5S, iPad mini Retina, iPad Air), run:
$ ./make.sh ios_arm64
- To cross-compile for all iDevices (armv7 + armv7s + arm64), run:
$ ./make.sh ios
Resulted files libcapstone.dylib, libcapstone.a & tests/test* can then
be used on iOS devices.
(5) Compile on Windows with Cygwin
To compile under Cygwin gcc-mingw-w64-i686 or x86_64-w64-mingw32 run:
......@@ -89,7 +110,7 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
be used on Windows machine.
(5) By default, "cc" (default C compiler on the system) is used as compiler.
(6) By default, "cc" (default C compiler on the system) is used as compiler.
- To use "clang" compiler instead, run command below:
......@@ -101,7 +122,7 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
(6) Language bindings
(7) Language bindings
So far, Python, Ocaml & Java are supported by bindings in the main code.
Look for the bindings under directory bindings/, and refer to README file
......
This file details the changelog of Capstone.
---------------------------------
Version 2.1.2: April 3rd, 2014
This is a stable release to fix some bugs deep in the core. There is no update
to any architectures or bindings, so bindings version 2.1 can be used with this
version 2.1.2 just fine.
[ Core changes]
- Support cross-compilation for all iDevices (iPhone/iPad/iPod).
- X86: do not print memory offset in negative form.
- Fix a bug in X86 when Capstone cannot handle short instruction.
- Print negative number above -9 without prefix 0x (arm64, mips, arm).
- Correct the SONAME setup for library versioning (Linux, *BSD, Solaris).
- Set library versioning for dylib of OSX.
---------------------------------
Version 2.1.1: March 13th, 2014
......
......@@ -142,6 +142,7 @@ struct MCInst {
int insn_size; // instruction size
uint64_t address; // address of this insn
cs_struct *csh; // save the main csh
uint8_t x86_imm_size; // save immediate size to print immediate properly
};
void MCInst_Init(MCInst *inst);
......
# Capstone Disassembly Engine
# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013>
# By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014
include config.mk
include pkgconfig.mk # package version
......@@ -22,7 +22,9 @@ ifeq ($(USE_SYS_DYN_MEM),yes)
CFLAGS += -DUSE_SYS_DYN_MEM
endif
LDFLAGS += -shared
ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
CFLAGS += -DCAPSTONE_DIET
endif
PREFIX ?= /usr
DESTDIR ?=
......@@ -31,17 +33,30 @@ INCDIR = $(DESTDIR)$(PREFIX)/include
LIBDIR = $(DESTDIR)$(PREFIX)/lib
# on x86_64, we might have /usr/lib64 directory instead of /usr/lib
UNAME_M := $(shell uname -m)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_M), x86_64)
ifeq (,$(wildcard $(LIBDIR)))
ifneq ($(UNAME_S), Darwin)
LIBDIR = $(DESTDIR)$(PREFIX)/lib64
else
LIBDIR = $(DESTDIR)$(PREFIX)/lib
endif
endif
endif
ifneq ($(UNAME_S),Darwin)
LDFLAGS += -shared
endif
LIBDATADIR = $(LIBDIR)
ifeq ($(UNAME_S), FreeBSD)
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata
endif
ifeq ($(UNAME_S), DragonFly)
LIBDATADIR = $(DESTDIR)$(PREFIX)/libdata
endif
INSTALL_BIN ?= install
INSTALL_DATA ?= $(INSTALL_BIN) -m0644
INSTALL_LIBRARY ?= $(INSTALL_BIN) -m0755
INSTALL_LIB ?= $(INSTALL_BIN) -m0755
LIBNAME = capstone
......@@ -138,13 +153,17 @@ LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_X8
LIBOBJ += MCInst.o
UNAME_S := $(shell uname -s)
PKGCFCGDIR = $(LIBDIR)/pkgconfig
PKGCFCGDIR = $(LIBDATADIR)/pkgconfig
API_MAJOR=$(shell echo `grep -e CS_API_MAJOR include/capstone.h | grep -v = | awk '{print $$3}'` | awk '{print $$1}')
VERSION_EXT =
# OSX?
ifeq ($(UNAME_S),Darwin)
EXT = dylib
VERSION_EXT = $(API_MAJOR).$(EXT)
LDFLAGS += -dynamiclib -install_name lib$(LIBNAME).$(VERSION_EXT) -current_version $(PKG_MAJOR).$(PKG_MINOR).$(PKG_EXTRA) -compatibility_version $(PKG_MAJOR).$(PKG_MINOR)
AR_EXT = a
ifneq ($(HOMEBREW_CAPSTONE),1)
ifneq ($(USE_SYS_DYN_MEM),yes)
# remove string check because OSX kernel complains about missing symbols
CFLAGS += -D_FORTIFY_SOURCE=0
......@@ -156,6 +175,7 @@ ifneq (,$(wildcard /opt/local/bin/port))
# then correct the path for pkgconfig file
PKGCFCGDIR = /opt/local/lib/pkgconfig
endif
endif
else
# Cygwin?
IS_CYGWIN := $(shell $(CC) -dumpmachine | grep -i cygwin | wc -l)
......@@ -177,10 +197,9 @@ CFLAGS := $(CFLAGS:-fPIC=)
else
# Linux, *BSD
EXT = so
VERSION_EXT = $(EXT).$(API_MAJOR)
AR_EXT = a
API_MAJOR=$(shell echo `grep -e CS_API_MAJOR include/capstone.h | grep -v = | awk '{print $$3}'` | awk '{print $$1}')
LDFLAGS += -Wl,-soname,lib$(LIBNAME)$(API_MAJOR)
LDFLAGS += -Wl,-soname,lib$(LIBNAME).$(VERSION_EXT)
endif
endif
endif
......@@ -198,7 +217,7 @@ all: $(LIBRARY) $(ARCHIVE) $(PKGCFGF)
$(LIBRARY): $(LIBOBJ)
$(CC) $(LDFLAGS) $(LIBOBJ) -o $(LIBRARY)
$(LIBOBJ): include/diet.h
$(LIBOBJ): config.mk
$(LIBOBJ_ARM): $(DEP_ARM)
$(LIBOBJ_ARM64): $(DEP_ARM64)
......@@ -206,23 +225,6 @@ $(LIBOBJ_MIPS): $(DEP_MIPS)
$(LIBOBJ_PPC): $(DEP_PPC)
$(LIBOBJ_X86): $(DEP_X86)
# auto-generate include/diet.h
include/diet.h: config.mk
@echo "// File auto-generated by Makefile for Capstone framework. DO NOT MODIFY!" > include/diet.h
@echo "" >> include/diet.h
@echo "#ifndef CAPSTONE_DIET_H" >> include/diet.h
@echo "#define CAPSTONE_DIET_H" >> include/diet.h
@echo "" >> include/diet.h
ifneq (,$(findstring yes,$(CAPSTONE_DIET)))
@echo "// Capstone is in DIET mode" >> include/diet.h
@echo "#define CAPSTONE_DIET" >> include/diet.h
else
@echo "// Capstone is in standard mode (NOT diet)" >> include/diet.h
@echo "#undef CAPSTONE_DIET" >> include/diet.h
endif
@echo "" >> include/diet.h
@echo "#endif" >> include/diet.h
$(ARCHIVE): $(LIBOBJ)
rm -f $(ARCHIVE)
$(AR) q $(ARCHIVE) $(LIBOBJ)
......@@ -244,7 +246,14 @@ endif
install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
mkdir -p $(LIBDIR)
$(INSTALL_LIBRARY) lib$(LIBNAME).$(EXT) $(LIBDIR)
# remove potential broken old libs
rm -f $(LIBDIR)/lib$(LIBNAME).*
$(INSTALL_LIB) lib$(LIBNAME).$(EXT) $(LIBDIR)
ifneq ($(VERSION_EXT),)
cd $(LIBDIR) && \
mv lib$(LIBNAME).$(EXT) lib$(LIBNAME).$(VERSION_EXT) && \
ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT)
endif
$(INSTALL_DATA) lib$(LIBNAME).$(AR_EXT) $(LIBDIR)
mkdir -p $(INCDIR)/$(LIBNAME)
$(INSTALL_DATA) include/*.h $(INCDIR)/$(LIBNAME)
......@@ -253,14 +262,12 @@ install: $(PKGCFGF) $(ARCHIVE) $(LIBRARY)
uninstall:
rm -rf $(INCDIR)/$(LIBNAME)
rm -f $(LIBDIR)/lib$(LIBNAME).$(EXT)
rm -f $(LIBDIR)/lib$(LIBNAME).$(AR_EXT)
rm -f $(LIBDIR)/lib$(LIBNAME).*
rm -f $(PKGCFCGDIR)/$(LIBNAME).pc
clean:
rm -f $(LIBOBJ) lib$(LIBNAME).*
rm -f $(PKGCFGF)
rm -f include/diet.h
$(MAKE) -C bindings/python clean
$(MAKE) -C bindings/java clean
$(MAKE) -C bindings/ocaml clean
......@@ -276,6 +283,7 @@ endif
dist:
git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz
git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
Version 2.1.1 is a stable release that fixes some bugs deep in the core.
Version 2.1.2 is a stable release that fixes some bugs deep in the core.
There is no update to any architectures or bindings, so older bindings
of release 2.1 can be used with this version 2.1.1 just fine.
of release 2.1 can be used with this version 2.1.2 just fine.
For this reason, after upgrading to 2.1.1, users do NOT need to upgrade
For this reason, after upgrading to 2.1.2, users do NOT need to upgrade
their bindings from release 2.1.
......@@ -63,10 +63,17 @@ static void printOffsetSImm9Operand(MCInst *MI, unsigned OpNum, SStream *O)
MCOperand *MOImm = MCInst_getOperand(MI, OpNum);
int32_t Imm = (int32_t)unpackSignedImm(9, MCOperand_getImm(MOImm));
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", Imm);
else
SStream_concat(O, "#%u", Imm);
if (Imm >=0) {
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", Imm);
else
SStream_concat(O, "#%u", Imm);
} else {
if (Imm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -Imm);
else
SStream_concat(O, "#-%u", -Imm);
}
if (MI->csh->detail) {
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
......@@ -330,10 +337,17 @@ static void printLabelOperand(MCInst *MI, unsigned OpNum,
MI->flat_insn.arm64.op_count++;
}
if (SImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, SImm);
else
SStream_concat(O, "#%"PRIu64, SImm);
if (SImm >= 0) {
if (SImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, SImm);
else
SStream_concat(O, "#%"PRIu64, SImm);
} else {
if (SImm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%"PRIx64, -SImm);
else
SStream_concat(O, "#-%"PRIu64, -SImm);
}
}
static void printLogicalImmOperand(MCInst *MI, unsigned OpNum,
......@@ -548,17 +562,27 @@ static void printSImm7ScaledOperand(MCInst *MI, unsigned OpNum,
{
MCOperand *MOImm = MCInst_getOperand(MI, OpNum);
int32_t Imm = (int32_t)unpackSignedImm(7, MCOperand_getImm(MOImm));
int64_t res;
res = Imm * MemScale;
if (res >= 0) {
if (res > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, res);
else
SStream_concat(O, "#%"PRIu64, res);
} else {
if (res < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%"PRIx64, -res);
else
SStream_concat(O, "#-%"PRIu64, -res);
}
if (Imm * MemScale > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", Imm * MemScale);
else
SStream_concat(O, "#%u", Imm * MemScale);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = Imm * MemScale;
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = res;
} else {
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm * MemScale;
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = res;
MI->flat_insn.arm64.op_count++;
}
}
......@@ -602,10 +626,18 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
} else if (MCOperand_isImm(Op)) {
int64_t imm = MCOperand_getImm(Op);
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, imm);
else
SStream_concat(O, "#%"PRIu64, imm);
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%"PRIx64, imm);
else
SStream_concat(O, "#%"PRIu64, imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%"PRIx64, -imm);
else
SStream_concat(O, "#-%"PRIu64, -imm);
}
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = (int32_t)imm;
......@@ -667,10 +699,18 @@ static void printNeonMovImmShiftOperand(MCInst *MI, unsigned OpNum,
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_MSL;
}
if (Imm > HEX_THRESHOLD)
SStream_concat(O, " #0x%"PRIx64, Imm);
else
SStream_concat(O, " #%"PRIu64, Imm);
if (Imm >= 0) {
if (Imm > HEX_THRESHOLD)
SStream_concat(O, " #0x%"PRIx64, Imm);
else
SStream_concat(O, " #%"PRIu64, Imm);
} else {
if (Imm < -HEX_THRESHOLD)
SStream_concat(O, " #-0x%"PRIx64, -Imm);
else
SStream_concat(O, " #-%"PRIu64, -Imm);
}
if (MI->csh->detail)
MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = (unsigned int)Imm;
}
......
......@@ -555,31 +555,20 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
}
} else if (MCOperand_isImm(Op)) {
SStream_concat(O, markup("<imm:"));
int32_t imm = (int32_t)MCOperand_getImm(Op);
SStream_concat(O, markup("<imm:"));
// relative branch only has relative offset, so we have to update it
// 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(MI->csh, MCInst_getOpcode(MI))) {
// only do this for relative branch
if (MI->csh->mode & CS_MODE_THUMB)
imm += (int32_t)MI->address + 4;
else
imm += (int32_t)MI->address + 8;
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", imm);
else
SStream_concat(O, "#%u", imm);
} else if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -imm);
else
SStream_concat(O, "#%u", imm);
} else
SStream_concat(O, "#-0x%x", -imm);
SStream_concat(O, "#-%u", -imm);
}
SStream_concat(O, markup(">"));
if (MI->csh->detail) {
......@@ -1657,10 +1646,17 @@ static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum,
if (isSub) {
SStream_concat(O, ", %s#-0x%x%s", markup("<imm:"), -OffImm, markup(">"));
} else if (AlwaysPrintImm0 || OffImm > 0) {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, ", %s#0x%x%s", markup("<imm:"), OffImm, markup(">"));
else
SStream_concat(O, ", %s#%u%s", markup("<imm:"), OffImm, markup(">"));
if (OffImm >= 0) {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, ", %s#0x%x%s", markup("<imm:"), OffImm, markup(">"));
else
SStream_concat(O, ", %s#%u%s", markup("<imm:"), OffImm, markup(">"));
} else {
if (OffImm < -HEX_THRESHOLD)
SStream_concat(O, ", %s#-0x%x%s", markup("<imm:"), -OffImm, markup(">"));
else
SStream_concat(O, ", %s#-%u%s", markup("<imm:"), -OffImm, markup(">"));
}
}
if (MI->csh->detail)
MI->flat_insn.arm.operands[MI->flat_insn.arm.op_count].mem.disp = OffImm;
......@@ -1788,9 +1784,12 @@ static void printT2AddrModeImm8OffsetOperand(MCInst *MI,
MI->flat_insn.arm.op_count++;
}
} else {
if (OffImm < 0)
SStream_concat(O, "#-0x%x%s", -OffImm, markup(">"));
else {
if (OffImm < 0) {
if (OffImm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x%s", -OffImm, markup(">"));
else
SStream_concat(O, "#-%u%s", -OffImm, markup(">"));
} else {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x%s", OffImm, markup(">"));
else
......@@ -1821,9 +1820,12 @@ static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI,
MI->flat_insn.arm.op_count++;
}
} else {
if (OffImm < 0)
SStream_concat(O, "#-0x%x%s", -OffImm, markup(">"));
else {
if (OffImm < 0) {
if (OffImm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x%s", -OffImm, markup(">"));
else
SStream_concat(O, "#-%u%s", -OffImm, markup(">"));
} else {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x%s", OffImm, markup(">"));
else
......
......@@ -13600,29 +13600,3 @@ const char *ARM_insn_name(csh handle, unsigned int id)
return NULL;
#endif
}
// list all relative branch instructions
// ie: insns[i].branch && !insns[i].indirect_branch
static unsigned int insn_rel[] = {
ARM_Bcc,
ARM_t2B,
ARM_t2Bcc,
ARM_tB,
ARM_tBcc,
ARM_tCBNZ,
ARM_tCBZ,
0
};
// check if this insn is relative branch
bool ARM_rel_branch(cs_struct *h, unsigned int id)
{
int i;
for (i = 0; insn_rel[i]; i++)
if (id == insn_rel[i])
return true;
// not found
return false;
}
......@@ -16,7 +16,4 @@ void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *ARM_insn_name(csh handle, unsigned int id);
// check if this insn is relative branch
bool ARM_rel_branch(cs_struct *h, unsigned int insn_id);
#endif
......@@ -247,7 +247,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
SStream_concat(O, "%"PRIu64, imm);
} else {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
......@@ -262,7 +262,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
SStream_concat(O, "%"PRIu64, imm);
} else {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
......@@ -288,7 +288,7 @@ static void printUnsignedImm(MCInst *MI, int opNum, SStream *O)
else
SStream_concat(O, "%u", (unsigned short int)imm);
} else {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%x", (short int)-imm);
else
SStream_concat(O, "-%u", (short int)-imm);
......
......@@ -2865,6 +2865,7 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
}
#ifndef CAPSTONE_DIET
/// getRegisterName - This method is automatically generated by tblgen
/// from the register set description. This returns the assembler name
/// for the specified register.
......@@ -2872,7 +2873,6 @@ 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,
......@@ -3002,10 +3002,8 @@ 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
}
#endif
#ifdef PRINT_ALIAS_INSTR
#undef PRINT_ALIAS_INSTR
......
......@@ -27,7 +27,10 @@
#include "../../MathExtras.h"
#include "PPCMapping.h"
#ifndef CAPSTONE_DIET
static const char *getRegisterName(unsigned RegNo);
#endif
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O);
......@@ -459,6 +462,7 @@ static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O)
}
#ifndef CAPSTONE_DIET
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
static const char *stripRegisterPrefix(const char *RegName)
......@@ -475,6 +479,7 @@ static const char *stripRegisterPrefix(const char *RegName)
return RegName;
}
#endif
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
......
......@@ -210,10 +210,7 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
if (MI->csh->detail)
MI->flat_insn.x86.operands[MI->flat_insn.x86.op_count].mem.disp = imm;
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
......@@ -336,7 +333,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
if (MCOperand_isImm(Op)) {
int64_t imm = MCOperand_getImm(Op) + MI->insn_size + MI->address;
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
......@@ -373,7 +370,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
SStream_concat(O, "%s$%"PRIu64"%s", markup("<imm:"), imm, markup(">"));
} else {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "%s$-0x%"PRIx64"%s", markup("<imm:"), -imm, markup(">"));
else
SStream_concat(O, "%s$-%"PRIu64"%s", markup("<imm:"), -imm, markup(">"));
......@@ -396,7 +393,7 @@ static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
// Print X86 immediates as signed values.
int64_t imm = MCOperand_getImm(Op);
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "%s$-0x%"PRIx64"%s", markup("<imm:"), -imm, markup(">"));
else
SStream_concat(O, "%s$-%"PRIu64"%s", markup("<imm:"), -imm, markup(">"));
......@@ -438,10 +435,7 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
MI->flat_insn.x86.operands[MI->flat_insn.x86.op_count].mem.disp = DispVal;
if (DispVal || (!MCOperand_getReg(IndexReg) && !MCOperand_getReg(BaseReg))) {
if (DispVal < 0) {
if (DispVal <= -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -DispVal);
else
SStream_concat(O, "-%"PRIu64, -DispVal);
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & DispVal);
} else {
if (DispVal > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, DispVal);
......
......@@ -719,8 +719,14 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *in
} else {
*size = (uint16_t)insn.length;
result = (!translateInstruction(instr, &insn)) ? true : false;
if (handle->detail)
update_pub_insn(&instr->flat_insn, &insn);
if (result) {
if (handle->detail)
update_pub_insn(&instr->flat_insn, &insn);
// save immediate size to print immediate properly
instr->x86_imm_size = insn.immediateSize;
}
return result;
}
}
......@@ -1160,7 +1160,6 @@ static int readSIB(struct InternalInstruction* insn)
case 2:
// dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode");
return -1;
break;
case 4:
sibIndexBase = SIB_INDEX_EAX;
sibBaseBase = SIB_BASE_EAX;
......@@ -1384,8 +1383,7 @@ static int readModRM(struct InternalInstruction* insn)
case 0xc: /* in case REXW.b is set */
insn->eaBase = (insn->addressSize == 4 ?
EA_BASE_sib : EA_BASE_sib64);
readSIB(insn);
if (readDisplacement(insn))
if (readSIB(insn) || readDisplacement(insn))
return -1;
break;
case 0x5:
......@@ -1410,8 +1408,7 @@ static int readModRM(struct InternalInstruction* insn)
case 0x4:
case 0xc: /* in case REXW.b is set */
insn->eaBase = EA_BASE_sib;
readSIB(insn);
if (readDisplacement(insn))
if (readSIB(insn) || readDisplacement(insn))
return -1;
break;
default:
......
......@@ -214,10 +214,7 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
if (MI->csh->detail)
MI->flat_insn.x86.operands[MI->flat_insn.x86.op_count].mem.disp = imm;
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
......@@ -374,7 +371,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
if (MCOperand_isImm(Op)) {
int64_t imm = MCOperand_getImm(Op) + MI->insn_size + MI->address;
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
......@@ -416,7 +413,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
SStream_concat(O, "%"PRIu64, imm);
} else {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
......@@ -439,10 +436,11 @@ static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
} else if (MCOperand_isImm(Op)) {
int64_t imm = MCOperand_getImm(Op);
if (imm < 0) {
if (imm <= -HEX_THRESHOLD)
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);