Modify RISCV minidump context to match Crashpad

- RISCV32 will only include support for 32 bit floating point registers
- RISCV64 will only include support for 64 bit floating point registers
- RISCV 32/64 context will include a "version" field to account for
  future extensions

Fixed: 1447862

Tested: `make check` on x86 host
Tested: `minidump_stackwalk` for RISCV64 minidump on x86 host
Change-Id: I605d5b2c35e627a5dc986aaf818a9c9898f6ae0b
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4553281
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
diff --git a/src/client/linux/dump_writer_common/thread_info.cc b/src/client/linux/dump_writer_common/thread_info.cc
index fc82c0c..6288a05 100644
--- a/src/client/linux/dump_writer_common/thread_info.cc
+++ b/src/client/linux/dump_writer_common/thread_info.cc
@@ -322,23 +322,19 @@
   out->t5  = mcontext.__gregs[30];
   out->t6  = mcontext.__gregs[31];
 
-# if __riscv_flen == 32
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++)
-    out->float_save.regs[i] = mcontext.__fpregs.__f.__f[i];
-  out->float_save.fpcsr = mcontext.__fpregs.__f.__fcsr;
-# elif __riscv_flen == 64
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++)
-    out->float_save.regs[i] = mcontext.__fpregs.__d.__f[i];
-  out->float_save.fpcsr = mcontext.__fpregs.__d.__fcsr;
-# elif __riscv_flen == 128
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++) {
-    out->float_save.regs[i].high = mcontext.__fpregs.__q.__f[2*i];
-    out->float_save.regs[i].low  = mcontext.__fpregs.__q.__f[2*i+1];
-  }
-  out->float_save.fpcsr = mcontext.__fpregs.__q.__fcsr;
-# else
-#  error "Unexpected __riscv_flen"
-# endif
+  // Breakpad only supports RISCV32 with 32 bit floating point.
+  // Breakpad only supports RISCV64 with 64 bit floating point.
+#if __riscv_xlen == 32
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; i++)
+    out->fpregs[i] = mcontext.__fpregs.__f.__f[i];
+  out->fcsr = mcontext.__fpregs.__f.__fcsr;
+#elif __riscv_xlen == 64
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; i++)
+    out->fpregs[i] = mcontext.__fpregs.__d.__f[i];
+  out->fcsr = mcontext.__fpregs.__d.__fcsr;
+#else
+#error "Unexpected __riscv_xlen"
+#endif
 }
 #endif  // __riscv
 
diff --git a/src/client/linux/dump_writer_common/ucontext_reader.cc b/src/client/linux/dump_writer_common/ucontext_reader.cc
index c6a8e9a..7649768 100644
--- a/src/client/linux/dump_writer_common/ucontext_reader.cc
+++ b/src/client/linux/dump_writer_common/ucontext_reader.cc
@@ -310,21 +310,19 @@
   out->t5  = uc->uc_mcontext.__gregs[30];
   out->t6  = uc->uc_mcontext.__gregs[31];
 
-# if __riscv_flen == 32
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++)
-    out->float_save.regs[i] = uc->uc_mcontext.__fpregs.__f.__f[i];
-  out->float_save.fpcsr = uc->uc_mcontext.__fpregs.__f.__fcsr;
-# elif __riscv_flen == 64
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++)
-    out->float_save.regs[i] = uc->uc_mcontext.__fpregs.__d.__f[i];
-  out->float_save.fpcsr = uc->uc_mcontext.__fpregs.__d.__fcsr;
-# elif __riscv_flen == 128
-  for(int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; i++) {
-    out->float_save.regs[i].high = uc->uc_mcontext.__fpregs.__q.__f[2*i];
-    out->float_save.regs[i].low  = uc->uc_mcontext.__fpregs.__q.__f[2*i+1];
-  }
-  out->float_save.fpcsr = uc->uc_mcontext.__fpregs.__q.__fcsr;
-# endif
+  // Breakpad only supports RISCV32 with 32 bit floating point.
+  // Breakpad only supports RISCV64 with 64 bit floating point.
+#if __riscv_xlen == 32
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; i++)
+    out->fpregs[i] = uc->uc_mcontext.__fpregs.__f.__f[i];
+  out->fcsr = uc->uc_mcontext.__fpregs.__f.__fcsr;
+#elif __riscv_xlen == 64
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; i++)
+    out->fpregs[i] = uc->uc_mcontext.__fpregs.__d.__f[i];
+  out->fcsr = uc->uc_mcontext.__fpregs.__d.__fcsr;
+#else
+#error "Unexpected __riscv_xlen"
+#endif
 }
 #endif
 
diff --git a/src/google_breakpad/common/minidump_cpu_riscv.h b/src/google_breakpad/common/minidump_cpu_riscv.h
index 94d0611..812cf5f 100644
--- a/src/google_breakpad/common/minidump_cpu_riscv.h
+++ b/src/google_breakpad/common/minidump_cpu_riscv.h
@@ -39,28 +39,8 @@
 
 #include "google_breakpad/common/breakpad_types.h"
 
-#define MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT 32
-#if defined(__riscv)
-# if __riscv_flen == 32
-typedef uint32_t riscv_fpr_size;
-# elif __riscv_flen == 64
-typedef uint64_t riscv_fpr_size;
-# elif __riscv_flen == 128
-typedef uint128_struct riscv_fpr_size;
-# else
-#  error "Unexpected __riscv_flen"
-# endif
-#else
-typedef uint32_t riscv_fpr_size;
-#endif
-
 #define MD_CONTEXT_RISCV_GPR_COUNT 32
-
-typedef struct {
-    /* 32 floating point registers, f0 .. f31. */
-    riscv_fpr_size regs[MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT];
-    uint32_t fpcsr;
-} MDFloatingSaveAreaRISCV;
+#define MD_CONTEXT_RISCV_FPR_COUNT 32
 
 enum MDRISCVRegisterNumbers {
   MD_CONTEXT_RISCV_REG_PC     = 0,
@@ -72,13 +52,14 @@
  * context stored in the structure. */
 #define MD_CONTEXT_RISCV 0x00800000
 #define MD_CONTEXT_RISCV_INTEGER (MD_CONTEXT_RISCV | 0x00000001)
-#define MD_CONTEXT_RISCV_FLOATING_POINT (MD_CONTEXT_RISCV | 0x00000004)
+#define MD_CONTEXT_RISCV_FLOATING_POINT (MD_CONTEXT_RISCV | 0x00000002)
 #define MD_CONTEXT_RISCV_FULL (MD_CONTEXT_RISCV_INTEGER | \
                                MD_CONTEXT_RISCV_FLOATING_POINT)
 
 typedef struct {
   /* Determines which fields of this struct are populated */
   uint32_t context_flags;
+  uint32_t version;
 
   uint32_t pc;
   uint32_t ra;
@@ -113,20 +94,24 @@
   uint32_t t5;
   uint32_t t6;
 
-  MDFloatingSaveAreaRISCV float_save;
+  /* 32 floating point registers, f0 .. f31. Breakpad only supports RISCV32
+   * with 32 bit floating point. */
+  uint32_t fpregs[MD_CONTEXT_RISCV_FPR_COUNT];
+  uint32_t fcsr;
 } MDRawContextRISCV;
 
 /* For (MDRawContextRISCV64).context_flags.  These values indicate the type of
  * context stored in the structure. */
 #define MD_CONTEXT_RISCV64 0x08000000
 #define MD_CONTEXT_RISCV64_INTEGER (MD_CONTEXT_RISCV64 | 0x00000001)
-#define MD_CONTEXT_RISCV64_FLOATING_POINT (MD_CONTEXT_RISCV64 | 0x00000004)
+#define MD_CONTEXT_RISCV64_FLOATING_POINT (MD_CONTEXT_RISCV64 | 0x00000002)
 #define MD_CONTEXT_RISCV64_FULL (MD_CONTEXT_RISCV64_INTEGER | \
                                  MD_CONTEXT_RISCV64_FLOATING_POINT)
 
 typedef struct {
   /* Determines which fields of this struct are populated */
   uint32_t context_flags;
+  uint32_t version;
 
   uint64_t pc;
   uint64_t ra;
@@ -161,7 +146,10 @@
   uint64_t t5;
   uint64_t t6;
 
-  MDFloatingSaveAreaRISCV float_save;
+  /* 32 floating point registers, f0 .. f31. Breakpad only supports RISCV64 with
+   * 64 bit floating point. */
+  uint64_t fpregs[MD_CONTEXT_RISCV_FPR_COUNT];
+  uint32_t fcsr;
 } MDRawContextRISCV64;
 
 
diff --git a/src/processor/dump_context.cc b/src/processor/dump_context.cc
index 93d826c..ab97930 100644
--- a/src/processor/dump_context.cc
+++ b/src/processor/dump_context.cc
@@ -776,24 +776,14 @@
              context_riscv->t6);
 
 #if defined(__riscv)
-      for (unsigned int freg_index = 0;
-           freg_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++freg_index) {
-        riscv_fpr_size fp_value = context_riscv->float_save.regs[freg_index];
-# if __riscv_flen == 32
-        printf("  float_save.regs[%2d]            = 0x%" PRIx32 "\n",
-               freg_index, fp_value);
-# elif __riscv_flen == 64
-        printf("  float_save.regs[%2d]            = 0x%" PRIx64 "\n",
-               freg_index, fp_value);
-# elif __riscv_flen == 128
-        printf("  float_save.regs[%2d]            = 0x%" PRIx64 "%" PRIx64 "\n",
-               freg_index, fp_value.high, fp_value.low);
-# else
-#  error "Unexpected __riscv_flen"
-# endif
+      for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT;
+           ++freg_index) {
+        // Breakpad only supports RISCV32 with 32 bit floating point.
+        uint32_t fp_value = context_riscv->fpregs[freg_index];
+        printf("  fpregs[%2d]            = 0x%" PRIx32 "\n", freg_index,
+               fp_value);
       }
-      printf("  float_save.fpcsr     = 0x%" PRIx32 "\n",
-             context_riscv->float_save.fpcsr);
+      printf("  fcsr     = 0x%" PRIx32 "\n", context_riscv->fcsr);
 #endif
       break;
     }
@@ -870,25 +860,14 @@
              context_riscv64->t6);
 
 #if defined(__riscv)
-      for (unsigned int freg_index = 0;
-           freg_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++freg_index) {
-        riscv_fpr_size fp_value = context_riscv64->float_save.regs[freg_index];
-# if __riscv_flen == 32
-        printf("  float_save.regs[%2d]            = 0x%" PRIx32 "\n",
-               freg_index, fp_value);
-# elif __riscv_flen == 64
-        printf("  float_save.regs[%2d]            = 0x%" PRIx64 "\n",
-               freg_index, fp_value);
-# elif __riscv_flen == 128
-        printf("  float_save.regs[%2d]            = 0x%"
-               PRIx64 "%" PRIx64 "\n",
-               freg_index, fp_value.high, fp_value.low);
-# else
-#  error "Unexpected __riscv_flen"
-# endif
+      for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT;
+           ++freg_index) {
+        // Breakpad only supports RISCV64 with 64 bit floating point.
+        uint64_t fp_value = context_riscv64->fpregs[freg_index];
+        printf("  fpregs[%2d]            = 0x%" PRIx64 "\n", freg_index,
+               fp_value);
       }
-      printf("  float_save.fpcsr     = 0x%" PRIx32 "\n",
-             context_riscv64->float_save.fpcsr);
+      printf("  fcsr     = 0x%" PRIx32 "\n", context_riscv64->fcsr);
 #endif
       break;
     }
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 45e4a52..f0f9253 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -1259,12 +1259,11 @@
           Swap(&context_riscv->t5);
           Swap(&context_riscv->t6);
 
-          for (int fpr_index = 0;
-               fpr_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT;
+          for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT;
                ++fpr_index) {
-            Swap(&context_riscv->float_save.regs[fpr_index]);
+            Swap(&context_riscv->fpregs[fpr_index]);
           }
-          Swap(&context_riscv->float_save.fpcsr);
+          Swap(&context_riscv->fcsr);
         }
         SetContextRISCV(context_riscv.release());
 
@@ -1338,12 +1337,11 @@
           Swap(&context_riscv64->t5);
           Swap(&context_riscv64->t6);
 
-          for (int fpr_index = 0;
-               fpr_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT;
+          for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT;
                ++fpr_index) {
-            Swap(&context_riscv64->float_save.regs[fpr_index]);
+            Swap(&context_riscv64->fpregs[fpr_index]);
           }
-          Swap(&context_riscv64->float_save.fpcsr);
+          Swap(&context_riscv64->fcsr);
         }
         SetContextRISCV64(context_riscv64.release());
 
diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc
index 9d5e5e3..3e310bc 100644
--- a/src/tools/linux/md2core/minidump-2-core.cc
+++ b/src/tools/linux/md2core/minidump-2-core.cc
@@ -583,25 +583,21 @@
   thread->mcontext.__gregs[30] = rawregs->t5;
   thread->mcontext.__gregs[31] = rawregs->t6;
 
-# if __riscv_flen == 32
-  for (int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++i) {
-    thread->mcontext.__fpregs.__f.__f[i] = rawregs->float_save.regs[i];
+  // Breakpad only supports RISCV32 with 32 bit floating point.
+  // Breakpad only supports RISCV64 with 64 bit floating point.
+#if __riscv_xlen == 32
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; ++i) {
+    thread->mcontext.__fpregs.__f.__f[i] = rawregs->fpregs[i];
   }
-  thread->mcontext.__fpregs.__f.__fcsr = rawregs->float_save.fpcsr;
-# elif __riscv_flen == 64
-  for (int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++i) {
-    thread->mcontext.__fpregs.__d.__f[i] = rawregs->float_save.regs[i];
+  thread->mcontext.__fpregs.__f.__fcsr = rawregs->fcsr;
+#elif __riscv_xlen == 64
+  for (int i = 0; i < MD_CONTEXT_RISCV_FPR_COUNT; ++i) {
+    thread->mcontext.__fpregs.__d.__f[i] = rawregs->fpregs[i];
   }
-  thread->mcontext.__fpregs.__d.__fcsr = rawregs->float_save.fpcsr;
-# elif __riscv_flen == 128
-  for (int i = 0; i < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++i) {
-    thread->mcontext.__fpregs.__q.__f[2*i] = rawregs->float_save.regs[i].high;
-    thread->mcontext.__fpregs.__q.__f[2*i+1] = rawregs->float_save.regs[i].low;
-  }
-  thread->mcontext.__fpregs.__q.__fcsr = rawregs->float_save.fpcsr;
-# else
-#  error "Unexpected __riscv_flen"
-# endif
+  thread->mcontext.__fpregs.__d.__fcsr = rawregs->fcsr;
+#else
+#error "Unexpected __riscv_xlen"
+#endif
 }
 #else
 #error "This code has not been ported to your platform yet"