From e7e40cedbb0508aa788e509075b9ba50c3af07ba Mon Sep 17 00:00:00 2001
From: Luis Machado <luis.machado@linaro.org>
Date: Mon, 10 May 2021 16:06:50 -0300
Subject: [PATCH] Fix build failure in d10v sim

While building all targets on Ubuntu 20.04/aarch64, I ran into the following
build error:

In file included from /usr/include/string.h:495,
                 from ../../bfd/bfd.h:48,
                 from ../../../../repos/binutils-gdb/sim/d10v/interp.c:4:
In function memset,
    inlined from sim_create_inferior at ../../../../repos/binutils-gdb/sim/d10v/interp.c:1146:3:
/usr/include/aarch64-linux-gnu/bits/string_fortified.h:71:10: error: __builtin_memset offset [33, 616] from the object at State is out of the bounds of referenced subobject regs with type reg_t[16] {aka short unsigned int[16]} at offset 0 [-Werror=array-bounds]
   71 |   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[3]: *** [Makefile:558: interp.o] Error 1

The following patch fixes this.

sim/ChangeLog:

2021-05-12  Luis Machado  <luis.machado@linaro.org>

	* d10v/interp.c (sim_create_inferior): Fix memset call.
---
 sim/ChangeLog     | 4 ++++
 sim/d10v/interp.c | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sim/ChangeLog b/sim/ChangeLog
index 469e768aee0..96588c7a780 100644
--- a/sim/ChangeLog
+++ b/sim/ChangeLog
@@ -1,3 +1,7 @@
+2021-05-12  Luis Machado  <luis.machado@linaro.org>
+
+	* d10v/interp.c (sim_create_inferior): Fix memset call.
+
 2021-05-07  Dimitar Dimitrov  <dimitar@dinux.eu>
 
 	* Makefile.in: Rebuild.
diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c
index 86e566a79fb..62507760af9 100644
--- a/sim/d10v/interp.c
+++ b/sim/d10v/interp.c
@@ -13,6 +13,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <assert.h>
 
 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
 
@@ -1142,8 +1143,12 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
 {
   bfd_vma start_address;
 
-  /* reset all state information */
-  memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs);
+  /* Make sure we have the right structure for the following memset.  */
+  static_assert ((uintptr_t) &State == (uintptr_t) &State.regs,
+		 "&State != &State.regs");
+
+  /* Reset state from the regs field until the mem field.  */
+  memset (&State, 0, (uintptr_t) &State.mem - (uintptr_t) &State.regs);
 
   /* There was a hack here to copy the values of argc and argv into r0
      and r1.  The values were also saved into some high memory that