diff options
Diffstat (limited to 'src/intel')
-rw-r--r-- | src/intel/common/gen_decoder.c | 41 |
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; } |