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

Richard Henderson posted 9 patches 5 years, 9 months ago
There is a newer version of this series
[RISU 6/9] Add magic and size to the trace header
Posted by Richard Henderson 5 years, 9 months ago
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(-)

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