diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-07-30 17:30:12 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-07-30 17:30:12 -0700 |
commit | f7d863b7d1703b055f11e0087baac640b016b880 (patch) | |
tree | 3fa7ef72ba6a9644a8e9f71ef86d9c3f317917b1 | |
parent | ecf8c3e38256739e5761c714aa4331f13790a7a9 (diff) | |
download | nasm-f7d863b7d1703b055f11e0087baac640b016b880.tar.gz |
BR 2028910: fix decoding of VEX prefixes in 16- and 32-bit mode
We would incorrectly set a bunch of VEX-related state for C4 and C5
bytes, even though we had already rejected it as not a VEX prefix due
to the top two bits of the following byte not being 11.
-rw-r--r-- | disasm.c | 33 |
1 files changed, 17 insertions, 16 deletions
@@ -1073,24 +1073,25 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, if (segsize == 64 || (data[1] & 0xc0) == 0xc0) { prefix.vex[0] = *data++; prefix.vex[1] = *data++; - if (prefix.vex[0] == 0xc4) + + prefix.rex = REX_V; + + if (prefix.vex[0] == 0xc4) { prefix.vex[2] = *data++; - } - prefix.rex = REX_V; - if (prefix.vex[0] == 0xc4) { - prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */ - prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W; - prefix.vex_m = prefix.vex[1] & 0x1f; - prefix.vex_v = (~prefix.vex[2] >> 3) & 15; - prefix.vex_lp = prefix.vex[2] & 7; - } else { - prefix.rex |= (~prefix.vex[1] >> (7-2)) & REX_R; - prefix.vex_m = 1; - prefix.vex_v = (~prefix.vex[1] >> 3) & 15; - prefix.vex_lp = prefix.vex[1] & 7; - } + prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */ + prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W; + prefix.vex_m = prefix.vex[1] & 0x1f; + prefix.vex_v = (~prefix.vex[2] >> 3) & 15; + prefix.vex_lp = prefix.vex[2] & 7; + } else { + prefix.rex |= (~prefix.vex[1] >> (7-2)) & REX_R; + prefix.vex_m = 1; + prefix.vex_v = (~prefix.vex[1] >> 3) & 15; + prefix.vex_lp = prefix.vex[1] & 7; + } - ix = itable_VEX[prefix.vex_m][prefix.vex_lp]; + ix = itable_VEX[prefix.vex_m][prefix.vex_lp]; + } end_prefix = true; break; |