Merge branch 'master' of https://github.com/danghvu/capstone into autogen
diff --git a/Makefile b/Makefile
index b8088df..7740893 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@
LIBNAME = capstone
LIBOBJ =
-LIBOBJ += cs.o asprintf.o utils.o SStream.o MCInstrDesc.o MCRegisterInfo.o
+LIBOBJ += cs.o utils.o SStream.o MCInstrDesc.o MCRegisterInfo.o
LIBOBJ += arch/ARM/ARMDisassembler.o arch/ARM/ARMInstPrinter.o arch/ARM/mapping.o
LIBOBJ += arch/X86/X86DisassemblerDecoder.o arch/X86/X86Disassembler.o arch/X86/X86IntelInstPrinter.o arch/X86/X86ATTInstPrinter.o arch/X86/mapping.o
LIBOBJ += arch/Mips/MipsDisassembler.o arch/Mips/MipsInstPrinter.o arch/Mips/mapping.o
diff --git a/arch/AArch64/AArch64BaseInfo.c b/arch/AArch64/AArch64BaseInfo.c
index bbed5a8..1b9ead0 100644
--- a/arch/AArch64/AArch64BaseInfo.c
+++ b/arch/AArch64/AArch64BaseInfo.c
@@ -14,9 +14,9 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
-#include "../../asprintf.h"
#include "../../utils.h"
+#include <stdio.h>
#include <stdlib.h>
#include "AArch64BaseInfo.h"
@@ -568,21 +568,23 @@
{"ich_lr15_el2", A64SysReg_ICH_LR15_EL2}
};
-// NOTE: caller must free() the result itself
-char *SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid)
+// result must be a big enough buffer: 128 bytes is more than enough
+void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result)
{
unsigned i;
for (i = 0; i < ARR_SIZE(SysRegPairs); ++i) {
if (SysRegPairs[i].Value == Bits) {
*Valid = true;
- return strdup(SysRegPairs[i].Name);
+ strcpy(result, SysRegPairs[i].Name);
+ return;
}
}
for (i = 0; i < S->NumInstPairs; ++i) {
if (S->InstPairs[i].Value == Bits) {
*Valid = true;
- return strdup(S->InstPairs[i].Name);
+ strcpy(result, S->InstPairs[i].Name);
+ return;
}
}
@@ -596,31 +598,27 @@
// name.
if (Op0 != 3 || (CRn != 11 && CRn != 15)) {
*Valid = false;
- return NULL;
+ return;
}
//assert(Op0 == 3 && (CRn == 11 || CRn == 15) && "Invalid generic sysreg");
*Valid = true;
- //return "s3_" + utostr(Op1) + "_c" + utostr(CRn) + "_c" + utostr(CRm) + "_" + utostr(Op2);
-
char *Op1S, *CRnS, *CRmS, *Op2S;
Op1S = utostr(Op1, false);
CRnS = utostr(CRn, false);
CRmS = utostr(CRm, false);
Op2S = utostr(Op2, false);
- char *result;
- int dummy = asprintf(&result, "s3_%s_c%s_c%s_%s", Op1S, CRnS, CRmS, Op2S);
+ //printf("Op1S: %s, CRnS: %s, CRmS: %s, Op2S: %s\n", Op1S, CRnS, CRmS, Op2S);
+ int dummy = sprintf(result, "s3_%s_c%s_c%s_%s", Op1S, CRnS, CRmS, Op2S);
(void)dummy;
free(Op1S);
free(CRnS);
free(CRmS);
free(Op2S);
-
- return result;
}
static NamedImmMapper_Mapping TLBIPairs[] = {
diff --git a/arch/AArch64/AArch64BaseInfo.h b/arch/AArch64/AArch64BaseInfo.h
index d7a4504..5f527d0 100644
--- a/arch/AArch64/AArch64BaseInfo.h
+++ b/arch/AArch64/AArch64BaseInfo.h
@@ -858,6 +858,6 @@
bool NamedImmMapper_validImm(NamedImmMapper *N, uint32_t Value);
-char *SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid);
+void SysRegMapper_toString(SysRegMapper *S, uint32_t Bits, bool *Valid, char *result);
#endif
diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c
index e9e883d..e849050 100644
--- a/arch/AArch64/AArch64Disassembler.c
+++ b/arch/AArch64/AArch64Disassembler.c
@@ -772,8 +772,8 @@
void *Decoder)
{
bool ValidNamed;
- char *str = SysRegMapper_toString(Mapper, Val, &ValidNamed);
- free(str);
+ char result[128];
+ SysRegMapper_toString(Mapper, Val, &ValidNamed, result);
MCInst_addOperand(Inst, MCOperand_CreateImm(Val));
diff --git a/arch/AArch64/AArch64GenAsmWriter.inc b/arch/AArch64/AArch64GenAsmWriter.inc
index 8987188..df707f8 100644
--- a/arch/AArch64/AArch64GenAsmWriter.inc
+++ b/arch/AArch64/AArch64GenAsmWriter.inc
@@ -3729,7 +3729,7 @@
uint64_t Bits1 = OpInfo[MCInst_getOpcode(MI)];
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
- SStream_concat(O, AsmStrs+(Bits & 4095)-1);
+ SStream_concat(O, "%s",AsmStrs+(Bits & 4095)-1);
// printf("Frag-0 : %lu\n", (Bits >> 12) & 15);
// Fragment 0 encoded into 4 bits for 15 unique commands.
diff --git a/arch/AArch64/AArch64InstPrinter.c b/arch/AArch64/AArch64InstPrinter.c
index 1bdc14d..dca077a 100644
--- a/arch/AArch64/AArch64InstPrinter.c
+++ b/arch/AArch64/AArch64InstPrinter.c
@@ -372,14 +372,15 @@
static void printSysRegOperand(SysRegMapper *Mapper,
MCInst *MI, unsigned OpNum, SStream *O)
{
+ bool ValidName;
+ char Name[128];
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
- bool ValidName;
- char *Name = SysRegMapper_toString(Mapper, MCOperand_getImm(MO), &ValidName);
+ SysRegMapper_toString(Mapper, MCOperand_getImm(MO), &ValidName, Name);
if (ValidName) {
SStream_concat(O, Name);
}
- free(Name);
}
#define GET_REGINFO_ENUM
diff --git a/arch/AArch64/mapping.c b/arch/AArch64/mapping.c
index 895d2a2..e956044 100644
--- a/arch/AArch64/mapping.c
+++ b/arch/AArch64/mapping.c
@@ -1884,6 +1884,17 @@
// call cs_reg_write() with handle = 1 to pass handle check
// we only need to find if this insn modifies ARM64_REG_NZCV
insn->arm64.update_flags = cs_reg_write(1, insn, ARM64_REG_NZCV);
+
+ if (insns[i].branch || insns[i].indirect_branch) {
+ // this insn also belongs to JUMP group
+ int j;
+ for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
+ if (insn->groups[j] == 0) {
+ insn->groups[j] = ARM64_GRP_JUMP;
+ break;
+ }
+ }
+ }
}
}
diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c
index a008a47..22500a8 100644
--- a/arch/ARM/ARMDisassembler.c
+++ b/arch/ARM/ARMDisassembler.c
@@ -22,6 +22,7 @@
#include "../../MCRegisterInfo.h"
#include "../../LEB128.h"
#include "../../MCDisassembler.h"
+#include "../../cs_priv.h"
#include "ARMDisassembler.h"
@@ -40,13 +41,7 @@
#define GET_INSTRINFO_ENUM
#include "ARMGenInstrInfo.inc"
-typedef struct ITStatus {
- //std_vector<unsigned char> ITStates;
- unsigned char ITStates[128]; // FIXME
- unsigned int size;
-} ITStatus;
-
-static bool ITStatus_push_back(ITStatus *it, char v)
+static bool ITStatus_push_back(ARM_ITStatus *it, char v)
{
it->ITStates[it->size] = v;
it->size++;
@@ -55,14 +50,14 @@
}
// Returns true if the current instruction is in an IT block
-static bool ITStatus_instrInITBlock(ITStatus *it)
+static bool ITStatus_instrInITBlock(ARM_ITStatus *it)
{
//return !ITStates.empty();
return (it->size > 0);
}
// Returns true if current instruction is the last instruction in an IT block
-static bool ITStatus_instrLastInITBlock(ITStatus *it)
+static bool ITStatus_instrLastInITBlock(ARM_ITStatus *it)
{
return (it->size == 1);
}
@@ -70,7 +65,7 @@
// Handles the condition code status of instructions in IT blocks
// Returns the condition code for instruction in IT block
-static unsigned ITStatus_getITCC(ITStatus *it)
+static unsigned ITStatus_getITCC(ARM_ITStatus *it)
{
unsigned CC = ARMCC_AL;
if (ITStatus_instrInITBlock(it))
@@ -80,7 +75,7 @@
}
// Advances the IT block state to the next T or E
-static void ITStatus_advanceITState(ITStatus *it)
+static void ITStatus_advanceITState(ARM_ITStatus *it)
{
//ITStates.pop_back();
it->size--;
@@ -89,7 +84,7 @@
// Called when decoding an IT instruction. Sets the IT state for the following
// instructions that for the IT block. Firstcond and Mask correspond to the
// fields in the IT instruction encoding.
-static void ITStatus_setITState(ITStatus *it, char Firstcond, char Mask)
+static void ITStatus_setITState(ARM_ITStatus *it, char Firstcond, char Mask)
{
// (3 - the number of trailing zeros) is the number of then / else.
unsigned CondBit0 = Firstcond & 1;
@@ -110,9 +105,6 @@
/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
-// FIXME: make this ITBlock private for each Disassembler handle
-static ITStatus ITBlock;
-
static bool Check(DecodeStatus *Out, DecodeStatus In)
{
switch (In) {
@@ -423,12 +415,12 @@
0);
}
-static DecodeStatus _ARM_getInstruction(MCInst *MI, unsigned char *code, size_t code_len,
+static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, unsigned char *code, size_t code_len,
uint16_t *Size, size_t Address)
{
uint8_t bytes[4];
- ITBlock.size = 0;
+ ud->ITBlock.size = 0;
//assert(!(STI.getFeatureBits() & ARM_ModeThumb) &&
// "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
@@ -547,7 +539,7 @@
// encoding, but rather get their predicates from IT context. We need
// to fix up the predicate operands using this context information as a
// post-pass.
-static DecodeStatus AddThumbPredicate(MCInst *MI)
+static DecodeStatus AddThumbPredicate(cs_struct *ud, MCInst *MI)
{
DecodeStatus S = MCDisassembler_Success;
@@ -566,7 +558,7 @@
case ARM_tSETEND:
// Some instructions (mostly conditional branches) are not
// allowed in IT blocks.
- if (ITStatus_instrInITBlock(&ITBlock))
+ if (ITStatus_instrInITBlock(&(ud->ITBlock)))
S = MCDisassembler_SoftFail;
else
return MCDisassembler_Success;
@@ -578,7 +570,7 @@
// Some instructions (mostly unconditional branches) can
// only appears at the end of, or outside of, an IT.
//if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
- if (ITStatus_instrInITBlock(&ITBlock) && !ITStatus_instrLastInITBlock(&ITBlock))
+ if (ITStatus_instrInITBlock(&(ud->ITBlock)) && !ITStatus_instrLastInITBlock(&(ud->ITBlock)))
S = MCDisassembler_SoftFail;
break;
default:
@@ -588,11 +580,11 @@
// If we're in an IT block, base the predicate on that. Otherwise,
// assume a predicate of AL.
unsigned CC;
- CC = ITStatus_getITCC(&ITBlock);
+ CC = ITStatus_getITCC(&(ud->ITBlock));
if (CC == 0xF)
CC = ARMCC_AL;
- if (ITStatus_instrInITBlock(&ITBlock))
- ITStatus_advanceITState(&ITBlock);
+ if (ITStatus_instrInITBlock(&(ud->ITBlock)))
+ ITStatus_advanceITState(&(ud->ITBlock));
MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
@@ -623,12 +615,12 @@
// mode, the auto-generated decoder will give them an (incorrect)
// predicate operand. We need to rewrite these operands based on the IT
// context as a post-pass.
-static void UpdateThumbVFPPredicate(MCInst *MI)
+static void UpdateThumbVFPPredicate(cs_struct *ud, MCInst *MI)
{
unsigned CC;
- CC = ITStatus_getITCC(&ITBlock);
- if (ITStatus_instrInITBlock(&ITBlock))
- ITStatus_advanceITState(&ITBlock);
+ CC = ITStatus_getITCC(&(ud->ITBlock));
+ if (ITStatus_instrInITBlock(&(ud->ITBlock)))
+ ITStatus_advanceITState(&(ud->ITBlock));
MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
@@ -645,12 +637,12 @@
}
}
-static DecodeStatus _Thumb_getInstruction(MCInst *MI, unsigned char *code, size_t code_len,
+static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, unsigned char *code, size_t code_len,
uint16_t *Size, size_t Address)
{
uint8_t bytes[4];
- ITBlock.size = 0;
+ ud->ITBlock.size = 0;
//assert((STI.getFeatureBits() & ARM_ModeThumb) &&
// "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
@@ -665,7 +657,7 @@
DecodeStatus result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 2;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
return result;
}
@@ -673,8 +665,8 @@
result = decodeInstruction_2(DecoderTableThumbSBit16, MI, insn16, Address, 2);
if (result) {
*Size = 2;
- bool InITBlock = ITStatus_instrInITBlock(&ITBlock);
- Check(&result, AddThumbPredicate(MI));
+ bool InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
+ Check(&result, AddThumbPredicate(ud, MI));
AddThumb1SBit(MI, InITBlock);
return result;
}
@@ -686,10 +678,10 @@
// Nested IT blocks are UNPREDICTABLE. Must be checked before we add
// the Thumb predicate.
- if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&ITBlock))
+ if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&(ud->ITBlock)))
result = MCDisassembler_SoftFail;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
// If we find an IT instruction, we need to parse its condition
// code and mask operands so that we can apply them correctly
@@ -698,7 +690,7 @@
unsigned Firstcond = MCOperand_getImm(MCInst_getOperand(MI, 0));
unsigned Mask = MCOperand_getImm(MCInst_getOperand(MI, 1));
- ITStatus_setITState(&ITBlock, Firstcond, Mask);
+ ITStatus_setITState(&(ud->ITBlock), Firstcond, Mask);
}
return result;
@@ -720,8 +712,8 @@
result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- bool InITBlock = ITStatus_instrInITBlock(&ITBlock);
- Check(&result, AddThumbPredicate(MI));
+ bool InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
+ Check(&result, AddThumbPredicate(ud, MI));
AddThumb1SBit(MI, InITBlock);
return result;
}
@@ -730,7 +722,7 @@
result = decodeInstruction_4(DecoderTableThumb232, MI, insn32, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
return result;
}
@@ -738,7 +730,7 @@
result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- UpdateThumbVFPPredicate(MI);
+ UpdateThumbVFPPredicate(ud, MI);
return result;
}
@@ -747,7 +739,7 @@
result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- UpdateThumbVFPPredicate(MI);
+ UpdateThumbVFPPredicate(ud, MI);
return result;
}
}
@@ -764,7 +756,7 @@
result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn32, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
return result;
}
}
@@ -777,7 +769,7 @@
result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
return result;
}
}
@@ -791,7 +783,7 @@
result = decodeInstruction_4(DecoderTableNEONData32, MI, NEONDataInsn, Address, 2);
if (result != MCDisassembler_Fail) {
*Size = 4;
- Check(&result, AddThumbPredicate(MI));
+ Check(&result, AddThumbPredicate(ud, MI));
return result;
}
}
@@ -825,7 +817,7 @@
bool Thumb_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr,
uint16_t *size, size_t address, void *info)
{
- DecodeStatus status = _Thumb_getInstruction(instr, code, code_len, size, address);
+ DecodeStatus status = _Thumb_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
//return status == MCDisassembler_Success;
return status != MCDisassembler_Fail;
@@ -834,7 +826,7 @@
bool ARM_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr,
uint16_t *size, size_t address, void *info)
{
- DecodeStatus status = _ARM_getInstruction(instr, code, code_len, size, address);
+ DecodeStatus status = _ARM_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
//return status == MCDisassembler_Success;
return status != MCDisassembler_Fail;
diff --git a/arch/ARM/ARMGenAsmWriter.inc b/arch/ARM/ARMGenAsmWriter.inc
index 3e28452..2bfb39d 100644
--- a/arch/ARM/ARMGenAsmWriter.inc
+++ b/arch/ARM/ARMGenAsmWriter.inc
@@ -6114,7 +6114,7 @@
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
//assert(Bits != 0 && "Cannot print this instruction.");
- SStream_concat(O, AsmStrs+(Bits & 4095)-1);
+ SStream_concat(O, "%s", AsmStrs+(Bits & 4095)-1);
//printf("Frag-0: %lu\n", (Bits >> 12) & 31);
// Fragment 0 encoded into 5 bits for 29 unique commands.
diff --git a/arch/ARM/mapping.c b/arch/ARM/mapping.c
index 1641507..a7b8595 100644
--- a/arch/ARM/mapping.c
+++ b/arch/ARM/mapping.c
@@ -2306,6 +2306,17 @@
memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
insn->arm.update_flags = cs_reg_write(1, insn, ARM_REG_CPSR);
+
+ if (insns[i].branch || insns[i].indirect_branch) {
+ // this insn also belongs to JUMP group
+ int j;
+ for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
+ if (insn->groups[j] == 0) {
+ insn->groups[j] = ARM_GRP_JUMP;
+ break;
+ }
+ }
+ }
}
}
diff --git a/arch/Mips/MipsGenAsmWriter.inc b/arch/Mips/MipsGenAsmWriter.inc
index 42e2e84..fe1b836 100644
--- a/arch/Mips/MipsGenAsmWriter.inc
+++ b/arch/Mips/MipsGenAsmWriter.inc
@@ -3696,7 +3696,7 @@
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
//assert(Bits != 0 && "Cannot print this instruction.");
- SStream_concat(O, AsmStrs+(Bits & 8191)-1);
+ SStream_concat(O, "%s", AsmStrs+(Bits & 8191)-1);
// Fragment 0 encoded into 3 bits for 6 unique commands.
//printf("\nFrag-0: %llu\n", (Bits >> 13) & 7);
diff --git a/arch/Mips/mapping.c b/arch/Mips/mapping.c
index fe0872b..8127c34 100644
--- a/arch/Mips/mapping.c
+++ b/arch/Mips/mapping.c
@@ -1390,6 +1390,17 @@
memcpy(insn->regs_write, alias_insns[i].regs_mod, sizeof(alias_insns[i].regs_mod));
memcpy(insn->groups, alias_insns[i].groups, sizeof(alias_insns[i].groups));
+ if (insns[i].branch || insns[i].indirect_branch) {
+ // this insn also belongs to JUMP group
+ int j;
+ for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
+ if (insn->groups[j] == 0) {
+ insn->groups[j] = MIPS_GRP_JUMP;
+ break;
+ }
+ }
+ }
+
return;
}
}
@@ -1400,6 +1411,17 @@
memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+
+ if (insns[i].branch || insns[i].indirect_branch) {
+ // this insn also belongs to JUMP group
+ int j;
+ for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
+ if (insn->groups[j] == 0) {
+ insn->groups[j] = MIPS_GRP_JUMP;
+ break;
+ }
+ }
+ }
}
}
diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c
index 285d5e6..f604dc8 100644
--- a/arch/X86/X86ATTInstPrinter.c
+++ b/arch/X86/X86ATTInstPrinter.c
@@ -144,16 +144,34 @@
static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
{
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%%%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
{
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%%%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
{
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%%%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
diff --git a/arch/X86/X86GenAsmWriter.inc b/arch/X86/X86GenAsmWriter.inc
index 0c5cca0..a4bf5d4 100644
--- a/arch/X86/X86GenAsmWriter.inc
+++ b/arch/X86/X86GenAsmWriter.inc
@@ -12150,7 +12150,7 @@
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
//assert(Bits != 0 && "Cannot print this instruction.");
- SStream_concat(O, AsmStrs+(Bits & 16383)-1);
+ SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
// Fragment 0 encoded into 7 bits for 65 unique commands.
// printf(">>> frag-0: %lu\n", (Bits >> 14) & 127);
diff --git a/arch/X86/X86GenAsmWriter1.inc b/arch/X86/X86GenAsmWriter1.inc
index a5f4bc8..40f9b91 100644
--- a/arch/X86/X86GenAsmWriter1.inc
+++ b/arch/X86/X86GenAsmWriter1.inc
@@ -11837,7 +11837,7 @@
uint64_t Bits2 = OpInfo2[MCInst_getOpcode(MI)];
uint64_t Bits = (Bits2 << 32) | Bits1;
//assert(Bits != 0 && "Cannot print this instruction.");
- SStream_concat(O, AsmStrs+(Bits & 16383)-1);
+ SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
// printf("F0: %lu\n", (Bits >> 14) & 63);
diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c
index 5dd0caa..f9ff156 100644
--- a/arch/X86/X86IntelInstPrinter.c
+++ b/arch/X86/X86IntelInstPrinter.c
@@ -142,12 +142,26 @@
static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
{
SStream_concat(O, "byte ptr ");
+
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
{
SStream_concat(O, "word ptr ");
+
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
@@ -155,6 +169,13 @@
static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
{
SStream_concat(O, "dword ptr ");
+
+ // If this has a segment register, print it.
+ // this is a hack. will fix it later
+ if (MI->pub_insn.x86.segment) {
+ SStream_concat(O, "%s:", X86_reg_name(MI->pub_insn.x86.segment));
+ }
+
printMemOffset(MI, OpNo, O);
}
diff --git a/arch/X86/mapping.c b/arch/X86/mapping.c
index 49cbc3a..e6a3c2b 100644
--- a/arch/X86/mapping.c
+++ b/arch/X86/mapping.c
@@ -19,14 +19,14 @@
// Fill-ins to make the compiler happy. These constants are never actually
// assigned; they are just filler to make an automatically-generated switch
// statement work.
-static enum {
+enum {
X86_REG_BX_SI = 500,
X86_REG_BX_DI = 501,
X86_REG_BP_SI = 502,
X86_REG_BP_DI = 503,
X86_REG_sib = 504,
X86_REG_sib64 = 505
-} __attribute__((unused)) _dummy;
+};
static x86_reg sib_index_map[] = {
X86_REG_INVALID,
@@ -6579,6 +6579,17 @@
memcpy(insn->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
memcpy(insn->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
memcpy(insn->groups, insns[i].groups, sizeof(insns[i].groups));
+
+ if (insns[i].branch || insns[i].indirect_branch) {
+ // this insn also belongs to JUMP group
+ int j;
+ for (j = 0; j < ARR_SIZE(insns[i].groups); j++) {
+ if (insn->groups[j] == 0) {
+ insn->groups[j] = X86_GRP_JUMP;
+ break;
+ }
+ }
+ }
}
}
diff --git a/asprintf.c b/asprintf.c
deleted file mode 100644
index dc3ead8..0000000
--- a/asprintf.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2007, The xFTPd Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the xFTPd Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * * Redistributions of this project or parts of this project in any form
- * must retain the following aknowledgment:
- * "This product includes software developed by the xFTPd Project.
- * http://www.xftpd.com/ - http://www.xftpd.org/"
- *
- * THIS SOFTWARE IS PROVIDED BY THE xFTPd PROJECT ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE xFTPd PROJECT BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* MinGW lacks asprintf */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-int vasprintf(char **strp, const char *fmt, va_list ap)
-{
- FILE *dev_null;
- int arg_len;
-
- dev_null = fopen("nul", "w");
- arg_len = vfprintf(dev_null, fmt, ap);
- if(arg_len != -1) {
- *strp = (char *)malloc((size_t)arg_len + 1);
- arg_len = vsprintf(*strp, fmt, ap);
- } else *strp = NULL;
- fclose(dev_null);
- return arg_len;
-}
-
-int asprintf(char **strp, const char *fmt, ...)
-{
- int result;
-
- va_list args;
- va_start(args, fmt);
- result = vasprintf(strp, fmt, args);
- va_end(args);
- return result;
-}
diff --git a/asprintf.h b/asprintf.h
deleted file mode 100644
index 0000db1..0000000
--- a/asprintf.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2007, The xFTPd Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the xFTPd Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * * Redistributions of this project or parts of this project in any form
- * must retain the following aknowledgment:
- * "This product includes software developed by the xFTPd Project.
- * http://www.xftpd.com/ - http://www.xftpd.org/"
- *
- * THIS SOFTWARE IS PROVIDED BY THE xFTPd PROJECT ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE xFTPd PROJECT BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* MinGW lacks asprintf */
-
-#ifndef __ASPRINTF_H
-#define __ASPRINTF_H
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <stdarg.h>
-#endif
-
-int asprintf(char **ret, const char *fmt, ...);
-int vasprintf(char **strp, const char *fmt, va_list ap);
-
-#endif /* __ASPRINTF_H */
diff --git a/cs_priv.h b/cs_priv.h
index 32e03f5..07eeda8 100644
--- a/cs_priv.h
+++ b/cs_priv.h
@@ -21,6 +21,12 @@
typedef void (*GetID_t)(cs_insn *insn, unsigned int id);
+// for ARM only
+typedef struct ARM_ITStatus {
+ unsigned char ITStates[128]; // FIXME
+ unsigned int size;
+} ARM_ITStatus;
+
typedef struct cs_struct {
cs_arch arch;
cs_mode mode;
@@ -35,6 +41,7 @@
PostPrinter_t post_printer;
bool micro_mips; // for Mips only
cs_err errnum;
+ ARM_ITStatus ITBlock; // for Arm only
} cs_struct;
#endif
diff --git a/include/arm.h b/include/arm.h
index b18c565..3151ec8 100644
--- a/include/arm.h
+++ b/include/arm.h
@@ -670,6 +670,8 @@
ARM_GRP_CRC,
ARM_GRP_DPVFP,
ARM_GRP_V6M,
+
+ ARM_GRP_JUMP, // jump insn (including conditional+direct+indirect jumps)
ARM_GRP_MAX,
} arm_insn_group;
diff --git a/include/arm64.h b/include/arm64.h
index 8777897..dca5bfe 100644
--- a/include/arm64.h
+++ b/include/arm64.h
@@ -706,6 +706,7 @@
ARM64_INS_NGC,
ARM64_INS_NEG,
+ ARM64_GRP_JUMP, // jump insn (including conditional+direct+indirect jumps)
ARM64_INS_MAX,
} arm64_insn;
diff --git a/include/mips.h b/include/mips.h
index de65e78..4d05092 100644
--- a/include/mips.h
+++ b/include/mips.h
@@ -669,6 +669,8 @@
MIPS_GRP_NONANSFPMATH,
MIPS_GRP_NOTFP64BIT,
MIPS_GRP_RELOCSTATIC,
+
+ MIPS_GRP_JUMP, // jump insn (including conditional+direct+indirect jumps)
MIPS_GRP_MAX,
} mips_insn_group;
diff --git a/include/x86.h b/include/x86.h
index 7cf8cf5..d397117 100644
--- a/include/x86.h
+++ b/include/x86.h
@@ -1430,6 +1430,8 @@
X86_GRP_CDI,
X86_GRP_ERI,
X86_GRP_TBM,
+
+ X86_GRP_JUMP, // jump insn (including conditional+direct+indirect jumps)
X86_GRP_MAX
} x86_insn_group;
diff --git a/tests/test_arm.c b/tests/test_arm.c
index 9737980..4dbdaf0 100644
--- a/tests/test_arm.c
+++ b/tests/test_arm.c
@@ -152,6 +152,7 @@
//#define THUMB_CODE "\x00\x47" // bx r0
//#define THUMB_CODE "\x01\x47" // bx r0
//#define THUMB_CODE "\x02\x47" // bx r0
+//#define THUMB_CODE "\x0a\xbf" // itet eq
#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1"
#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
diff --git a/tests/test_arm64.c b/tests/test_arm64.c
index 993df04..29d1449 100644
--- a/tests/test_arm64.c
+++ b/tests/test_arm64.c
@@ -133,6 +133,7 @@
//#define ARM64_CODE "\x20\x00\x02\xab" // adds x0, x1, x2 (alias of adds x0, x1, x2, lsl #0)
//#define ARM64_CODE "\x20\xf4\x18\x9e" // fcvtzs x0, s1, #3
//#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2
+//#define ARM64_CODE "\xd0\xb6\x1e\xd5" // msr s3_6_c11_c6_6, x16
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b"
struct platform platforms[] = {
diff --git a/tests/test_detail.c b/tests/test_detail.c
index 51b6178..d196190 100644
--- a/tests/test_detail.c
+++ b/tests/test_detail.c
@@ -46,6 +46,8 @@
//#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0
//#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x10\x20\x21\x1e"
+//#define THUMB_CODE "\x0a\xbf" // itet eq
+//#define X86_CODE32 "\x77\x04" // ja +6
struct platform platforms[] = {
{
diff --git a/tests/test_x86.c b/tests/test_x86.c
index d1d8298..4d9eb18 100644
--- a/tests/test_x86.c
+++ b/tests/test_x86.c
@@ -113,6 +113,8 @@
//#define X86_CODE16 "\x67\x00\x18"
//#define X86_CODE32 "\xd1\xe1" // shl ecx, 1
#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6"
+//#define X86_CODE32 "\x64\xa1\x18\x00\x00\x00" // mov eax, dword ptr fs:[18]
+//#define X86_CODE32 "\x64\xa3\x00\x00\x00\x00" // mov [fs:0x0], eax
struct platform platforms[] = {
{