intel: decoder: don't read qword outside instruction/struct limit
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Thu, 3 Aug 2017 13:50:35 +0000 (14:50 +0100)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 1 Nov 2017 13:19:20 +0000 (13:19 +0000)
We used to print invalid data when the last field was being clamped to
32bits due to Dword Length of the whole instruction. Here is an
example where the decoder read part of the next instruction instead of
stopping at the 32bit limit:

0x000ce0b4:  0x10000002:  MI_STORE_DATA_IMM
0x000ce0b4:  0x10000002 : Dword 0
    DWord Length: 2
    Store Qword: 0
    Use Global GTT: false
0x000ce0b8:  0x00045010 : Dword 1
    Core Mode Enable: 0
    Address: 0x00045010
0x000ce0bc:  0x00000000 : Dword 2
0x000ce0c0:  0x00000000 : Dword 3
    Immediate Data: 8791026489807077376

With this change we have the proper value :

0x000ce0b4:  0x10000002:  MI_STORE_DATA_IMM (4 Dwords)
0x000ce0b4:  0x10000002 : Dword 0
    DWord Length: 2
    Store Qword: 0
    Use Global GTT: false
0x000ce0b8:  0x00045010 : Dword 1
    Core Mode Enable: 0
    Address: 0x00045010
0x000ce0bc:  0x00000000 : Dword 2
0x000ce0c0:  0x00000000 : Dword 3
    Immediate Data: 0

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Scott D Phillips <scott.d.phillips@intel.com>
src/intel/common/gen_decoder.c
src/intel/common/gen_decoder.h

index ac7c94f41e6fe1c745a60a42a2af866ae96c2ed1..d2190cb8b1f7559482f78c02355cc1413d2e4711 100644 (file)
@@ -850,9 +850,13 @@ gen_field_decode(struct gen_field_iterator *iter)
    else
       memset(iter->name, 0, sizeof(iter->name));
 
-   if ((iter->field->end - iter->field->start) > 32)
-      v.qw = ((uint64_t) iter->p[iter->dword+1] << 32) | iter->p[iter->dword];
-   else
+   memset(&v, 0, sizeof(v));
+
+   if ((iter->field->end - iter->field->start) > 32) {
+      if (&iter->p[iter->dword + 1] < iter->p_end)
+         v.qw = ((uint64_t) iter->p[iter->dword+1] << 32);
+      v.qw |= iter->p[iter->dword];
+   } else
       v.qw = iter->p[iter->dword];
 
    const char *enum_name = NULL;
@@ -941,6 +945,7 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
    else
       iter->field = group->next->fields;
    iter->p = p;
+   iter->p_end = &p[gen_group_get_length(iter->group, iter->p)];
    iter->print_colors = print_colors;
 
    gen_field_decode(iter);
index b8666ca3044c0bfed161ac46d27848002bb1cc67..88375c8223d7a0d2a483a495984f1603191fb7e9 100644 (file)
@@ -57,6 +57,7 @@ struct gen_field_iterator {
    char value[128];
    struct gen_group *struct_desc;
    const uint32_t *p;
+   const uint32_t *p_end;
    int dword; /**< current field starts at &p[dword] */
    int start; /**< current field starts at this bit number */
    int end;   /**< current field ends at this bit number */