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;