diff --git a/shlr/udis86/syn.c b/shlr/udis86/syn.c index 1b9e1d42a5..5654bd71f8 100644 --- a/shlr/udis86/syn.c +++ b/shlr/udis86/syn.c @@ -94,7 +94,12 @@ ud_syn_rel_target(struct ud *u, struct ud_operand *opr) const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode); switch (opr->size) { case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask; - case 16: return (u->pc + opr->lval.sword) & trunc_mask; + case 16: { + int delta = (opr->lval.sword & trunc_mask); + if ((u->pc + delta) > 0xffff) + return (u->pc & 0xf0000) + ((u->pc + delta) & 0xffff); + return (u->pc + delta); + } case 32: return (u->pc + opr->lval.sdword) & trunc_mask; default: UD_ASSERT(!"invalid relative offset size."); return 0ull;