summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Kennard <glenn.kennard@gmail.com>2015-08-27 19:04:16 +0200
committerEmil Velikov <emil.l.velikov@gmail.com>2015-09-02 21:06:36 +0100
commit6f92f4dea9a1ff6879f38348ff377d4445e1ef0d (patch)
treeb04e3dc6c0604172ccd420f475183cce4893013c
parent1a9310b8b12a63eccc57a245a0c0db46b81f028e (diff)
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> (cherry picked from commit a830225adbb77073272961df409885cca6b861ee)
-rw-r--r--src/gallium/drivers/r600/r600_asm.c2
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_decoder.cpp1
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_parser.cpp4
3 files changed, 6 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 762cc7fac44..b514c58f9d8 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -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");
}
}
diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
index 5e233f982ea..5fe8f50aa4c 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp
@@ -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);
diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
index 4879c036f9f..748aae29eeb 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -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(