[RISU,6/9] Add magic and size to the trace header

Message ID 20200513180953.20376-7-richard.henderson@linaro.org
State New
Headers show
Series
  • risu cleanups and improvements
Related show

Commit Message

Richard Henderson May 13, 2020, 6:09 p.m.
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.henderson@linaro.org>

---
 risu.h    |  6 +++++-
 reginfo.c | 42 ++++++++++++++++++++++++++++++++----------
 2 files changed, 37 insertions(+), 11 deletions(-)

-- 
2.20.1

Patch

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) {