On 15/10/2019 19.51, Richard Henderson wrote: > Capstone assumes any unknown instruction is 2 bytes. > Instead, use the ilen field in the first two bits of > the instruction to stay in sync with the insn stream. > > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> > --- > disas.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/disas.c b/disas.c > index 51c71534a3..2a000cbeb0 100644 > --- a/disas.c > +++ b/disas.c > @@ -178,6 +178,39 @@ static int print_insn_od_target(bfd_vma pc, > disassemble_info *info) > to share this across calls and across host vs target disassembly. */ > 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; > +}
The kernel has also a nice function to calculate this: static inline int insn_length(unsigned char code) { return ((((int) code + 64) >> 7) + 1) << 1; } ... but the switch-case is likely easier to read, so anyway: Reviewed-by: Thomas Huth <th...@redhat.com>