summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2017-08-03 14:50:35 +0100
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>2017-11-01 13:19:20 +0000
commit68e1853ea3a6feabf14cbe42e8e003647fdc82f3 (patch)
tree1c17d010671fa5fae0df9aed93945a0799dfa6a8
parentf5e5ca1e210c2e0f505ea154ca553275157dda73 (diff)
intel: decoder: don't read qword outside instruction/struct limit
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>
-rw-r--r--src/intel/common/gen_decoder.c11
-rw-r--r--src/intel/common/gen_decoder.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index ac7c94f41e..d2190cb8b1 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -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);
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h
index b8666ca304..88375c8223 100644
--- a/src/intel/common/gen_decoder.h
+++ b/src/intel/common/gen_decoder.h
@@ -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 */