|
@@ -16,6 +16,39 @@
|
|
|
*/
|
|
|
static __thread cs_insn *cap_insn;
|
|
|
|
|
|
+/*
|
|
|
+ * The capstone library always skips 2 bytes for S390X.
|
|
|
+ * This is less than ideal, since we can tell from the first two bits
|
|
|
+ * the size of the insn and thus stay in sync with the insn stream.
|
|
|
+ */
|
|
|
+static size_t CAPSTONE_API
|
|
|
+cap_skipdata_s390x_cb(const uint8_t *code, size_t code_size,
|
|
|
+ size_t offset, void *user_data)
|
|
|
+{
|
|
|
+ size_t ilen;
|
|
|
+
|
|
|
+ /* See get_ilen() in target/s390x/internal.h. */
|
|
|
+ switch (code[offset] >> 6) {
|
|
|
+ case 0:
|
|
|
+ ilen = 2;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ ilen = 4;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ilen = 6;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ilen;
|
|
|
+}
|
|
|
+
|
|
|
+static const cs_opt_skipdata cap_skipdata_s390x = {
|
|
|
+ .mnemonic = ".byte",
|
|
|
+ .callback = cap_skipdata_s390x_cb
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* Initialize the Capstone library.
|
|
|
*
|
|
@@ -42,13 +75,20 @@ static cs_err cap_disas_start(disassemble_info *info, csh *handle)
|
|
|
/* "Disassemble" unknown insns as ".byte W,X,Y,Z". */
|
|
|
cs_option(*handle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
|
|
|
|
|
- if (info->cap_arch == CS_ARCH_X86) {
|
|
|
+ switch (info->cap_arch) {
|
|
|
+ case CS_ARCH_SYSZ:
|
|
|
+ cs_option(*handle, CS_OPT_SKIPDATA_SETUP,
|
|
|
+ (uintptr_t)&cap_skipdata_s390x);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case CS_ARCH_X86:
|
|
|
/*
|
|
|
* We don't care about errors (if for some reason the library
|
|
|
* is compiled without AT&T syntax); the user will just have
|
|
|
* to deal with the Intel syntax.
|
|
|
*/
|
|
|
cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
/* Allocate temp space for cs_disasm_iter. */
|