Merge branch 'next' of https://github.com/aquynh/capstone into next

Conflicts:
	arch/PowerPC/PPCInstPrinter.c
This commit is contained in:
kratolp 2014-10-01 11:54:14 +02:00
commit 73835104a4
17 changed files with 106 additions and 49 deletions

View File

@ -409,6 +409,19 @@ 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
TESTS = test test_detail test_arm test_arm64 test_mips test_ppc test_sparc
TESTS += test_systemz test_x86 test_xcore
TESTS += test.static test_detail.static test_arm.static test_arm64.static
TESTS += test_mips.static test_ppc.static test_sparc.static
TESTS += test_systemz.static test_x86.static test_xcore.static
TESTS += test_skipdata test_skipdata.static
check:
@for t in $(TESTS); do \
echo Check $$t ... ; \
./tests/$$t > /dev/null && echo OK || echo FAILED; \
done
$(OBJDIR)/%.o: %.c
@mkdir -p $(@D)
ifeq ($(V),0)

View File

@ -1,7 +1,3 @@
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.2 just fine.
For this reason, after upgrading to 2.1.2, users do NOT need to upgrade
their bindings from release 2.1.
The old bindings from version 2.x are not compatible with version 3.0, so
must be updated. For Java/Ocaml/Python bindings, see respective README files
under bindings/ directory in the source on how to reinstall them.

2
TODO
View File

@ -18,4 +18,4 @@ Issues to be solved in next versions
[Bindings]
- OCaml binding are broken due to many API changes. This should be fixed ASAP.
- OCaml binding is working, but still support the core API better.

View File

@ -1342,9 +1342,6 @@ static void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKi
case 'w':
MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTW;
break;
case 'x':
MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTX;
break;
}
} else {
switch(SrcRegKind) {

View File

@ -441,8 +441,6 @@ static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
return rc->RegsBegin[RegNo];
}
#define nullptr NULL
static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
uint64_t Address, MCRegisterInfo *Decoder)
{
@ -451,7 +449,8 @@ static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
// The register class also depends on this.
uint32_t tmp = fieldFromInstruction(insn, 17, 5);
unsigned NSize = 0;
DecodeFN RegDecoder = nullptr;
DecodeFN RegDecoder = NULL;
if ((tmp & 0x18) == 0x00) { // INSVE_B
NSize = 4;
RegDecoder = DecodeMSA128BRegisterClass;
@ -468,20 +467,27 @@ static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
//assert(NSize != 0 && RegDecoder != nullptr);
if (RegDecoder == NULL)
return MCDisassembler_Fail;
// $wd
tmp = fieldFromInstruction(insn, 6, 5);
if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
return MCDisassembler_Fail;
// $wd_in
if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
return MCDisassembler_Fail;
// $n
tmp = fieldFromInstruction(insn, 16, NSize);
MCOperand_CreateImm0(MI, tmp);
// $ws
tmp = fieldFromInstruction(insn, 11, 5);
if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
return MCDisassembler_Fail;
// $n2
MCOperand_CreateImm0(MI, 0);

View File

@ -186,6 +186,14 @@ static name_map reg_name_maps[] = {
{ MIPS_REG_HI, "hi"},
{ MIPS_REG_LO, "lo"},
{ MIPS_REG_PC, "pc"},
{ MIPS_REG_P0, "p0"},
{ MIPS_REG_P1, "p1"},
{ MIPS_REG_P2, "p2"},
{ MIPS_REG_MPL0, "mpl0"},
{ MIPS_REG_MPL1, "mpl1"},
{ MIPS_REG_MPL2, "mpl2"},
};
#endif

View File

@ -736,7 +736,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
#define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
SStream ss;
const char* opCode;
int decCtr, needComma;
int decCtr = false, needComma = false;
char *tmp, *AsmMnem, *AsmOps, *c;
int OpIdx, PrintMethodIdx;
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
@ -774,7 +774,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 0) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 1)) {
SStream_concat(&ss, opCode, "dnzf");
decCtr = 1;
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -782,7 +782,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 2) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 3)) {
SStream_concat(&ss, opCode, "dzf");
decCtr = 1;
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -812,7 +812,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
if(MCOperand_getImm(MCInst_getOperand(MI, 0)) == 7)
SStream_concat0(&ss, "+");
decCtr = 0;
decCtr = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -820,7 +820,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 8) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 9)) {
SStream_concat(&ss, opCode, "dnzt");
decCtr = 1;
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -828,7 +828,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 10) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 11)) {
SStream_concat(&ss, opCode, "dzt");
decCtr = 1;
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -858,7 +858,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
if(MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15)
SStream_concat0(&ss, "+");
decCtr = 0;
decCtr = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -871,7 +871,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
if(MCOperand_getImm(MCInst_getOperand(MI, 0)) == 25)
SStream_concat0(&ss, "+");
needComma = 0;
needComma = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
@ -884,7 +884,7 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
if(MCOperand_getImm(MCInst_getOperand(MI, 0)) == 27)
SStream_concat0(&ss, "+");
needComma = 0;
needComma = false;
}
if (MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
@ -892,8 +892,9 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) {
int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
op_addReg(MI, PPC_REG_CR0+cr-PPC_CR0);
if(decCtr) {
needComma = 1;
needComma = true;
SStream_concat0(&ss, " ");
if(cr > PPC_CR0) {
SStream_concat(&ss, "4*cr%d+", cr-PPC_CR0);
@ -915,17 +916,15 @@ static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
}
} else {
if(cr > PPC_CR0) {
needComma = 1;
needComma = true;
SStream_concat(&ss, " cr%d", cr-PPC_CR0);
} else {
needComma = 0;
}
}
}
if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
MCOperand_getImm(MCInst_getOperand(MI, 2)) != 0) {
if(needComma)
if (needComma)
SStream_concat0(&ss, ",");
SStream_concat0(&ss, " $\xFF\x03\x01");
}

View File

@ -8094,7 +8094,7 @@ bool PPC_alias_insn(const char *name, struct ppc_alias *alias)
// not really an alias insn
i = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name);
if (i) {
if (i != -1) {
alias->id = insn_name_maps[i].id;
alias->cc = PPC_BC_INVALID;
return true;

View File

@ -959,14 +959,13 @@ static bool is16BitEquivalent(unsigned orig, unsigned equiv)
size_t i;
uint16_t idx;
if ((idx = x86_16_bit_eq_lookup[orig]) != 0)
{
for (i = idx - 1; x86_16_bit_eq_tbl[i].first == orig && i < ARR_SIZE(x86_16_bit_eq_tbl); ++i)
{
if ((idx = x86_16_bit_eq_lookup[orig]) != 0) {
for (i = idx - 1; i < ARR_SIZE(x86_16_bit_eq_tbl) && x86_16_bit_eq_tbl[i].first == orig; i++) {
if (x86_16_bit_eq_tbl[i].second == equiv)
return true;
}
}
return false;
}

View File

@ -82,4 +82,9 @@ clean:
cd python && $(MAKE) clean
cd ocaml && $(MAKE) clean
check:
make -C ocaml check
make -C python check
make -C java check
FORCE:

View File

@ -59,3 +59,11 @@ ifdef BUILDDIR
rm -rf $(BLDIR)
rm -rf $(OBJDIR)
endif
TESTS = test arm arm64 mips ppc sparc systemz x86 xcore
check:
@for t in $(TESTS); do \
echo Check $$t ... ; \
./run.sh $$t > /dev/null && echo OK || echo FAILED; \
done

View File

@ -12,6 +12,7 @@ fi
case "$1" in
"") java -classpath ${JNA}:. Test ;;
"test") java -classpath ${JNA}:. Test ;;
"arm") java -classpath ${JNA}:. TestArm ;;
"arm64") java -classpath ${JNA}:. TestArm64 ;;
"mips") java -classpath ${JNA}:. TestMips ;;

View File

@ -260,3 +260,11 @@ clean:
gen_const:
cd .. && python const_generator.py ocaml
TESTS = test test_detail test_arm test_arm64 test_mips test_ppc
TESTS += test_sparc test_systemz test_x86 test_xcore
check:
@for t in $(TESTS); do \
echo Check $$t ... ; \
./$$t > /dev/null && echo OK || echo FAILED; \
done

View File

@ -47,3 +47,13 @@ install_cython:
clean:
rm -rf $(OBJDIR)
rm -f capstone/*.so
TESTS = test.py test_detail.py test_arm.py test_arm64.py test_mips.py test_ppc.py
TESTS += test_sparc.py test_systemz.py test_x86.py test_xcore.py test_skipdata.py
check:
@for t in $(TESTS); do \
echo Check $$t ... ; \
./$$t > /dev/null && echo OK || echo FAILED; \
done

View File

@ -65,7 +65,7 @@ def print_detail(insn):
if len(insn.groups) > 0:
print("\tThis instruction belongs to groups: ", end=''),
for m in insn.groups:
print("%u " % m, end=''),
print("%s " % insn.group_name(m), end=''),
print()

35
cs.c
View File

@ -422,10 +422,10 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
bool r;
void *tmp;
size_t skipdata_bytes;
// save all the original info of the buffer
uint64_t offset_org;
uint64_t offset_org; // save all the original info of the buffer
size_t size_org;
const uint8_t *buffer_org;
unsigned int cache_size = INSN_CACHE_SIZE;
if (!handle) {
// FIXME: how to handle this case:
@ -435,11 +435,17 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
handle->errnum = CS_ERR_OK;
#ifdef CAPSTONE_USE_SYS_DYN_MEM
if (count > 0 && count < INSN_CACHE_SIZE)
cache_size = count;
#endif
// save the original offset for SKIPDATA
buffer_org = buffer;
offset_org = offset;
size_org = size;
total_size = (sizeof(cs_insn) * INSN_CACHE_SIZE);
total_size = sizeof(cs_insn) * cache_size;
total = cs_mem_malloc(total_size);
insn_cache = total;
@ -475,10 +481,15 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
handle->printer(&mci, &ss, handle->printer_info);
fill_insn(handle, insn_cache, ss.buffer, &mci, handle->post_printer, buffer);
c++;
if (count > 0 && c == count)
// disasm requested number of instructions
break;
f++;
if (f == INSN_CACHE_SIZE) {
if (f == cache_size) {
// resize total to contain newly disasm insns
total_size += (sizeof(cs_insn) * INSN_CACHE_SIZE);
total_size += (sizeof(cs_insn) * cache_size);
tmp = cs_mem_realloc(total, total_size);
if (tmp == NULL) { // insufficient memory
if (handle->detail) {
@ -494,17 +505,13 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
}
total = tmp;
insn_cache = (cs_insn *)((char *)total + total_size - (sizeof(cs_insn) * INSN_CACHE_SIZE));
insn_cache = (cs_insn *)((char *)total + total_size - (sizeof(cs_insn) * cache_size));
// reset f back to 0
f = 0;
} else
insn_cache++;
c++;
if (count > 0 && c == count)
break;
buffer += insn_size;
size -= insn_size;
offset += insn_size;
@ -544,10 +551,10 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
insn_cache->detail = NULL;
f++;
if (f == INSN_CACHE_SIZE) {
if (f == cache_size) {
// resize total to contain newly disasm insns
total_size += (sizeof(cs_insn) * INSN_CACHE_SIZE);
total_size += (sizeof(cs_insn) * cache_size);
tmp = cs_mem_realloc(total, total_size);
if (tmp == NULL) { // insufficient memory
if (handle->detail) {
@ -563,7 +570,7 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
}
total = tmp;
insn_cache = (cs_insn *)((char *)total + total_size - (sizeof(cs_insn) * INSN_CACHE_SIZE));
insn_cache = (cs_insn *)((char *)total + total_size - (sizeof(cs_insn) * cache_size));
// reset f back to 0
f = 0;
@ -579,7 +586,7 @@ size_t cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, si
if (f) {
// resize total to contain newly disasm insns
void *tmp = cs_mem_realloc(total, total_size - (INSN_CACHE_SIZE - f) * sizeof(*insn_cache));
void *tmp = cs_mem_realloc(total, total_size - (cache_size - f) * sizeof(*insn_cache));
if (tmp == NULL) { // insufficient memory
// free all detail pointers
if (handle->detail) {

View File

@ -240,7 +240,7 @@ static void test()
if (detail->groups_count > 0) {
printf("\tThis instruction belongs to groups: ");
for (n = 0; n < detail->groups_count; n++) {
printf("%u ", detail->groups[n]);
printf("%s ", cs_group_name(handle, detail->groups[n]));
}
printf("\n");
}