ppc: fix endian check (#1029)
* Remove `big_endian` field of `cs_struct`
Added a helper macro `MODE_IS_BIG_ENDIAN()` to check if
`CS_MODE_BIG_ENDIAN` is set.
Refactored `cs_open()` check for valid mode out of arch-specific code
into arch-independent code. Also added a valid mode check to
`cs_option()`. The checks use a new global array
`arch_disallowed_mode_mask[]`, which is initialized in the arch-specific
`*_enable()` functions.
Fixes bug where endianness could not be set for ppc.
* Fix Mac OS brew for Travis CI
diff --git a/cs.c b/cs.c
index 68f60d9..a65299a 100644
--- a/cs.c
+++ b/cs.c
@@ -54,6 +54,7 @@
cs_err (*arch_init[MAX_ARCH])(cs_struct *) = { NULL };
cs_err (*arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t value) = { NULL };
void (*arch_destroy[MAX_ARCH]) (cs_struct *) = { NULL };
+cs_mode arch_disallowed_mode_mask[MAX_ARCH] = { 0 };
extern void ARM_enable(void);
extern void AArch64_enable(void);
@@ -244,6 +245,12 @@
archs_enable();
if (arch < CS_ARCH_MAX && arch_init[arch]) {
+ // verify if requested mode is valid
+ if (mode & arch_disallowed_mode_mask[arch]) {
+ *handle = 0;
+ return CS_ERR_MODE;
+ }
+
ud = cs_mem_calloc(1, sizeof(*ud));
if (!ud) {
// memory insufficient
@@ -253,7 +260,6 @@
ud->errnum = CS_ERR_OK;
ud->arch = arch;
ud->mode = mode;
- ud->big_endian = (mode & CS_MODE_BIG_ENDIAN) != 0;
// by default, do not break instruction into details
ud->detail = CS_OPT_OFF;
@@ -429,6 +435,12 @@
if (value)
handle->skipdata_setup = *((cs_opt_skipdata *)value);
return CS_ERR_OK;
+ case CS_OPT_MODE:
+ // verify if requested mode is valid
+ if (value & arch_disallowed_mode_mask[handle->arch]) {
+ return CS_ERR_OPTION;
+ }
+ break;
}
return arch_option[handle->arch](handle, type, value);