forked from capstone-engine/capstone
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Xtensa: cstest + cstool + test_xtensa.c
- Loading branch information
Showing
11 changed files
with
297 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/usr/bin/env python3 | ||
import argparse | ||
import difflib | ||
import re | ||
import subprocess | ||
import sys | ||
|
||
|
||
def stdout_cmp(f1, f2): | ||
def lines_run(xs): | ||
out = subprocess.run(xs, stdout=subprocess.PIPE, check=True).stdout.decode() | ||
lines = out.splitlines(keepends=True) | ||
return out, [re.sub(r'([\t ])', '', ln) for ln in lines] | ||
|
||
out1, lns1 = lines_run(f1) | ||
out2, lns2 = lines_run(f2) | ||
dif = list(difflib.unified_diff(lns1, lns2)) | ||
return len(dif) == 0, dif | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser(description='Comparing the standard output of two threads') | ||
parser.add_argument("-f1", nargs='+') | ||
parser.add_argument("-f2", nargs='+') | ||
argv = parser.parse_args(sys.argv[1:]) | ||
res, dif = stdout_cmp(argv.f1, argv.f2) | ||
if not res: | ||
print('\n'.join(dif)) | ||
exit(1) | ||
exit(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include <stdio.h> | ||
#include <capstone/capstone.h> | ||
|
||
static inline void print_insn_detail_xtensa(csh handle, cs_insn *ins) | ||
{ | ||
int i; | ||
cs_regs regs_read, regs_write; | ||
uint8_t regs_read_count, regs_write_count; | ||
|
||
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON | ||
if (ins->detail == NULL) | ||
return; | ||
|
||
cs_xtensa *detail = &(ins->detail->xtensa); | ||
|
||
if (detail->op_count) | ||
printf("\top_count: %u\n", detail->op_count); | ||
|
||
for (i = 0; i < detail->op_count; i++) { | ||
cs_xtensa_op *op = &(detail->operands[i]); | ||
if (op->type & CS_OP_REG) | ||
printf("\t\toperands[%u].type: REG = %s\n", i, | ||
cs_reg_name(handle, op->reg)); | ||
else if (op->type & CS_OP_IMM) | ||
printf("\t\toperands[%u].type: IMM = 0x%" PRIx32 "\n", | ||
i, op->imm); | ||
else if (op->type & CS_OP_MEM) | ||
printf("\t\toperands[%u].type: MEM\n" | ||
"\t\t\t.mem.base: REG = %s\n" | ||
"\t\t\t.mem.disp: 0x%" PRIx8 "\n", | ||
i, cs_reg_name(handle, op->mem.base), | ||
op->mem.disp); | ||
if (op->access & CS_AC_READ) | ||
printf("\t\t\t.access: READ\n"); | ||
else if (op->access & CS_AC_WRITE) | ||
printf("\t\t\t.access: WRITE\n"); | ||
else if (op->access & (CS_AC_READ | CS_AC_WRITE)) | ||
printf("\t\t\t.access: READ | WRITE\n"); | ||
} | ||
// Print out all registers accessed by this instruction (either implicit or | ||
// explicit) | ||
if (!cs_regs_access(handle, ins, regs_read, ®s_read_count, | ||
regs_write, ®s_write_count)) { | ||
if (regs_read_count) { | ||
printf("\tRegisters read:"); | ||
for (i = 0; i < regs_read_count; i++) { | ||
printf(" %s", | ||
cs_reg_name(handle, regs_read[i])); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
if (regs_write_count) { | ||
printf("\tRegisters modified:"); | ||
for (i = 0; i < regs_write_count; i++) { | ||
printf(" %s", | ||
cs_reg_name(handle, regs_write[i])); | ||
} | ||
printf("\n"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include "factory.h" | ||
|
||
char *get_detail_xtensa(csh *p_handle, cs_mode mode, cs_insn *ins) | ||
{ | ||
cs_xtensa *detail; | ||
int i; | ||
cs_regs regs_read, regs_write; | ||
uint8_t regs_read_count, regs_write_count; | ||
|
||
if (ins->detail == NULL) | ||
return NULL; | ||
|
||
char *result = (char *)calloc(1024, sizeof(char)); | ||
csh handle = *p_handle; | ||
detail = &(ins->detail->xtensa); | ||
|
||
#define printf(...) add_str(&result, __VA_ARGS__) | ||
|
||
if (detail->op_count) | ||
printf("\top_count: %u\n", detail->op_count); | ||
|
||
for (i = 0; i < detail->op_count; i++) { | ||
cs_xtensa_op *op = &(detail->operands[i]); | ||
if (op->type & CS_OP_REG) | ||
printf("\t\toperands[%u].type: REG = %s\n", i, | ||
cs_reg_name(handle, op->reg)); | ||
else if (op->type & CS_OP_IMM) | ||
printf("\t\toperands[%u].type: IMM = 0x%" PRIx32 "\n", | ||
i, op->imm); | ||
else if (op->type & CS_OP_MEM) | ||
printf("\t\toperands[%u].type: MEM\n" | ||
"\t\t\t.mem.base: REG = %s\n" | ||
"\t\t\t.mem.disp: 0x%" PRIx8 "\n", | ||
i, cs_reg_name(handle, op->mem.base), | ||
op->mem.disp); | ||
if (op->access & CS_AC_READ) | ||
printf("\t\t\t.access: READ\n"); | ||
else if (op->access & CS_AC_WRITE) | ||
printf("\t\t\t.access: WRITE\n"); | ||
else if (op->access & (CS_AC_READ | CS_AC_WRITE)) | ||
printf("\t\t\t.access: READ | WRITE\n"); | ||
} | ||
// Print out all registers accessed by this instruction (either implicit or | ||
// explicit) | ||
if (!cs_regs_access(handle, ins, regs_read, ®s_read_count, | ||
regs_write, ®s_write_count)) { | ||
if (regs_read_count) { | ||
printf("\tRegisters read:"); | ||
for (i = 0; i < regs_read_count; i++) { | ||
printf(" %s", | ||
cs_reg_name(handle, regs_read[i])); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
if (regs_write_count) { | ||
printf("\tRegisters modified:"); | ||
for (i = 0; i < regs_write_count; i++) { | ||
printf(" %s", | ||
cs_reg_name(handle, regs_write[i])); | ||
} | ||
printf("\n"); | ||
} | ||
} | ||
|
||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* Capstone Disassembler Engine */ | ||
/// Capstone xtensa test, by billow <[email protected]> | ||
|
||
#include <stdio.h> | ||
|
||
#include <capstone/platform.h> | ||
#include <capstone/capstone.h> | ||
#include "../cstool/cstool_xtensa.inc" | ||
|
||
struct platform { | ||
cs_arch arch; | ||
cs_mode mode; | ||
unsigned char *code; | ||
size_t size; | ||
char *comment; | ||
}; | ||
|
||
static csh handle; | ||
|
||
static void print_string_hex(const char *comment, unsigned char *str, | ||
size_t len) | ||
{ | ||
unsigned char *c; | ||
|
||
printf("%s", comment); | ||
for (c = str; c < str + len; c++) { | ||
printf("0x%02x ", *c & 0xff); | ||
} | ||
|
||
printf("\n"); | ||
} | ||
|
||
static void test() | ||
{ | ||
#define TEST_CODE "\x60\x51\x60\x32\x51\x02" | ||
|
||
struct platform platforms[] = { | ||
{ | ||
CS_ARCH_XTENSA, | ||
CS_MODE_LITTLE_ENDIAN, | ||
(unsigned char *)TEST_CODE, | ||
sizeof(TEST_CODE) - 1, | ||
"Xtensa", | ||
}, | ||
}; | ||
|
||
uint64_t address = 0x1000; | ||
cs_insn *insn; | ||
int i; | ||
size_t count; | ||
|
||
for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) { | ||
cs_err err = | ||
cs_open(platforms[i].arch, platforms[i].mode, &handle); | ||
if (err) { | ||
printf("Failed on cs_open() with error returned: %u\n", | ||
err); | ||
continue; | ||
} | ||
|
||
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); | ||
|
||
count = cs_disasm(handle, platforms[i].code, platforms[i].size, | ||
address, 0, &insn); | ||
if (count) { | ||
size_t j; | ||
|
||
printf("****************\n"); | ||
printf("Platform: %s\n", platforms[i].comment); | ||
print_string_hex("Code:", platforms[i].code, | ||
platforms[i].size); | ||
printf("Disasm:\n"); | ||
|
||
for (j = 0; j < count; j++) { | ||
printf("0x%" PRIx64 ":\t%s\t%s\n", | ||
insn[j].address, insn[j].mnemonic, | ||
insn[j].op_str); | ||
print_insn_detail_xtensa(handle, &insn[j]); | ||
} | ||
|
||
// free memory allocated by cs_disasm() | ||
cs_free(insn, count); | ||
} else { | ||
printf("****************\n"); | ||
printf("Platform: %s\n", platforms[i].comment); | ||
print_string_hex("Code:", platforms[i].code, | ||
platforms[i].size); | ||
printf("ERROR: Failed to disasm given code!\n"); | ||
} | ||
|
||
cs_close(&handle); | ||
} | ||
} | ||
|
||
int main() | ||
{ | ||
test(); | ||
|
||
return 0; | ||
} |