summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/common/gen_decoder.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 7ca71c0d9fc..595fa29e43d 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -847,35 +847,38 @@ iter_advance_field(struct gen_field_iterator *iter)
return true;
}
-static uint64_t
-iter_decode_field_raw(struct gen_field_iterator *iter)
+static bool
+iter_decode_field_raw(struct gen_field_iterator *iter, uint64_t *qw)
{
- uint64_t qw = 0;
+ *qw = 0;
int field_start = iter->p_bit + iter->bit;
int field_end = field_start + (iter->field->end - iter->field->start);
const uint32_t *p = iter->p + (iter->bit / 32);
+ if (iter->p_end && p >= iter->p_end)
+ return false;
+
if ((field_end - field_start) > 32) {
- if ((p + 1) < iter->p_end)
- qw = ((uint64_t) p[1]) << 32;
- qw |= p[0];
+ if (!iter->p_end || (p + 1) < iter->p_end)
+ *qw = ((uint64_t) p[1]) << 32;
+ *qw |= p[0];
} else
- qw = p[0];
+ *qw = p[0];
- qw = field_value(qw, field_start, field_end);
+ *qw = field_value(*qw, field_start, field_end);
/* Address & offset types have to be aligned to dwords, their start bit is
* a reminder of the alignment requirement.
*/
if (iter->field->type.kind == GEN_TYPE_ADDRESS ||
iter->field->type.kind == GEN_TYPE_OFFSET)
- qw <<= field_start % 32;
+ *qw <<= field_start % 32;
- return qw;
+ return true;
}
-static void
+static bool
iter_decode_field(struct gen_field_iterator *iter)
{
union {
@@ -890,7 +893,8 @@ iter_decode_field(struct gen_field_iterator *iter)
memset(&v, 0, sizeof(v));
- iter->raw_value = iter_decode_field_raw(iter);
+ if (!iter_decode_field_raw(iter, &iter->raw_value))
+ return false;
const char *enum_name = NULL;
@@ -963,6 +967,8 @@ iter_decode_field(struct gen_field_iterator *iter)
" (%s)", fmt_name);
}
}
+
+ return true;
}
void
@@ -980,10 +986,14 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
iter->field = group->next->fields;
iter->p = p;
iter->p_bit = p_bit;
- iter->p_end = &p[gen_group_get_length(iter->group, iter->p)];
+
+ int length = gen_group_get_length(iter->group, iter->p);
+ iter->p_end = length > 0 ? &p[length] : NULL;
iter->print_colors = print_colors;
- iter_decode_field(iter);
+ bool result = iter_decode_field(iter);
+ if (length >= 0)
+ assert(result);
}
bool
@@ -992,7 +1002,8 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
if (!iter_advance_field(iter))
return false;
- iter_decode_field(iter);
+ if (!iter_decode_field(iter))
+ return false;
return true;
}