mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 22:30:12 +01:00
freedreno/decode: try harder to not crash in disasm
Move the handling for catching asserts when we start decoding garbage into disasm-a3xx. This way it can also cover other cases where cffdec tries to disassemble memory, such as SP_xS_OBJ_START. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6242>
This commit is contained in:
parent
cbfce486f2
commit
3d6e4a201a
4 changed files with 43 additions and 38 deletions
|
|
@ -54,6 +54,7 @@ int disasm_a2xx(uint32_t *dwords, int sizedwords, int level, gl_shader_stage typ
|
||||||
int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id);
|
int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id);
|
||||||
int disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
|
int disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
|
||||||
unsigned gpu_id, struct shader_stats *stats);
|
unsigned gpu_id, struct shader_stats *stats);
|
||||||
|
int try_disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id);
|
||||||
|
|
||||||
void disasm_a2xx_set_debug(enum debug_t debug);
|
void disasm_a2xx_set_debug(enum debug_t debug);
|
||||||
void disasm_a3xx_set_debug(enum debug_t debug);
|
void disasm_a3xx_set_debug(enum debug_t debug);
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ disasm_gpuaddr(const char *name, uint64_t gpuaddr, int level)
|
||||||
const char *ext;
|
const char *ext;
|
||||||
|
|
||||||
dump_hex(buf, min(64, sizedwords), level+1);
|
dump_hex(buf, min(64, sizedwords), level+1);
|
||||||
disasm_a3xx(buf, sizedwords, level+2, stdout, options->gpu_id);
|
try_disasm_a3xx(buf, sizedwords, level+2, stdout, options->gpu_id);
|
||||||
|
|
||||||
/* this is a bit ugly way, but oh well.. */
|
/* this is a bit ugly way, but oh well.. */
|
||||||
if (strstr(name, "SP_VS_OBJ")) {
|
if (strstr(name, "SP_VS_OBJ")) {
|
||||||
|
|
@ -1491,7 +1491,7 @@ cp_load_state(uint32_t *dwords, uint32_t sizedwords, int level)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contents)
|
if (contents)
|
||||||
disasm_a3xx(contents, num_unit * 2, level+2, stdout, options->gpu_id);
|
try_disasm_a3xx(contents, num_unit * 2, level+2, stdout, options->gpu_id);
|
||||||
|
|
||||||
/* dump raw shader: */
|
/* dump raw shader: */
|
||||||
if (ext)
|
if (ext)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -231,34 +230,6 @@ parseline(const char *line, const char *fmt, ...)
|
||||||
break; \
|
break; \
|
||||||
} else
|
} else
|
||||||
|
|
||||||
/*
|
|
||||||
* Provide our own disasm assert() handler, so that we can recover
|
|
||||||
* after attempting to disassemble things that might not be valid
|
|
||||||
* instructions:
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool jmp_env_valid;
|
|
||||||
static jmp_buf jmp_env;
|
|
||||||
|
|
||||||
void
|
|
||||||
ir3_assert_handler(const char *expr, const char *file, int line,
|
|
||||||
const char *func)
|
|
||||||
{
|
|
||||||
printf("\n%s:%u: %s: Assertion `%s' failed.\n", file, line, func, expr);
|
|
||||||
if (jmp_env_valid)
|
|
||||||
longjmp(jmp_env, 1);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TRY(x) do { \
|
|
||||||
assert(!jmp_env_valid); \
|
|
||||||
if (setjmp(jmp_env) == 0) { \
|
|
||||||
jmp_env_valid = true; \
|
|
||||||
x; \
|
|
||||||
} \
|
|
||||||
jmp_env_valid = false; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode ringbuffer section:
|
* Decode ringbuffer section:
|
||||||
*/
|
*/
|
||||||
|
|
@ -930,7 +901,7 @@ decode_shader_blocks(void)
|
||||||
* (or parts of shaders?), so perhaps we should search
|
* (or parts of shaders?), so perhaps we should search
|
||||||
* for ends of shaders and decode each?
|
* for ends of shaders and decode each?
|
||||||
*/
|
*/
|
||||||
TRY(disasm_a3xx(buf, sizedwords, 1, stdout, options.gpu_id));
|
try_disasm_a3xx(buf, sizedwords, 1, stdout, options.gpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump)
|
if (dump)
|
||||||
|
|
|
||||||
|
|
@ -1635,12 +1635,6 @@ static bool print_instr(struct disasm_ctx *ctx, uint32_t *dwords, int n)
|
||||||
((opc == OPC_END) || (opc == OPC_CHSH));
|
((opc == OPC_END) || (opc == OPC_CHSH));
|
||||||
}
|
}
|
||||||
|
|
||||||
int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
|
|
||||||
{
|
|
||||||
struct shader_stats stats;
|
|
||||||
return disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
int disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
|
int disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
|
||||||
unsigned gpu_id, struct shader_stats *stats)
|
unsigned gpu_id, struct shader_stats *stats)
|
||||||
{
|
{
|
||||||
|
|
@ -1680,3 +1674,42 @@ void disasm_a3xx_set_debug(enum debug_t d)
|
||||||
{
|
{
|
||||||
debug = d;
|
debug = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
static bool jmp_env_valid;
|
||||||
|
static jmp_buf jmp_env;
|
||||||
|
|
||||||
|
void
|
||||||
|
ir3_assert_handler(const char *expr, const char *file, int line,
|
||||||
|
const char *func)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "\n%s:%u: %s: Assertion `%s' failed.\n", file, line, func, expr);
|
||||||
|
if (jmp_env_valid)
|
||||||
|
longjmp(jmp_env, 1);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TRY(x) do { \
|
||||||
|
assert(!jmp_env_valid); \
|
||||||
|
if (setjmp(jmp_env) == 0) { \
|
||||||
|
jmp_env_valid = true; \
|
||||||
|
x; \
|
||||||
|
} \
|
||||||
|
jmp_env_valid = false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
|
||||||
|
{
|
||||||
|
struct shader_stats stats;
|
||||||
|
return disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
int try_disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
|
||||||
|
{
|
||||||
|
struct shader_stats stats;
|
||||||
|
int ret;
|
||||||
|
TRY(ret = disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue