mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-24 14:09:56 +00:00
Merge branch 'next' of https://github.com/aquynh/capstone into next
Conflicts: arch/PowerPC/PPCInstPrinter.c
This commit is contained in:
commit
73835104a4
13
Makefile
13
Makefile
@ -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)
|
||||
|
@ -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
2
TODO
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 ;;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
35
cs.c
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user