diff options
Diffstat (limited to 'libcpu/i386_disasm.c')
-rw-r--r-- | libcpu/i386_disasm.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c index 75936356..9961e4d9 100644 --- a/libcpu/i386_disasm.c +++ b/libcpu/i386_disasm.c @@ -393,17 +393,16 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, bufcnt = 0; size_t cnt = 0; + next_match: while (curr < match_end) { - const uint8_t *start = curr; - uint_fast8_t len = *curr++; + const uint8_t *start = curr; assert (len > 0); - assert (curr + 2 * len + 2 <= match_end); + assert (curr + 2 * len <= match_end); const uint8_t *codep = data; - size_t avail = len; int correct_prefix = 0; int opoff = 0; @@ -411,8 +410,6 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, { /* We match a prefix byte. This is exactly one byte and is matched exactly, without a mask. */ - --avail; - --len; start += 2; opoff = 8; @@ -423,25 +420,23 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr, correct_prefix = last_prefix_bit; } + size_t avail = len; while (avail > 0) { uint_fast8_t masked = *codep++ & *curr++; if (masked != *curr++) - break; + { + not: + curr = start + 2 * len; + ++cnt; + goto next_match; + } --avail; if (codep == end && avail > 0) goto do_ret; } - if (avail != 0) - { - not: - curr = start + 1 + 2 * len + 2; - ++cnt; - continue; - } - if (len > end - data) /* There is not enough data for the entire instruction. The caller can figure this out by looking at the pointer into |