Sanity check that we're not getting out of sync with the trace stream. This will be especially bad with the change in size of the sve save data.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- risu.h | 6 +++++- reginfo.c | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/risu.h b/risu.h index e2b4508..3fc198f 100644 --- a/risu.h +++ b/risu.h @@ -62,10 +62,14 @@ extern void *memblock; struct reginfo; typedef struct { - uintptr_t pc; + uint32_t magic; + uint32_t size; uint32_t risu_op; + uintptr_t pc; } trace_header_t; +#define RISU_MAGIC (('R' << 24) | ('i' << 16) | ('S' << 8) | 'u') + /* Functions operating on reginfo */ /* Function prototypes for read/write helper functions. diff --git a/reginfo.c b/reginfo.c index 1b2a821..a4f7da6 100644 --- a/reginfo.c +++ b/reginfo.c @@ -26,20 +26,45 @@ int send_register_info(write_fn write_fn, void *uc) struct reginfo ri; trace_header_t header; int op; + void *extra; reginfo_init(&ri, uc); op = get_risuop(&ri); /* Write a header with PC/op to keep in sync */ + header.magic = RISU_MAGIC; header.pc = get_pc(&ri); header.risu_op = op; + + switch (op) { + case OP_TESTEND: + case OP_COMPARE: + default: + header.size = reginfo_size(); + extra = &ri; + break; + + case OP_SETMEMBLOCK: + case OP_GETMEMBLOCK: + header.size = 0; + extra = NULL; + break; + + case OP_COMPAREMEM: + header.size = MEMBLOCKLEN; + extra = memblock; + break; + } + if (write_fn(&header, sizeof(header)) != 0) { return -1; } + if (extra && write_fn(extra, header.size) != 0) { + return -1; + } switch (op) { case OP_TESTEND: - write_fn(&ri, reginfo_size()); /* if we are tracing write_fn will return 0 unlike a remote end, hence we force return of 1 here */ return 1; @@ -51,14 +76,9 @@ int send_register_info(write_fn write_fn, void *uc) get_reginfo_paramreg(&ri) + (uintptr_t)memblock); break; case OP_COMPAREMEM: - return write_fn(memblock, MEMBLOCKLEN); - break; case OP_COMPARE: default: - /* Do a simple register compare on (a) explicit request - * (b) end of test (c) a non-risuop UNDEF - */ - return write_fn(&ri, reginfo_size()); + break; } return 0; } @@ -84,7 +104,7 @@ int recv_and_compare_register_info(read_fn read_fn, return -1; } - if (header.risu_op != op) { + if (header.magic != RISU_MAGIC || header.risu_op != op) { /* We are out of sync */ resp = 2; resp_fn(resp); @@ -101,7 +121,8 @@ int recv_and_compare_register_info(read_fn read_fn, /* Do a simple register compare on (a) explicit request * (b) end of test (c) a non-risuop UNDEF */ - if (read_fn(&apprentice_ri, reginfo_size())) { + if (header.size != reginfo_size() || + read_fn(&apprentice_ri, header.size)) { packet_mismatch = 1; resp = 2; } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) { @@ -121,7 +142,8 @@ int recv_and_compare_register_info(read_fn read_fn, break; case OP_COMPAREMEM: mem_used = 1; - if (read_fn(apprentice_memblock, MEMBLOCKLEN)) { + if (header.size != MEMBLOCKLEN || + read_fn(apprentice_memblock, MEMBLOCKLEN)) { packet_mismatch = 1; resp = 2; } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) { -- 2.20.1