libipt, ild: fix LDS/LES decode
For VEX decode, we considered the VEX prefix byte instead of the next byte when
distinguishing between VEX and LDS/LES in non-64-bit mode. Fix it.
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
diff --git a/libipt/src/pt_ild.c b/libipt/src/pt_ild.c
index e3ef595..556865e 100644
--- a/libipt/src/pt_ild.c
+++ b/libipt/src/pt_ild.c
@@ -389,7 +389,7 @@
}
else if (length + 1 < max_bytes)
{ /* non64b mode */
- pti_uint8_t n = get_byte (ild, length);
+ pti_uint8_t n = get_byte (ild, length + 1);
if (bits_match (n, 0xC0, 0xC0))
{
ild->u.s.vexc5 = 1;
@@ -437,7 +437,7 @@
}
else if (length + 1 < max_bytes)
{ /* non64b mode */
- pti_uint8_t n = get_byte (ild, length);
+ pti_uint8_t n = get_byte (ild, length + 1);
if (bits_match (n, 0xC0, 0xC0))
{
ild->u.s.vexc4 = 1;
diff --git a/libipt/test/src/ptunit-ild.c b/libipt/test/src/ptunit-ild.c
index fcc77bc..d54d88c 100644
--- a/libipt/test/src/ptunit-ild.c
+++ b/libipt/test/src/ptunit-ild.c
@@ -510,6 +510,118 @@
return ptu_passed();
}
+static struct ptunit_result les(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result les_disp16(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x06, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result les_disp32(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x05, 0x00, 0x00, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result les_ind_disp8(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x40, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result les_ind_disp16(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x80, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result les_ind_disp32(void)
+{
+ pti_uint8_t insn[] = { 0xc4, 0x80, 0x00, 0x00, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds_disp16(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x06, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds_disp32(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x05, 0x00, 0x00, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds_ind_disp8(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x40, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds_ind_disp16(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x80, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_16);
+
+ return ptu_passed();
+}
+
+static struct ptunit_result lds_ind_disp32(void)
+{
+ pti_uint8_t insn[] = { 0xc5, 0x80, 0x00, 0x00, 0x00, 0x00 };
+
+ ptu_boring_s(insn, PTI_MODE_32);
+
+ return ptu_passed();
+}
+
int main(int argc, char **argv)
{
struct ptunit_suite suite;
@@ -559,6 +671,18 @@
ptu_run(suite, mov_eax_moffs32);
ptu_run(suite, mov_ax_moffs32);
ptu_run(suite, mov_ax_moffs16);
+ ptu_run(suite, les);
+ ptu_run(suite, les_disp16);
+ ptu_run(suite, les_disp32);
+ ptu_run(suite, les_ind_disp8);
+ ptu_run(suite, les_ind_disp16);
+ ptu_run(suite, les_ind_disp32);
+ ptu_run(suite, lds);
+ ptu_run(suite, lds_disp16);
+ ptu_run(suite, lds_disp32);
+ ptu_run(suite, lds_ind_disp8);
+ ptu_run(suite, lds_ind_disp16);
+ ptu_run(suite, lds_ind_disp32);
ptunit_report(&suite);
return suite.nr_fails;