Add cortex-m support to cstool, refactoring and crash fix (#1099)
* cstool: Refactor architecture parsing and fix crash with invalid arch
* cstool: Enable cortex-m decoder
diff --git a/cstool/cstool.c b/cstool/cstool.c
index df4a41d..26fc016 100644
--- a/cstool/cstool.c
+++ b/cstool/cstool.c
@@ -88,6 +88,8 @@
printf(" armbe: arm + big endian\n");
printf(" thumb: thumb mode\n");
printf(" thumbbe: thumb + big endian\n");
+ printf(" cortexm: thumb + cortex-m extensions\n");
+
}
if (cs_support(CS_ARCH_ARM64)) {
@@ -134,6 +136,7 @@
cs_mode md;
cs_arch arch;
bool detail_flag = false;
+ bool x86_att_syntax = false;
if (argc != 3 && argc != 4 && argc != 5) {
usage(argv[0]);
@@ -180,135 +183,82 @@
}
}
- if (!strcmp(mode, "arm")) {
+ if (!strcmp(mode, "arm") || !strcmp(mode, "arml") || !strcmp(mode, "armle")) {
arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle);
- }
-
- if (!strcmp(mode, "armb") || !strcmp(mode, "armbe") ) {
+ md = CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "armb") || !strcmp(mode, "armbe") ) {
arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "arml")) {
+ md = CS_MODE_ARM | CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "thumb") || !strcmp(mode, "thumble")) {
arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "thumb")) {
+ md = CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "thumbbe")) {
arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "thumbbe")) {
+ md = CS_MODE_THUMB | CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "cortexm")) {
arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "thumble")) {
- arch = CS_ARCH_ARM;
- err = cs_open(CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "arm64")) {
+ md = CS_MODE_THUMB | CS_MODE_MCLASS | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "arm64")) {
arch = CS_ARCH_ARM64;
- err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "arm64be")) {
+ md = CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "arm64be")) {
arch = CS_ARCH_ARM64;
- err = cs_open(CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "mips")) {
+ md = CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "mips")) {
arch = CS_ARCH_MIPS;
- err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "mipsbe")) {
+ md = CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "mipsbe")) {
arch = CS_ARCH_MIPS;
- err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "mips64")) {
+ md = CS_MODE_MIPS32 | CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "mips64")) {
arch = CS_ARCH_MIPS;
- err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "mips64be")) {
+ md = CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode, "mips64be")) {
arch = CS_ARCH_MIPS;
- err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "x16")) {
+ md = CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "x16")) {
+ arch = CS_ARCH_X86;
md = CS_MODE_16;
+ } else if (!strcmp(mode, "x32")) {
arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
- }
-
- if (!strcmp(mode, "x32")) {
md = CS_MODE_32;
+ } else if (!strcmp(mode, "x64")) {
arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
- }
-
- if (!strcmp(mode, "x64")) {
md = CS_MODE_64;
+ } else if (!strcmp(mode, "x16att")) {
arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
- }
-
- if (!strcmp(mode, "x16att")) {
md = CS_MODE_16;
+ x86_att_syntax = true;
+ } else if (!strcmp(mode,"x32att")) {
arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
- if (!err) {
- cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
- }
- }
-
- if (!strcmp(mode,"x32att")) {
md = CS_MODE_32;
+ x86_att_syntax = true;
+ } else if (!strcmp(mode,"x64att")) {
arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
- if (!err) {
- cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
- }
- }
-
- if (!strcmp(mode,"x64att")) {
md = CS_MODE_64;
- arch = CS_ARCH_X86;
- err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
- if (!err) {
- cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
- }
- }
-
- if (!strcmp(mode,"ppc64")) {
+ x86_att_syntax = true;
+ } else if (!strcmp(mode,"ppc64")) {
arch = CS_ARCH_PPC;
- err = cs_open(CS_ARCH_PPC, CS_MODE_64 | CS_MODE_LITTLE_ENDIAN, &handle);
- }
-
- if (!strcmp(mode,"ppc64be")) {
+ md = CS_MODE_64 | CS_MODE_LITTLE_ENDIAN;
+ } else if (!strcmp(mode,"ppc64be")) {
arch = CS_ARCH_PPC;
- err = cs_open(CS_ARCH_PPC,CS_MODE_64 | CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode,"sparc")) {
+ md = CS_MODE_64 | CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode,"sparc")) {
arch = CS_ARCH_SPARC;
- err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle);
- }
-
- if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
+ md = CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
arch = CS_ARCH_SYSZ;
- err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle);
+ md = CS_MODE_BIG_ENDIAN;
+ } else if (!strcmp(mode,"xcore")) {
+ arch = CS_ARCH_XCORE;
+ md = CS_MODE_BIG_ENDIAN;
+ } else {
+ printf("ERROR: unknown architecture '%s'!\n", mode);
+ usage(argv[0]);
+ return -1;
}
- if (!strcmp(mode,"xcore")) {
- arch = CS_ARCH_XCORE;
- err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle);
- }
+ err = cs_open(arch, md, &handle);
if (err) {
printf("ERROR: Failed on cs_open(), quit!\n");
@@ -316,6 +266,10 @@
return -1;
}
+ if (arch == CS_ARCH_X86 && x86_att_syntax) {
+ cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
+ }
+
if (detail_flag) {
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
}