r600g/sb: Don't read junk after EOP

Shaders that contain instruction data after an instruction with EOP could end
up parsing that as an instruction, leading to various crashes and asserts in
SB as it gets very confused if it sees for instance a loop start instruction
jumping off to some random point.

Add a couple of asserts, and print EOP bit if set in old asm printer.

Signed-off-by: Glenn Kennard <glenn.kennard@gmail.com>
Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Glenn Kennard 2015-08-27 19:04:16 +02:00 committed by Dave Airlie
parent 36f1999a87
commit a830225adb
3 changed files with 6 additions and 1 deletions

View file

@ -2029,6 +2029,8 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
fprintf(stderr, "CND:%X ", cf->cond);
if (cf->pop_count)
fprintf(stderr, "POP:%X ", cf->pop_count);
if (cf->end_of_program)
fprintf(stderr, "EOP ");
fprintf(stderr, "\n");
}
}

View file

@ -32,6 +32,7 @@ int bc_decoder::decode_cf(unsigned &i, bc_cf& bc) {
int r = 0;
uint32_t dw0 = dw[i];
uint32_t dw1 = dw[i+1];
assert(i+1 <= ndw);
if ((dw1 >> 29) & 1) { // CF_ALU
return decode_cf_alu(i, bc);

View file

@ -95,7 +95,7 @@ int bc_parser::decode_shader() {
if ((r = decode_cf(i, eop)))
return r;
} while (!eop || (i >> 1) <= max_cf);
} while (!eop || (i >> 1) < max_cf);
return 0;
}
@ -769,6 +769,7 @@ int bc_parser::prepare_ir() {
}
int bc_parser::prepare_loop(cf_node* c) {
assert(c->bc.addr-1 < cf_map.size());
cf_node *end = cf_map[c->bc.addr - 1];
assert(end->bc.op == CF_OP_LOOP_END);
@ -788,6 +789,7 @@ int bc_parser::prepare_loop(cf_node* c) {
}
int bc_parser::prepare_if(cf_node* c) {
assert(c->bc.addr-1 < cf_map.size());
cf_node *c_else = NULL, *end = cf_map[c->bc.addr];
BCP_DUMP(