public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Removal of uses of MAX_REGISTER_SIZE
@ 2017-01-24 10:31 Alan Hayward
  2017-01-27 11:49 ` Pedro Alves
  2017-01-27 12:11 ` Pedro Alves
  0 siblings, 2 replies; 28+ messages in thread
From: Alan Hayward @ 2017-01-24 10:31 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd

This patch replaces all current uses of MAX_REGISTER_SIZE with calls to
either register_size() when the register number is known, and
max_register_size() in all other cases.

It assumes that the patch "[PATCH 3/3] Calculate max register size" will be
approved, and follows the methods used in that series of 3 patches.

In a couple of cases I've moved variables outside a loop to prevent multiple
allocations.

Tested with "make check" on a build using enable-targets=all, and manually run
on x86 and aarch64.

Ok to commit?
Alan.

2017-01-24  Alan Hayward  <alan.hayward@arm.com>

	* aarch64-tdep.c (aarch64_store_return_value): Replace
	MAX_REGISTER_SIZE.
	(aarch64_pseudo_read_value): Likewise.
	(aarch64_pseudo_write): Likewise.
	* alpha-tdep.c (alpha_register_to_value): Likewise.
	(alpha_value_to_register): Likewise.
	* arm-tdep.c (arm_store_return_value): Likewise.
	* bfin-tdep.c (bfin_pseudo_register_read): Likewise.
	(bfin_pseudo_register_write): Likewise.
	* frame.c (frame_unwind_register_signed): Likewise.
	(frame_unwind_register_unsigned): Likewise.
	(get_frame_register_bytes): Likewise.
	(put_frame_register_bytes): Likewise.
	* frv-linux-tdep.c (frv_linux_supply_gregset): Likewise.
	* i386-tdep.c (i386_pseudo_register_read_into_value): Likewise.
	(i386_pseudo_register_write): Likewise.
	(i386_process_record): Likewise.
	* i387-tdep.c (i387_supply_xsave): Likewise.
	* ia64-tdep.c (ia64_register_to_value): Likewise.
	(ia64_value_to_register): Likewise.
	(examine_prologue): Likewise.
	(ia64_sigtramp_frame_prev_register): Likewise.
	(ia64_access_reg): Likewise.
	(ia64_access_rse_reg): Likewise.
	(ia64_libunwind_frame_prev_register): Likewise.
	(ia64_extract_return_value): Likewise.
	(ia64_store_return_value): Likewise.
	(ia64_push_dummy_call): Likewise.
	* m32r-tdep.c (m32r_push_dummy_call): Likewise.
	* m68k-linux-nat.c (fetch_register): Likewise.
	(store_register): Likewise.
	* gdb/mi/mi-main.c (register_changed_p): Likewise
	* mips-fbsd-tdep.c (mips_fbsd_supply_reg): Likewise.
	(mips_fbsd_collect_reg): Likewise.
	* mips-linux-tdep.c (supply_32bit_reg): Likewise.
	(mips_supply_gregset): Likewise.
	(mips_supply_fpregset): Likewise.
	(mips64_supply_gregset): Likewise.
	(mips64_fill_gregset): Likewise.
	(mips64_fill_fpregset): Likewise.
	* mips-tdep.c (mips_eabi_push_dummy_call): Likewise.
	(mips_o32_return_value): Likewise.
	(print_gp_register_row): Likewise.
	* mn10300-linux-tdep.c (am33_supply_gregset_method): Likewise.
	* mn10300-tdep.c (mn10300_extract_return_value): Likewise.
	(mn10300_push_dummy_call): Likewise.
	* ppc-linux-nat.c: Likewise.
	* ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call): Likewise.
	(get_decimal_float_return_value): Likewise.
	(do_ppc_sysv_return_value): Likewise.
	(ppc64_sysv_abi_push_integer): Likewise.
	(ppc64_sysv_abi_push_freg): Likewise.
	(ppc64_sysv_abi_return_value_base): Likewise.
	(ppc64_sysv_abi_return_value): Likewise.
	* record-full.c (record_full_exec_insn): Likewise.
	(record_full_core_open_1): Likewise.
	(record_full_core_fetch_registers): Likewise.
	(record_full_core_store_registers): Likewise.
	(init_record_full_core_ops): Likewise.
	* remote-sim.c (gdbsim_fetch_register): Likewise.
	(gdbsim_store_register): Likewise.
	* rs6000-aix-tdep.c (rs6000_push_dummy_call): Likewise.
	* rs6000-lynx178-tdep.c (rs6000_lynx178_push_dummy_call): Likewise.
	* rs6000-nat.c: Likewise.
	* rs6000-tdep.c (rs6000_register_to_value): Likewise.
	(rs6000_value_to_register): Likewise.
	* sh-tdep.c (sh_pseudo_register_read): Likewise.
	(sh_pseudo_register_write): Likewise.
	* sh64-tdep.c (sh64_pseudo_register_read): Likewise.
	(sh64_pseudo_register_write): Likewise.
	* sol-thread.c (sol_thread_store_registers): Likewise.
	* stack.c (frame_info): Likewise.
	* target.c (debug_print_register): Likewise.
	* xtensa-tdep.c (xtensa_register_write_masked): Likewise.
	(xtensa_register_read_masked): Likewise.
	(xtensa_pseudo_register_read): Likewise.
	(xtensa_pseudo_register_write): Likewise.


diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 801c03d5a0b5d205dc967cb0d53e299ea95eaa8f..a317c8f2bb192fc25689c84375b8c7bb327dd596 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1982,7 +1982,8 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
       for (i = 0; i < elements; i++)
 	{
 	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte tmpbuf[MAX_REGISTER_SIZE];
+	  bfd_byte *tmpbuf = (bfd_byte *) alloca (register_size (gdbarch,
+								 regno));

 	  if (aarch64_debug)
 	    {
@@ -2236,7 +2237,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
 			   struct regcache *regcache,
 			   int regnum)
 {
-  gdb_byte reg_buf[MAX_REGISTER_SIZE];
+  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   struct value *result_value;
   gdb_byte *buf;

@@ -2331,13 +2332,13 @@ static void
 aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 		      int regnum, const gdb_byte *buf)
 {
-  gdb_byte reg_buf[MAX_REGISTER_SIZE];
+  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Ensure the register buffer is zero, we want gdb writes of the
      various 'scalar' pseudo registers to behavior like architectural
      writes, register width bytes are written the remainder are set to
      zero.  */
-  memset (reg_buf, 0, sizeof (reg_buf));
+  memset (reg_buf, 0, sizeof (register_size (gdbarch, regnum)));

   regnum -= gdbarch_num_regs (gdbarch);

diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 4dd65c58cc2896ea6038399128e3eb376d1ee672..5d850db07da0d5f6d47795da970add58161d722c 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -244,7 +244,7 @@ alpha_register_to_value (struct frame_info *frame, int regnum,
 			int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte in[MAX_REGISTER_SIZE];
+  gdb_byte *in = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Convert to TYPE.  */
   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -266,7 +266,8 @@ static void
 alpha_value_to_register (struct frame_info *frame, int regnum,
 			 struct type *valtype, const gdb_byte *in)
 {
-  gdb_byte out[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  gdb_byte *out = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   switch (TYPE_LENGTH (valtype))
     {
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 2bdfa57c2ff018f849fabecacfe44fec996c0505..8fe65a1647baf22ff1278a6dfc7e172d8382e2dc 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8150,7 +8150,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,

   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));

       switch (gdbarch_tdep (gdbarch)->fp_model)
 	{
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 3df1ba387a323dc6827b1189432f8877d1833184..68848d1d700981d8f4b698fc122997284c964b57 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -689,7 +689,7 @@ static enum register_status
 bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buffer)
 {
-  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   enum register_status status;

   if (regnum != BFIN_CC_REGNUM)
@@ -710,7 +710,7 @@ static void
 bfin_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buffer)
 {
-  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   if (regnum != BFIN_CC_REGNUM)
     internal_error (__FILE__, __LINE__,
diff --git a/gdb/frame.c b/gdb/frame.c
index d98003dee7c34a63bd25356e6674721664a4b2f3..10c905e9f5c2cabf303e8aaba22a7cd0df77a3ea 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1252,7 +1252,7 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (size);

   frame_unwind_register (frame, regnum, buf);
   return extract_signed_integer (buf, size, byte_order);
@@ -1270,7 +1270,7 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (size);

   frame_unwind_register (frame, regnum, buf);
   return extract_unsigned_integer (buf, size, byte_order);
@@ -1410,7 +1410,8 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
+	  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch,
+							      regnum));
 	  enum lval_type lval;
 	  CORE_ADDR addr;
 	  int realnum;
@@ -1460,8 +1461,8 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
-
+	  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch,
+							      regnum));
 	  deprecated_frame_register_read (frame, regnum, buf);
 	  memcpy (buf + offset, myaddr, curr_len);
 	  put_frame_register (frame, regnum, buf);
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index eb87f93058b0287e8f05c585d1b6aa1ff2bffb78..06f8cbb8cc4cd257a626bafac3307a68a1d04855 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -413,9 +413,10 @@ frv_linux_supply_gregset (const struct regset *regset,
 			  int regnum, const void *gregs, size_t len)
 {
   int regi;
-  char zerobuf[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   /* gr0 always contains 0.  Also, the kernel passes the TBR value in
      this slot.  */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..6191593174f605cb0425a735ec02ca4d38969bc8 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 				      int regnum,
 				      struct value *result_value)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);

@@ -3455,7 +3455,7 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index adbe72133089bc371108d5dd79bf8d8e61ba259c..acc43d7e98ac317824f4755ec150794f63af71e4 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -899,7 +899,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = (const gdb_byte *) xsave;
   int i;
   unsigned int clear_bv;
-  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
+  gdb_byte *zero = (gdb_byte *) alloca (max_register_size (gdbarch));
+  memset (zero, 0, max_register_size (gdbarch));
   enum
     {
       none = 0x0,
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 4c53bc6b05a011e4995c94b669b4f11108a12a38..14e924d9d07ffd83d8bd9b41a9a725c78dce3375 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -1227,7 +1227,7 @@ ia64_register_to_value (struct frame_info *frame, int regnum,
 			int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte in[MAX_REGISTER_SIZE];
+  gdb_byte *in = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Convert to TYPE.  */
   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -1245,7 +1245,7 @@ ia64_value_to_register (struct frame_info *frame, int regnum,
                          struct type *valtype, const gdb_byte *in)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte out[MAX_REGISTER_SIZE];
+  gdb_byte *out = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   convert_typed_floating (in, valtype, out, ia64_ext_type (gdbarch));
   put_frame_register (frame, regnum, out);
 }
@@ -1516,7 +1516,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 	  else if (qp == 0 && rN == 2
 	        && ((rM == fp_reg && fp_reg != 0) || rM == 12))
 	    {
-	      gdb_byte buf[MAX_REGISTER_SIZE];
+	      struct gdbarch *gdbarch = get_frame_arch (this_frame);
+	      gdb_byte *buf
+		= (gdb_byte *) alloca (register_size (gdbarch, sp_regnum));
 	      CORE_ADDR saved_sp = 0;
 	      /* adds r2, spilloffset, rFramePointer
 	           or
@@ -1532,7 +1534,6 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 		 this'll be wrong.  FIXME */
 	      if (this_frame)
 		{
-		  struct gdbarch *gdbarch = get_frame_arch (this_frame);
 		  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 		  get_frame_register (this_frame, sp_regnum, buf);
 		  saved_sp = extract_unsigned_integer (buf, 8, byte_order);
@@ -2289,8 +2290,6 @@ static struct value *
 ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
 				   void **this_cache, int regnum)
 {
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct ia64_frame_cache *cache =
@@ -2305,6 +2304,7 @@ ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
     {
       CORE_ADDR pc = 0;
       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

       if (addr != 0)
 	{
@@ -2495,8 +2495,8 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   long new_sof, old_sof;
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);

@@ -2575,8 +2575,8 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum,
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   long new_sof, old_sof;
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);

@@ -2982,7 +2982,8 @@ ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
 	{
 	  int rrb_pr = 0;
 	  ULONGEST cfm;
-	  gdb_byte buf[MAX_REGISTER_SIZE];
+	  gdb_byte *buf
+	    = (gdb_byte *) alloca (register_size (gdbarch, IA64_CFM_REGNUM));

 	  /* Fetch predicate register rename base from current frame
 	     marker for this frame.  */
@@ -3229,9 +3230,9 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache,
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      gdb_byte from[MAX_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
+      gdb_byte *from = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);

       while (n-- > 0)
@@ -3294,9 +3295,9 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      gdb_byte to[MAX_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
+      gdb_byte *to = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);

       while (n-- > 0)
@@ -3854,9 +3855,9 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	{
 	  argoffset = 0;
 	  len = TYPE_LENGTH (type);
+	  gdb_byte *to = (gdb_byte *) alloca (max_register_size (gdbarch));
 	  while (len > 0 && floatreg < IA64_FR16_REGNUM)
 	    {
-	      gdb_byte to[MAX_REGISTER_SIZE];
 	      convert_typed_floating (value_contents (arg) + argoffset,
 				      float_elt_type, to,
 				      ia64_ext_type (gdbarch));
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index 40f29d343b91f254cce2dd783553795c9c990eff..108d67ddfae0b445e41c6e0ae0a143da8f3b15ac 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -677,7 +677,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   enum type_code typecode;
   CORE_ADDR regval;
   gdb_byte *val;
-  gdb_byte valbuf[MAX_REGISTER_SIZE];
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));
   int len;

   /* First force sp to a 4-byte alignment.  */
@@ -707,7 +707,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       typecode = TYPE_CODE (type);
       len = TYPE_LENGTH (type);

-      memset (valbuf, 0, sizeof (valbuf));
+      memset (valbuf, 0, max_register_size (gdbarch));

       /* Passes structures that do not fit in 2 registers by reference.  */
       if (len > 8
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 6944c74eb198381135fda3ddf01b9da3a63e62d5..09bfaaa9972054b9982eed20235c21467709b25d 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   long regaddr, val;
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
   int tid;

   /* Overload thread id onto process id.  */
@@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
   long regaddr, val;
   int i;
   int tid;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   /* Overload thread id onto process id.  */
   tid = ptid_get_lwp (inferior_ptid);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 22803cb55694a835f59368d69bd0c8a389d778db..e4a5030d446d705f1da82ed451bbecc71b966cf2 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1129,8 +1129,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
 		    struct regcache *this_regs)
 {
   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
-  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
-  gdb_byte this_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *prev_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
+  gdb_byte *this_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
   enum register_status prev_status;
   enum register_status this_status;

diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index 00fae0ec60ddc9e645d3236efe29f2f9e9ceab5c..3ec9a503aa52d4aa3546cd32af3913eadc62d919 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -63,7 +63,7 @@ mips_fbsd_supply_reg (struct regcache *regcache, int regnum, const void *addr,
   else
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       LONGEST val;

       val = extract_signed_integer ((const gdb_byte *) addr, len, byte_order);
@@ -90,7 +90,7 @@ mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr,
   else
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       LONGEST val;

       regcache_raw_collect (regcache, regnum, buf);
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 57e75b5343e1b927e9fe28dea16759f769cf4506..07da374193bf7c83d1e72a0f9e8ebdf025dc0a2e 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -118,7 +118,8 @@ supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+
   store_signed_integer (buf, register_size (gdbarch, regnum), byte_order,
 			extract_signed_integer ((const gdb_byte *) addr, 4,
 						byte_order));
@@ -131,12 +132,12 @@ void
 mips_supply_gregset (struct regcache *regcache,
 		     const mips_elf_gregset_t *gregsetp)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
   const mips_elf_greg_t *regp = *gregsetp;
-  char zerobuf[MAX_REGISTER_SIZE];
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = EF_REG0 + 1; regi <= EF_REG31; regi++)
     supply_32bit_reg (regcache, regi - EF_REG0, regp + regi);
@@ -245,9 +246,9 @@ mips_supply_fpregset (struct regcache *regcache,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
-  char zerobuf[MAX_REGISTER_SIZE];
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = 0; regi < 32; regi++)
     regcache_raw_supply (regcache,
@@ -377,12 +378,12 @@ void
 mips64_supply_gregset (struct regcache *regcache,
 		       const mips64_elf_gregset_t *gregsetp)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
   const mips64_elf_greg_t *regp = *gregsetp;
-  gdb_byte zerobuf[MAX_REGISTER_SIZE];
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  gdb_byte *zerobuf = (gdb_byte *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
     supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
@@ -470,7 +471,7 @@ mips64_fill_gregset (const struct regcache *regcache,

   if (regaddr != -1)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
@@ -574,7 +575,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
     }
   else if (regno == mips_regnum (gdbarch)->fp_control_status)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
@@ -585,7 +586,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
     }
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 637b34edd7c2cf5676b5c359ca1acfe59f0ad6c8..1a427449e053bd9f5a61960bb0eed1b183ca3a2a 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -4523,10 +4523,10 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   /* Now load as many as possible of the first arguments into
      registers, and push the rest onto the stack.  Loop thru args
      from first to last.  */
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argnum = 0; argnum < nargs; argnum++)
     {
       const gdb_byte *val;
-      gdb_byte valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -5757,7 +5757,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      gdb_byte reg[MAX_REGISTER_SIZE];
+      gdb_byte *reg = (gdb_byte *) alloca (max_register_size (gdbarch));
       int regnum;
       int field;
       for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
@@ -6472,7 +6472,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   /* Do values for GP (int) regs.  */
-  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
   int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8);    /* display cols
 							       per row.  */
   int col, byte;
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index 8c23f02b2b58b29b10a65df5ae0b4bcdce2925cd..4d36285bc77bcfe75d09682531bdc961f0e215e3 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -86,7 +86,9 @@ am33_supply_gregset_method (const struct regset *regset,
 			    struct regcache *regcache,
 			    int regnum, const void *gregs, size_t len)
 {
-  char zerobuf[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regsize = register_size (gdbarch, regnum);
+  char zerobuf[regsize];
   const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
   int i;

@@ -188,15 +190,15 @@ am33_supply_gregset_method (const struct regset *regset,

     /* ssp, msp, and usp are inaccessible.  */
   case E_E8_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
     break;
   case E_E9_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
     break;
   case E_E10_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);

     break;
@@ -218,11 +220,11 @@ am33_supply_gregset_method (const struct regset *regset,
     break;
   case E_FPCR_REGNUM + 1:
     /* The two unused registers beyond fpcr are inaccessible.  */
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
     break;
   case E_FPCR_REGNUM + 2:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
     break;
   default:	/* An error, obviously, but should we error out?  */
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 5f5d5ca87b811d66da272036a515210cf2f17134..bce8d839f100b0fe851a8f526e521c3b2dda95f3 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -195,7 +195,7 @@ static void
 mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 			      struct regcache *regcache, void *valbuf)
 {
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
   int len = TYPE_LENGTH (type);
   int reg, regsz;

@@ -1223,7 +1223,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
   int stack_offset = 0;
   int argnum;
   const gdb_byte *val;
-  gdb_byte valbuf[MAX_REGISTER_SIZE];
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));

   /* This should be a nop, but align the stack just in case something
      went wrong.  Stacks are four byte aligned on the mn10300.  */
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index a56d154d3126c69431eff0717d6b4bcbe15f9d96..d9d0ad561f1b6b49324c9f516af1b732efad10b7 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -496,7 +496,7 @@ fetch_register (struct regcache *regcache, int tid, int regno)
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int bytes_transferred;
   unsigned int offset;         /* Offset of registers within the u area.  */
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   if (altivec_register_p (gdbarch, regno))
     {
@@ -983,7 +983,7 @@ store_register (const struct regcache *regcache, int tid, int regno)
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int i;
   size_t bytes_to_transfer;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   if (altivec_register_p (gdbarch, regno))
     {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index ecae6363e3ae0a388bc5294aade5590c4b432d18..15350e19b4acaaf8f92b86db7aa65f9d89c06dec 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -134,13 +134,14 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		    {
 		      /* Always store the floating point value using
 		         the register's floating-point format.  */
-		      gdb_byte regval[MAX_REGISTER_SIZE];
+		      int regnum = tdep->ppc_fp0_regnum + freg;
+		      gdb_byte *regval
+			= (gdb_byte *) alloca (register_size (gdbarch,
+							      regnum));
 		      struct type *regtype
 			= register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
 		      convert_typed_floating (val, type, regval, regtype);
-		      regcache_cooked_write (regcache,
-                                             tdep->ppc_fp0_regnum + freg,
-					     regval);
+		      regcache_cooked_write (regcache, regnum, regval);
 		    }
 		  freg++;
 		}
@@ -278,7 +279,9 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		{
 		  if (write_pass)
 		    {
-		      gdb_byte regval[MAX_REGISTER_SIZE];
+		      int regnum = tdep->ppc_fp0_regnum + freg;
+		      gdb_byte *regval
+			= (gdb_byte *) alloca (register_size (gdbarch, regnum));
 		      const gdb_byte *p;

 		      /* 32-bit decimal floats are right aligned in the
@@ -291,8 +294,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		      else
 			p = val;

-		      regcache_cooked_write (regcache,
-			  tdep->ppc_fp0_regnum + freg, p);
+		      regcache_cooked_write (regcache, regnum, p);
 		    }

 		  freg++;
@@ -364,7 +366,9 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 			  if (write_pass)
 			    {
 			      int regnum = tdep->ppc_fp0_regnum + freg;
-			      gdb_byte regval[MAX_REGISTER_SIZE];
+			      gdb_byte *regval
+				= (gdb_byte *) alloca (register_size (gdbarch,
+								      regnum));
 			      struct type *regtype
 				= register_type (gdbarch, regnum);
 			      convert_typed_floating (elval, eltype,
@@ -411,16 +415,17 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		    }
 		  else
 		    {
-		      gdb_byte word[MAX_REGISTER_SIZE];
+		      int regnum = tdep->ppc_gp0_regnum + greg;
+		      gdb_byte *word
+			= (gdb_byte *) alloca (register_size (gdbarch,
+							      regnum));
 		      store_unsigned_integer (word, tdep->wordsize, byte_order,
 					      unpack_long (eltype, elval));

 		      if (greg <= 10)
 			{
 			  if (write_pass)
-			    regcache_cooked_write (regcache,
-						   tdep->ppc_gp0_regnum + greg,
-						   word);
+			    regcache_cooked_write (regcache, regnum, word);
 			  greg++;
 			}
 		      else
@@ -516,8 +521,9 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	    {
 	      /* Reduce the parameter down to something that fits in a
 	         "word".  */
-	      gdb_byte word[MAX_REGISTER_SIZE];
-	      memset (word, 0, MAX_REGISTER_SIZE);
+	      gdb_byte *word
+		= (gdb_byte *) alloca (max_register_size (gdbarch));
+	      memset (word, 0, max_register_size (gdbarch));
 	      if (len > tdep->wordsize
 		  || TYPE_CODE (type) == TYPE_CODE_STRUCT
 		  || TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -621,9 +627,11 @@ get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
   /* 32-bit and 64-bit decimal floats in f1.  */
   if (TYPE_LENGTH (valtype) <= 8)
     {
+      int regnum = tdep->ppc_fp0_regnum + 1;
       if (writebuf != NULL)
 	{
-	  gdb_byte regval[MAX_REGISTER_SIZE];
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));
 	  const gdb_byte *p;

 	  /* 32-bit decimal float is right aligned in the doubleword.  */
@@ -635,11 +643,11 @@ get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
 	  else
 	    p = writebuf;

-	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p);
+	  regcache_cooked_write (regcache, regnum, p);
 	}
       if (readbuf != NULL)
 	{
-	  regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf);
+	  regcache_cooked_read (regcache, regnum, readbuf);

 	  /* Left align 32-bit decimal float.  */
 	  if (TYPE_LENGTH (valtype) == 4)
@@ -702,24 +710,26 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
       && TYPE_LENGTH (type) <= 8
       && !tdep->soft_float)
     {
+      int regnum = tdep->ppc_fp0_regnum + 1;
       if (readbuf)
 	{
 	  /* Floats and doubles stored in "f1".  Convert the value to
 	     the required type.  */
-	  gdb_byte regval[MAX_REGISTER_SIZE];
-	  struct type *regtype = register_type (gdbarch,
-                                                tdep->ppc_fp0_regnum + 1);
-	  regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));
+	  struct type *regtype = register_type (gdbarch, regnum);
+	  regcache_cooked_read (regcache, regnum, regval);
 	  convert_typed_floating (regval, regtype, readbuf, type);
 	}
       if (writebuf)
 	{
 	  /* Floats and doubles stored in "f1".  Convert the value to
 	     the register's "double" type.  */
-	  gdb_byte regval[MAX_REGISTER_SIZE];
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));
 	  struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
 	  convert_typed_floating (writebuf, type, regval, regtype);
-	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
+	  regcache_cooked_write (regcache, regnum, regval);
 	}
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -847,7 +857,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  if (TYPE_CODE (eltype) == TYPE_CODE_FLT)
 	    {
 	      int regnum = tdep->ppc_fp0_regnum + 1 + i;
-	      gdb_byte regval[MAX_REGISTER_SIZE];
+	      gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								     regnum));
 	      struct type *regtype = register_type (gdbarch, regnum);

 	      if (writebuf != NULL)
@@ -977,7 +988,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
       /* GCC screwed up for structures or unions whose size is less
 	 than or equal to 8 bytes..  Instead of left-aligning, it
 	 right-aligns the data into the buffer formed by r3, r4.  */
-      gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+      gdb_byte *regvals
+	= (gdb_byte *) alloca (max_register_size (gdbarch) * 2);
       int len = TYPE_LENGTH (type);
       int offset = (2 * tdep->wordsize - len) % tdep->wordsize;

@@ -992,7 +1004,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	}
       if (writebuf)
 	{
-	  memset (regvals, 0, sizeof regvals);
+	  memset (regvals, 0, max_register_size (gdbarch) * 2);
 	  memcpy (regvals + offset, writebuf, len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
 				 regvals + 0 * tdep->wordsize);
@@ -1010,7 +1022,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  /* This matches SVr4 PPC, it does not match GCC.  */
 	  /* The value is right-padded to 8 bytes and then loaded, as
 	     two "words", into r3/r4.  */
-	  gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+	  gdb_byte *regvals
+	    = (gdb_byte *) alloca (max_register_size (gdbarch) * 2);
 	  regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
 				regvals + 0 * tdep->wordsize);
 	  if (TYPE_LENGTH (type) > tdep->wordsize)
@@ -1023,8 +1036,9 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  /* This matches SVr4 PPC, it does not match GCC.  */
 	  /* The value is padded out to 8 bytes and then loaded, as
 	     two "words" into r3/r4.  */
-	  gdb_byte regvals[MAX_REGISTER_SIZE * 2];
-	  memset (regvals, 0, sizeof regvals);
+	  gdb_byte *regvals
+	    = (gdb_byte *) alloca (max_register_size (gdbarch) * 2);
+	  memset (regvals, 0, max_register_size (gdbarch) * 2);
 	  memcpy (regvals, writebuf, TYPE_LENGTH (type));
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
 				 regvals + 0 * tdep->wordsize);
@@ -1340,7 +1354,7 @@ ppc64_sysv_abi_push_integer (struct gdbarch *gdbarch, ULONGEST val,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));

   if (argpos->regcache)
     store_unsigned_integer (buf, tdep->wordsize, byte_order, val);
@@ -1369,7 +1383,8 @@ ppc64_sysv_abi_push_freg (struct gdbarch *gdbarch,
 	{
 	  int regnum = tdep->ppc_fp0_regnum + argpos->freg;
 	  struct type *regtype = register_type (gdbarch, regnum);
-	  gdb_byte regval[MAX_REGISTER_SIZE];
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));

 	  convert_typed_floating (val, type, regval, regtype);
 	  regcache_cooked_write (argpos->regcache, regnum, regval);
@@ -1814,7 +1829,7 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
     {
       int regnum = tdep->ppc_fp0_regnum + 1 + index;
       struct type *regtype = register_type (gdbarch, regnum);
-      gdb_byte regval[MAX_REGISTER_SIZE];
+      gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch, regnum));

       if (writebuf != NULL)
 	{
@@ -2072,8 +2087,9 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,

       for (i = 0; i < n_regs; i++)
 	{
-	  gdb_byte regval[MAX_REGISTER_SIZE];
 	  int regnum = tdep->ppc_gp0_regnum + 3 + i;
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));
 	  int offset = i * tdep->wordsize;
 	  int len = TYPE_LENGTH (valtype) - offset;

@@ -2082,7 +2098,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,

 	  if (writebuf != NULL)
 	    {
-	      memset (regval, 0, sizeof regval);
+	      memset (regval, 0, register_size (gdbarch, regnum));
 	      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
 		  && offset == 0)
 		memcpy (regval + tdep->wordsize - len, writebuf, len);
diff --git a/gdb/record-full.c b/gdb/record-full.c
index fdd613b6e41bbfcd8644b02ccfeb98b53b518bff..c634de5edc73572aee52517c13e205039e1f9dd0 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -698,7 +698,8 @@ record_full_exec_insn (struct regcache *regcache,
     {
     case record_full_reg: /* reg */
       {
-        gdb_byte reg[MAX_REGISTER_SIZE];
+	gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch,
+							    entry->u.reg.num));

         if (record_debug > 1)
           fprintf_unfiltered (gdb_stdlog,
@@ -792,15 +793,17 @@ static void
 record_full_core_open_1 (const char *name, int from_tty)
 {
   struct regcache *regcache = get_current_regcache ();
-  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regnum = gdbarch_num_regs (gdbarch);
+  int regmaxsize = max_register_size (gdbarch);
   int i;

   /* Get record_full_core_regbuf.  */
   target_fetch_registers (regcache, -1);
-  record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum);
+  record_full_core_regbuf = (gdb_byte *) xmalloc (regmaxsize * regnum);
   for (i = 0; i < regnum; i ++)
     regcache_raw_collect (regcache, i,
-			  record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			  record_full_core_regbuf + regmaxsize * i);

   /* Get record_full_core_start and record_full_core_end.  */
   if (build_section_table (core_bfd, &record_full_core_start,
@@ -2038,6 +2041,9 @@ record_full_core_fetch_registers (struct target_ops *ops,
 				  struct regcache *regcache,
 				  int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (regno < 0)
     {
       int num = gdbarch_num_regs (get_regcache_arch (regcache));
@@ -2045,11 +2051,11 @@ record_full_core_fetch_registers (struct target_ops *ops,

       for (i = 0; i < num; i ++)
         regcache_raw_supply (regcache, i,
-                             record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			     record_full_core_regbuf + regmaxsize * i);
     }
   else
     regcache_raw_supply (regcache, regno,
-                         record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			 record_full_core_regbuf + regmaxsize * regno);
 }

 /* "to_prepare_to_store" method for prec over corefile.  */
@@ -2067,9 +2073,12 @@ record_full_core_store_registers (struct target_ops *ops,
                              struct regcache *regcache,
                              int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (record_full_gdb_operation_disable)
     regcache_raw_collect (regcache, regno,
-                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			  record_full_core_regbuf + regmaxsize * regno);
   else
     error (_("You can't do that without a process to debug."));
 }
@@ -2265,7 +2274,7 @@ init_record_full_core_ops (void)
      record_full_reg:
        1 byte:  record type (record_full_reg, see enum record_full_type).
        8 bytes: register id (network byte order).
-       MAX_REGISTER_SIZE bytes: register value.
+       max_register_size bytes: register value.
      record_full_mem:
        1 byte:  record type (record_full_mem, see enum record_full_type).
        8 bytes: memory length (network byte order).
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index b0c68c617e365c0ea18ac2eca525598b688ffbb5..b9051269beafbe833126150e1cee2960ec726c0e 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -447,29 +447,31 @@ gdbsim_fetch_register (struct target_ops *ops,
       {
 	/* For moment treat a `does not exist' register the same way
 	   as an ``unavailable'' register.  */
-	gdb_byte buf[MAX_REGISTER_SIZE];
+	int regsize = register_size (gdbarch, regno);
+      	gdb_byte *buf = (gdb_byte *) alloca (regsize);
 	int nr_bytes;

-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	regcache_raw_supply (regcache, regno, buf);
 	break;
       }

     default:
       {
+	int regsize = register_size (gdbarch, regno);
 	static int warn_user = 1;
-	gdb_byte buf[MAX_REGISTER_SIZE];
+	gdb_byte buf[regsize];
 	int nr_bytes;

 	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
 				       gdbarch_register_sim_regno
 					 (gdbarch, regno),
 				       buf,
-				       register_size (gdbarch, regno));
+				       regsize);
 	if (nr_bytes > 0
-	    && nr_bytes != register_size (gdbarch, regno) && warn_user)
+	    && nr_bytes != regsize && warn_user)
 	  {
 	    fprintf_unfiltered (gdb_stderr,
 				"Size of register %s (%d/%d) "
@@ -478,7 +480,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 				regno,
 				gdbarch_register_sim_regno
 				  (gdbarch, regno),
-				nr_bytes, register_size (gdbarch, regno));
+				nr_bytes, regsize);
 	    warn_user = 0;
 	  }
 	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
@@ -492,7 +494,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 	    fprintf_unfiltered (gdb_stdlog,
 				"gdbsim_fetch_register: %d", regno);
 	    /* FIXME: We could print something more intelligible.  */
-	    dump_mem (buf, register_size (gdbarch, regno));
+	    dump_mem (buf, regsize);
 	  }
 	break;
       }
@@ -516,15 +518,16 @@ gdbsim_store_register (struct target_ops *ops,
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
     {
-      gdb_byte tmp[MAX_REGISTER_SIZE];
+      int regsize = register_size (gdbarch, regno);
+      gdb_byte tmp[regsize];
       int nr_bytes;

       regcache_cooked_read (regcache, regno, tmp);
       nr_bytes = sim_store_register (sim_data->gdbsim_desc,
 				     gdbarch_register_sim_regno
 				       (gdbarch, regno),
-				     tmp, register_size (gdbarch, regno));
-      if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno))
+				     tmp, regsize);
+      if (nr_bytes > 0 && nr_bytes != regsize)
 	internal_error (__FILE__, __LINE__,
 			_("Register size different to expected"));
       if (nr_bytes < 0)
@@ -538,7 +541,7 @@ gdbsim_store_register (struct target_ops *ops,
 	{
 	  fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno);
 	  /* FIXME: We could print something more intelligible.  */
-	  dump_mem (tmp, register_size (gdbarch, regno));
+	  dump_mem (tmp, regsize);
 	}
     }
 }
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 9841a60eafb0381cd2343dd3a8d5745571f5460e..eefd0d6a15f7a64eaa4bf10a72bde80a35646ac9 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -236,6 +236,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    User may have to cast\args to handle promotion correctly
    since gdb won't know if prototype supplied or not.  */

+  gdb_byte *word = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
       int reg_size = register_size (gdbarch, ii + 3);
@@ -253,14 +254,12 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	     Always store the floating point value using the register's
 	     floating-point format.  */
 	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
-	  gdb_byte reg_val[MAX_REGISTER_SIZE];
 	  struct type *reg_type = register_type (gdbarch, fp_regnum);

 	  gdb_assert (len <= 8);

-	  convert_typed_floating (value_contents (arg), type,
-				  reg_val, reg_type);
-	  regcache_cooked_write (regcache, fp_regnum, reg_val);
+	  convert_typed_floating (value_contents (arg), type, word, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, word);
 	  ++f_argno;
 	}

@@ -270,7 +269,6 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	  /* Argument takes more than one register.  */
 	  while (argbytes < len)
 	    {
-	      gdb_byte word[MAX_REGISTER_SIZE];
 	      memset (word, 0, reg_size);
 	      memcpy (word,
 		      ((char *) value_contents (arg)) + argbytes,
@@ -290,8 +288,6 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
 	{
 	  /* Argument can fit in one register.  No problem.  */
-	  gdb_byte word[MAX_REGISTER_SIZE];
-
 	  memset (word, 0, reg_size);
 	  memcpy (word, value_contents (arg), len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word);
diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c
index f2aa1f8448cf487b1522df89ef42a3937799d95f..56f80410770b52a6ea81639c5108bbddd5c164f5 100644
--- a/gdb/rs6000-lynx178-tdep.c
+++ b/gdb/rs6000-lynx178-tdep.c
@@ -87,6 +87,7 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
      User may have to cast\args to handle promotion correctly
      since gdb won't know if prototype supplied or not.  */

+  gdb_byte *word = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
       int reg_size = register_size (gdbarch, ii + 3);
@@ -105,24 +106,22 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
 	     Always store the floating point value using the register's
 	     floating-point format.  */
 	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
-	  gdb_byte reg_val[MAX_REGISTER_SIZE];
 	  struct type *reg_type = register_type (gdbarch, fp_regnum);

 	  gdb_assert (len <= 8);

-	  convert_typed_floating (value_contents (arg), type,
-				  reg_val, reg_type);
-	  regcache_cooked_write (regcache, fp_regnum, reg_val);
+	  convert_typed_floating (value_contents (arg), type, word, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, word);
 	  ++f_argno;
 	}

       if (len > reg_size)
 	{
-
 	  /* Argument takes more than one register.  */
 	  while (argbytes < len)
 	    {
-	      gdb_byte word[MAX_REGISTER_SIZE];
+	      gdb_byte *word
+		= (gdb_byte *) alloca (max_register_size (gdbarch));
 	      memset (word, 0, reg_size);
 	      memcpy (word,
 		      ((char *) value_contents (arg)) + argbytes,
@@ -142,8 +141,6 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
       else
 	{
 	  /* Argument can fit in one register.  No problem.  */
-	  gdb_byte word[MAX_REGISTER_SIZE];
-
 	  memset (word, 0, reg_size);
 	  memcpy (word, value_contents (arg), len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word);
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index f42847bfeab8ad6d03c96a161238283a262f98d1..6f322ed465ee40f06fe35967104fc0c90fb88661 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -162,7 +162,7 @@ static void
 fetch_register (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int addr[MAX_REGISTER_SIZE];
+  int *addr = (int *) alloca (register_size (gdbarch, regno) * sizeof (int));
   int nr, isfloat;

   /* Retrieved values may be -1, so infer errors from errno.  */
@@ -222,7 +222,7 @@ static void
 store_register (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int addr[MAX_REGISTER_SIZE];
+  int *addr = (int *) alloca (register_size (gdbarch, regno) * sizeof (int));
   int nr, isfloat;

   /* Fetch the register's value from the register cache.  */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 527f643b7be833b4bf7a2386940f9764f8b81514..52bf957dd422deb41248dd8bb696dd0aae74c142 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2590,8 +2590,7 @@ rs6000_register_to_value (struct frame_info *frame,
 			  int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte from[MAX_REGISTER_SIZE];
-
+  gdb_byte *from = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -2612,7 +2611,7 @@ rs6000_value_to_register (struct frame_info *frame,
                           const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte to[MAX_REGISTER_SIZE];
+  gdb_byte *to = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 9b3692dc0c32ffcb53d99f0fc095303d2c221fcb..ac59bdc051c5ce524b70af6d5d3b2942dffc2f1c 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1648,7 +1648,6 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			 int reg_nr, gdb_byte *buffer)
 {
   int base_regnum;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
   enum register_status status;

   if (reg_nr == PSEUDO_BANK_REGNUM)
@@ -1656,6 +1655,8 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
       base_regnum = dr_reg_base_num (gdbarch, reg_nr);
+      gdb_byte *temp_buffer
+	= (gdb_byte *) alloca (register_size (gdbarch, base_regnum));

       /* Build the value in the provided buffer.  */
       /* Read the real regs for which this one is an alias.  */
@@ -1687,7 +1688,6 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			  int reg_nr, const gdb_byte *buffer)
 {
   int base_regnum, portion;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];

   if (reg_nr == PSEUDO_BANK_REGNUM)
     {
@@ -1704,6 +1704,8 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
       base_regnum = dr_reg_base_num (gdbarch, reg_nr);
+      gdb_byte *temp_buffer
+	= (gdb_byte *) alloca (register_size (gdbarch, base_regnum));

       /* We must pay attention to the endiannes.  */
       sh_register_convert_to_raw (gdbarch, register_type (gdbarch, reg_nr),
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 23f5ade3b2e631eeb50cb918a4f36bb8cfbe6131..9e77bb9597354541a7fc5f7c92149074f5dce719 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1528,7 +1528,8 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum;
   int offset = 0;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *temp_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   enum register_status status;

   if (reg_nr >= DR0_REGNUM
@@ -1704,7 +1705,7 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum, portion;
   int offset;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *temp_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));

   if (reg_nr >= DR0_REGNUM
       && reg_nr <= DR_LAST_REGNUM)
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index a09a3ab9a8bc56f367e3ba1537f5674f0a7f491f..4ac95ad5f726e57e5d7a9d2696fef33bbc52473d 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -514,6 +514,7 @@ sol_thread_store_registers (struct target_ops *ops,
   td_err_e val;
   prgregset_t gregset;
   prfpregset_t fpregset;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);

   if (!ptid_tid_p (inferior_ptid))
     {
@@ -535,7 +536,7 @@ sol_thread_store_registers (struct target_ops *ops,
   if (regnum != -1)
     {
       /* Not writing all the registers.  */
-      char old_value[MAX_REGISTER_SIZE];
+      char *old_value = (char *) alloca (register_size (gdbarch, regnum));

       /* Save new register value.  */
       regcache_raw_collect (regcache, regnum, old_value);
diff --git a/gdb/stack.c b/gdb/stack.c
index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..b76b2f540de3dce23dcb29a56280295790a7a533 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1667,7 +1667,7 @@ frame_info (char *addr_exp, int from_tty)
 	  {
 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
-	    gdb_byte value[MAX_REGISTER_SIZE];
+	    gdb_byte *value = (gdb_byte *) alloca (sp_size);
 	    CORE_ADDR sp;

 	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
diff --git a/gdb/target.c b/gdb/target.c
index be7367c4c940e0ee5889cd00193ecb9e9de01b6b..7997615dfa98147fc080482d6781d3abbb324b75 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3565,7 +3565,7 @@ debug_print_register (const char * func,
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       int i, size = register_size (gdbarch, regno);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (size);

       regcache_raw_collect (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 978b13abc57a404974fc02dfd868977b3dab0290..d2e97f86705d13975e5db8d981acab1002cfd567 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -370,7 +370,10 @@ static void
 xtensa_register_write_masked (struct regcache *regcache,
 			      xtensa_register_t *reg, const gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
+						 + 1);
+
   const xtensa_mask_t *mask = reg->mask;

   int shift = 0;		/* Shift for next mask (mod 32).  */
@@ -454,7 +457,9 @@ static enum register_status
 xtensa_register_read_masked (struct regcache *regcache,
 			     xtensa_register_t *reg, gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
+						 + 1);
   const xtensa_mask_t *mask = reg->mask;

   int shift = 0;
@@ -559,12 +564,11 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
       && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+      int wb_regnum = gdbarch_tdep (gdbarch)->wb_regnum;
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, wb_regnum));
       enum register_status status;

-      status = regcache_raw_read (regcache,
-				  gdbarch_tdep (gdbarch)->wb_regnum,
-				  buf);
+      status = regcache_raw_read (regcache, wb_regnum, buf);
       if (status != REG_VALID)
 	return status;
       regnum = arreg_number (gdbarch, regnum,
@@ -655,10 +659,10 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
       && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+      int wb_regnum = gdbarch_tdep (gdbarch)->wb_regnum;
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, wb_regnum));

-      regcache_raw_read (regcache,
-			 gdbarch_tdep (gdbarch)->wb_regnum, buf);
+      regcache_raw_read (regcache, wb_regnum, buf);
       regnum = arreg_number (gdbarch, regnum,
 			     extract_unsigned_integer (buf, 4, byte_order));
     }



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-01-24 10:31 [PATCH] Removal of uses of MAX_REGISTER_SIZE Alan Hayward
@ 2017-01-27 11:49 ` Pedro Alves
  2017-01-27 12:11 ` Pedro Alves
  1 sibling, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2017-01-27 11:49 UTC (permalink / raw)
  To: Alan Hayward, gdb-patches; +Cc: nd

On 01/24/2017 10:31 AM, Alan Hayward wrote:
> This patch replaces all current uses of MAX_REGISTER_SIZE with calls to
> either register_size() when the register number is known, and
> max_register_size() in all other cases.
> 
> It assumes that the patch "[PATCH 3/3] Calculate max register size" will be
> approved, and follows the methods used in that series of 3 patches.
> 
> In a couple of cases I've moved variables outside a loop to prevent multiple
> allocations.

The very first hunk calls alloca in a loop (I didn't look any
further).  This is unfortunately easy to get wrong with alloca.  (Not
just in this patch, but also future patches that might move things
around and add loops around allocas without noticing.)  Wish
the compiler warned about it and/or that C++ supported VLAs.  :-/

> index 801c03d5a0b5d205dc967cb0d53e299ea95eaa8f..a317c8f2bb192fc25689c84375b8c7bb327dd596 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -1982,7 +1982,8 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
>        for (i = 0; i < elements; i++)
>  	{
>  	  int regno = AARCH64_V0_REGNUM + i;
> -	  bfd_byte tmpbuf[MAX_REGISTER_SIZE];
> +	  bfd_byte *tmpbuf = (bfd_byte *) alloca (register_size (gdbarch,
> +								 regno));
> 
>  	  if (aarch64_debug)
>  	    {

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-01-24 10:31 [PATCH] Removal of uses of MAX_REGISTER_SIZE Alan Hayward
  2017-01-27 11:49 ` Pedro Alves
@ 2017-01-27 12:11 ` Pedro Alves
  2017-01-27 16:46   ` Alan Hayward
  2017-02-01 12:45   ` Yao Qi
  1 sibling, 2 replies; 28+ messages in thread
From: Pedro Alves @ 2017-01-27 12:11 UTC (permalink / raw)
  To: Alan Hayward, gdb-patches; +Cc: nd

On 01/24/2017 10:31 AM, Alan Hayward wrote:
>  aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
>  		      int regnum, const gdb_byte *buf)
>  {
> -  gdb_byte reg_buf[MAX_REGISTER_SIZE];
> +  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
> 
>    /* Ensure the register buffer is zero, we want gdb writes of the
>       various 'scalar' pseudo registers to behavior like architectural
>       writes, register width bytes are written the remainder are set to
>       zero.  */
> -  memset (reg_buf, 0, sizeof (reg_buf));
> +  memset (reg_buf, 0, sizeof (register_size (gdbarch, regnum)));

OK, I scrolled a bit further down to the third hunk.  This sizeof is 
clearly broken.  There may be more instances of this.

Makes me wonder whether this is the right approach.  :-/
(No, I don't have a formed opinion for what that would be.)

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-01-27 12:11 ` Pedro Alves
@ 2017-01-27 16:46   ` Alan Hayward
  2017-02-01 15:49     ` Pedro Alves
  2017-02-01 12:45   ` Yao Qi
  1 sibling, 1 reply; 28+ messages in thread
From: Alan Hayward @ 2017-01-27 16:46 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, nd

Thanks for the review.

> On 27 Jan 2017, at 11:49, Pedro Alves <palves@redhat.com> wrote:
> 
> On 01/24/2017 10:31 AM, Alan Hayward wrote:
>> This patch replaces all current uses of MAX_REGISTER_SIZE with calls to
>> either register_size() when the register number is known, and
>> max_register_size() in all other cases.
>> 
>> It assumes that the patch "[PATCH 3/3] Calculate max register size" will be
>> approved, and follows the methods used in that series of 3 patches.
>> 
>> In a couple of cases I've moved variables outside a loop to prevent multiple
>> allocations.
> 
> The very first hunk calls alloca in a loop (I didn't look any
> further).  This is unfortunately easy to get wrong with alloca.  (Not
> just in this patch, but also future patches that might move things
> around and add loops around allocas without noticing.)  Wish
> the compiler warned about it and/or that C++ supported VLAs.  :-/
> 

Fixed. There were quite of few of these already in this patch, but looks
like I missed a few. Fixed those up too.


> On 27 Jan 2017, at 12:11, Pedro Alves <palves@redhat.com> wrote:
> 
> On 01/24/2017 10:31 AM, Alan Hayward wrote:
>> aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
>> 		      int regnum, const gdb_byte *buf)
>> {
>> -  gdb_byte reg_buf[MAX_REGISTER_SIZE];
>> +  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
>> 
>>   /* Ensure the register buffer is zero, we want gdb writes of the
>>      various 'scalar' pseudo registers to behavior like architectural
>>      writes, register width bytes are written the remainder are set to
>>      zero.  */
>> -  memset (reg_buf, 0, sizeof (reg_buf));
>> +  memset (reg_buf, 0, sizeof (register_size (gdbarch, regnum)));
> 
> OK, I scrolled a bit further down to the third hunk.  This sizeof is 
> clearly broken.  There may be more instances of this.
> 

Fixed. Did a grep for sizeof across the patch and couldn’t see any more.


> Makes me wonder whether this is the right approach.  :-/
> (No, I don't have a formed opinion for what that would be.)
> 

Couldn’t see any other way of doing this (hence the previous patches that
just changed one or two of them). Once they are all changed it shouldn’t
be too much of a problem going forward - it’s doing this many at once
which is the pain.

Updated patch below.

Thanks,
Alan.

2017-01-27  Alan Hayward  <alan.hayward@arm.com>

	* aarch64-tdep.c (aarch64_store_return_value): Replace
	MAX_REGISTER_SIZE.
	(aarch64_pseudo_read_value): Likewise.
	(aarch64_pseudo_write): Likewise.
	* alpha-tdep.c (alpha_register_to_value): Likewise.
	(alpha_value_to_register): Likewise.
	* arm-tdep.c (arm_store_return_value): Likewise.
	* bfin-tdep.c (bfin_pseudo_register_read): Likewise.
	(bfin_pseudo_register_write): Likewise.
	* frame.c (frame_unwind_register_signed): Likewise.
	(frame_unwind_register_unsigned): Likewise.
	(get_frame_register_bytes): Likewise.
	(put_frame_register_bytes): Likewise.
	* frv-linux-tdep.c (frv_linux_supply_gregset): Likewise.
	* i386-tdep.c (i386_pseudo_register_read_into_value): Likewise.
	(i386_pseudo_register_write): Likewise.
	(i386_process_record): Likewise.
	* i387-tdep.c (i387_supply_xsave): Likewise.
	* ia64-tdep.c (ia64_register_to_value): Likewise.
	(ia64_value_to_register): Likewise.
	(examine_prologue): Likewise.
	(ia64_sigtramp_frame_prev_register): Likewise.
	(ia64_access_reg): Likewise.
	(ia64_access_rse_reg): Likewise.
	(ia64_libunwind_frame_prev_register): Likewise.
	(ia64_extract_return_value): Likewise.
	(ia64_store_return_value): Likewise.
	(ia64_push_dummy_call): Likewise.
	* m32r-tdep.c (m32r_push_dummy_call): Likewise.
	* m68k-linux-nat.c (fetch_register): Likewise.
	(store_register): Likewise.
	* gdb/mi/mi-main.c (register_changed_p): Likewise
	* mips-fbsd-tdep.c (mips_fbsd_supply_reg): Likewise.
	(mips_fbsd_collect_reg): Likewise.
	* mips-linux-tdep.c (supply_32bit_reg): Likewise.
	(mips_supply_gregset): Likewise.
	(mips_supply_fpregset): Likewise.
	(mips64_supply_gregset): Likewise.
	(mips64_fill_gregset): Likewise.
	(mips64_fill_fpregset): Likewise.
	* mips-tdep.c (mips_eabi_push_dummy_call): Likewise.
	(mips_o32_return_value): Likewise.
	(print_gp_register_row): Likewise.
	* mn10300-linux-tdep.c (am33_supply_gregset_method): Likewise.
	* mn10300-tdep.c (mn10300_extract_return_value): Likewise.
	(mn10300_push_dummy_call): Likewise.
	* ppc-linux-nat.c: Likewise.
	* ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call): Likewise.
	(get_decimal_float_return_value): Likewise.
	(do_ppc_sysv_return_value): Likewise.
	(ppc64_sysv_abi_push_integer): Likewise.
	(ppc64_sysv_abi_push_freg): Likewise.
	(ppc64_sysv_abi_return_value_base): Likewise.
	(ppc64_sysv_abi_return_value): Likewise.
	* record-full.c (record_full_exec_insn): Likewise.
	(record_full_core_open_1): Likewise.
	(record_full_core_fetch_registers): Likewise.
	(record_full_core_store_registers): Likewise.
	(init_record_full_core_ops): Likewise.
	* remote-sim.c (gdbsim_fetch_register): Likewise.
	(gdbsim_store_register): Likewise.
	* rs6000-aix-tdep.c (rs6000_push_dummy_call): Likewise.
	* rs6000-lynx178-tdep.c (rs6000_lynx178_push_dummy_call): Likewise.
	* rs6000-nat.c: Likewise.
	* rs6000-tdep.c (rs6000_register_to_value): Likewise.
	(rs6000_value_to_register): Likewise.
	* sh-tdep.c (sh_pseudo_register_read): Likewise.
	(sh_pseudo_register_write): Likewise.
	* sh64-tdep.c (sh64_pseudo_register_read): Likewise.
	(sh64_pseudo_register_write): Likewise.
	* sol-thread.c (sol_thread_store_registers): Likewise.
	* stack.c (frame_info): Likewise.
	* target.c (debug_print_register): Likewise.
	* xtensa-tdep.c (xtensa_register_write_masked): Likewise.
	(xtensa_register_read_masked): Likewise.
	(xtensa_pseudo_register_read): Likewise.
	(xtensa_pseudo_register_write): Likewise.


diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 801c03d5a0b5d205dc967cb0d53e299ea95eaa8f..d946d82aa8d0bd93c0f265a1239a12332ec85597 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1978,11 +1978,11 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
       struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
       int len = TYPE_LENGTH (member_type);
       int i;
+      bfd_byte *tmpbuf = (bfd_byte *) alloca (max_register_size (gdbarch));

       for (i = 0; i < elements; i++)
 	{
 	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte tmpbuf[MAX_REGISTER_SIZE];

 	  if (aarch64_debug)
 	    {
@@ -2236,7 +2236,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
 			   struct regcache *regcache,
 			   int regnum)
 {
-  gdb_byte reg_buf[MAX_REGISTER_SIZE];
+  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   struct value *result_value;
   gdb_byte *buf;

@@ -2331,13 +2331,13 @@ static void
 aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 		      int regnum, const gdb_byte *buf)
 {
-  gdb_byte reg_buf[MAX_REGISTER_SIZE];
+  gdb_byte *reg_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Ensure the register buffer is zero, we want gdb writes of the
      various 'scalar' pseudo registers to behavior like architectural
      writes, register width bytes are written the remainder are set to
      zero.  */
-  memset (reg_buf, 0, sizeof (reg_buf));
+  memset (reg_buf, 0, register_size (gdbarch, regnum));

   regnum -= gdbarch_num_regs (gdbarch);

diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 4dd65c58cc2896ea6038399128e3eb376d1ee672..5d850db07da0d5f6d47795da970add58161d722c 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -244,7 +244,7 @@ alpha_register_to_value (struct frame_info *frame, int regnum,
 			int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte in[MAX_REGISTER_SIZE];
+  gdb_byte *in = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Convert to TYPE.  */
   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -266,7 +266,8 @@ static void
 alpha_value_to_register (struct frame_info *frame, int regnum,
 			 struct type *valtype, const gdb_byte *in)
 {
-  gdb_byte out[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  gdb_byte *out = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   switch (TYPE_LENGTH (valtype))
     {
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 2bdfa57c2ff018f849fabecacfe44fec996c0505..8fe65a1647baf22ff1278a6dfc7e172d8382e2dc 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8150,7 +8150,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,

   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));

       switch (gdbarch_tdep (gdbarch)->fp_model)
 	{
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 3df1ba387a323dc6827b1189432f8877d1833184..68848d1d700981d8f4b698fc122997284c964b57 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -689,7 +689,7 @@ static enum register_status
 bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			   int regnum, gdb_byte *buffer)
 {
-  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   enum register_status status;

   if (regnum != BFIN_CC_REGNUM)
@@ -710,7 +710,7 @@ static void
 bfin_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buffer)
 {
-  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   if (regnum != BFIN_CC_REGNUM)
     internal_error (__FILE__, __LINE__,
diff --git a/gdb/frame.c b/gdb/frame.c
index d98003dee7c34a63bd25356e6674721664a4b2f3..16250f9a800b607706845d7b3bdb5ee7567d4bd5 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1252,7 +1252,7 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (size);

   frame_unwind_register (frame, regnum, buf);
   return extract_signed_integer (buf, size, byte_order);
@@ -1270,7 +1270,7 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (size);

   frame_unwind_register (frame, regnum, buf);
   return extract_unsigned_integer (buf, size, byte_order);
@@ -1389,6 +1389,8 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
     error (_("Bad debug information detected: "
 	     "Attempt to read %d bytes from registers."), len);

+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* Copy the data.  */
   while (len > 0)
     {
@@ -1410,7 +1412,6 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
 	  enum lval_type lval;
 	  CORE_ADDR addr;
 	  int realnum;
@@ -1446,6 +1447,8 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
       regnum++;
     }

+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* Copy the data.  */
   while (len > 0)
     {
@@ -1460,8 +1463,6 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
-
 	  deprecated_frame_register_read (frame, regnum, buf);
 	  memcpy (buf + offset, myaddr, curr_len);
 	  put_frame_register (frame, regnum, buf);
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index eb87f93058b0287e8f05c585d1b6aa1ff2bffb78..06f8cbb8cc4cd257a626bafac3307a68a1d04855 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -413,9 +413,10 @@ frv_linux_supply_gregset (const struct regset *regset,
 			  int regnum, const void *gregs, size_t len)
 {
   int regi;
-  char zerobuf[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   /* gr0 always contains 0.  Also, the kernel passes the TBR value in
      this slot.  */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..6191593174f605cb0425a735ec02ca4d38969bc8 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 				      int regnum,
 				      struct value *result_value)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);

@@ -3455,7 +3455,7 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index adbe72133089bc371108d5dd79bf8d8e61ba259c..acc43d7e98ac317824f4755ec150794f63af71e4 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -899,7 +899,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = (const gdb_byte *) xsave;
   int i;
   unsigned int clear_bv;
-  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
+  gdb_byte *zero = (gdb_byte *) alloca (max_register_size (gdbarch));
+  memset (zero, 0, max_register_size (gdbarch));
   enum
     {
       none = 0x0,
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 4c53bc6b05a011e4995c94b669b4f11108a12a38..1ead36f2e308b5462dbf84881a671465c2de6e98 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -1227,7 +1227,7 @@ ia64_register_to_value (struct frame_info *frame, int regnum,
 			int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte in[MAX_REGISTER_SIZE];
+  gdb_byte *in = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   /* Convert to TYPE.  */
   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -1245,7 +1245,7 @@ ia64_value_to_register (struct frame_info *frame, int regnum,
                          struct type *valtype, const gdb_byte *in)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte out[MAX_REGISTER_SIZE];
+  gdb_byte *out = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   convert_typed_floating (in, valtype, out, ia64_ext_type (gdbarch));
   put_frame_register (frame, regnum, out);
 }
@@ -1453,6 +1453,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 	}
     }

+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch, sp_regnum));
+
   /* Loop, looking for prologue instructions, keeping track of
      where preserved registers were spilled.  */
   while (pc < lim_pc)
@@ -1516,7 +1519,6 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 	  else if (qp == 0 && rN == 2
 	        && ((rM == fp_reg && fp_reg != 0) || rM == 12))
 	    {
-	      gdb_byte buf[MAX_REGISTER_SIZE];
 	      CORE_ADDR saved_sp = 0;
 	      /* adds r2, spilloffset, rFramePointer
 	           or
@@ -1532,10 +1534,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 		 this'll be wrong.  FIXME */
 	      if (this_frame)
 		{
-		  struct gdbarch *gdbarch = get_frame_arch (this_frame);
 		  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-		  get_frame_register (this_frame, sp_regnum, buf);
-		  saved_sp = extract_unsigned_integer (buf, 8, byte_order);
+		  get_frame_register (this_frame, sp_regnum, regval);
+		  saved_sp = extract_unsigned_integer (regval, 8, byte_order);
 		}
 	      spill_addr  = saved_sp
 	                  + (rM == 12 ? 0 : mem_stack_frame_size)
@@ -2289,8 +2290,6 @@ static struct value *
 ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
 				   void **this_cache, int regnum)
 {
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct ia64_frame_cache *cache =
@@ -2305,6 +2304,7 @@ ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
     {
       CORE_ADDR pc = 0;
       CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));

       if (addr != 0)
 	{
@@ -2495,8 +2495,8 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   long new_sof, old_sof;
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);

@@ -2575,8 +2575,8 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum,
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   long new_sof, old_sof;
-  gdb_byte buf[MAX_REGISTER_SIZE];
-
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);

@@ -2982,7 +2982,8 @@ ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
 	{
 	  int rrb_pr = 0;
 	  ULONGEST cfm;
-	  gdb_byte buf[MAX_REGISTER_SIZE];
+	  gdb_byte *buf
+	    = (gdb_byte *) alloca (register_size (gdbarch, IA64_CFM_REGNUM));

 	  /* Fetch predicate register rename base from current frame
 	     marker for this frame.  */
@@ -3229,9 +3230,9 @@ ia64_extract_return_value (struct type *type, struct regcache *regcache,
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      gdb_byte from[MAX_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
+      gdb_byte *from = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);

       while (n-- > 0)
@@ -3294,9 +3295,9 @@ ia64_store_return_value (struct type *type, struct regcache *regcache,
   float_elt_type = is_float_or_hfa_type (type);
   if (float_elt_type != NULL)
     {
-      gdb_byte to[MAX_REGISTER_SIZE];
       int offset = 0;
       int regnum = IA64_FR8_REGNUM;
+      gdb_byte *to = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);

       while (n-- > 0)
@@ -3854,9 +3855,9 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	{
 	  argoffset = 0;
 	  len = TYPE_LENGTH (type);
+	  gdb_byte *to = (gdb_byte *) alloca (max_register_size (gdbarch));
 	  while (len > 0 && floatreg < IA64_FR16_REGNUM)
 	    {
-	      gdb_byte to[MAX_REGISTER_SIZE];
 	      convert_typed_floating (value_contents (arg) + argoffset,
 				      float_elt_type, to,
 				      ia64_ext_type (gdbarch));
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index 40f29d343b91f254cce2dd783553795c9c990eff..108d67ddfae0b445e41c6e0ae0a143da8f3b15ac 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -677,7 +677,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   enum type_code typecode;
   CORE_ADDR regval;
   gdb_byte *val;
-  gdb_byte valbuf[MAX_REGISTER_SIZE];
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));
   int len;

   /* First force sp to a 4-byte alignment.  */
@@ -707,7 +707,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       typecode = TYPE_CODE (type);
       len = TYPE_LENGTH (type);

-      memset (valbuf, 0, sizeof (valbuf));
+      memset (valbuf, 0, max_register_size (gdbarch));

       /* Passes structures that do not fit in 2 registers by reference.  */
       if (len > 8
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 6944c74eb198381135fda3ddf01b9da3a63e62d5..09bfaaa9972054b9982eed20235c21467709b25d 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   long regaddr, val;
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
   int tid;

   /* Overload thread id onto process id.  */
@@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
   long regaddr, val;
   int i;
   int tid;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   /* Overload thread id onto process id.  */
   tid = ptid_get_lwp (inferior_ptid);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..2f63d4310e6fda872ea35a0e366111b58198b459 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
 		    struct regcache *this_regs)
 {
   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
-  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
-  gdb_byte this_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *prev_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
+  gdb_byte *this_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
   enum register_status prev_status;
   enum register_status this_status;

diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index 00fae0ec60ddc9e645d3236efe29f2f9e9ceab5c..3ec9a503aa52d4aa3546cd32af3913eadc62d919 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -63,7 +63,7 @@ mips_fbsd_supply_reg (struct regcache *regcache, int regnum, const void *addr,
   else
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       LONGEST val;

       val = extract_signed_integer ((const gdb_byte *) addr, len, byte_order);
@@ -90,7 +90,7 @@ mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr,
   else
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
       LONGEST val;

       regcache_raw_collect (regcache, regnum, buf);
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 57e75b5343e1b927e9fe28dea16759f769cf4506..07da374193bf7c83d1e72a0f9e8ebdf025dc0a2e 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -118,7 +118,8 @@ supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+
   store_signed_integer (buf, register_size (gdbarch, regnum), byte_order,
 			extract_signed_integer ((const gdb_byte *) addr, 4,
 						byte_order));
@@ -131,12 +132,12 @@ void
 mips_supply_gregset (struct regcache *regcache,
 		     const mips_elf_gregset_t *gregsetp)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
   const mips_elf_greg_t *regp = *gregsetp;
-  char zerobuf[MAX_REGISTER_SIZE];
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = EF_REG0 + 1; regi <= EF_REG31; regi++)
     supply_32bit_reg (regcache, regi - EF_REG0, regp + regi);
@@ -245,9 +246,9 @@ mips_supply_fpregset (struct regcache *regcache,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
-  char zerobuf[MAX_REGISTER_SIZE];
+  char *zerobuf = (char *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = 0; regi < 32; regi++)
     regcache_raw_supply (regcache,
@@ -377,12 +378,12 @@ void
 mips64_supply_gregset (struct regcache *regcache,
 		       const mips64_elf_gregset_t *gregsetp)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int regi;
   const mips64_elf_greg_t *regp = *gregsetp;
-  gdb_byte zerobuf[MAX_REGISTER_SIZE];
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  gdb_byte *zerobuf = (gdb_byte *) alloca (max_register_size (gdbarch));

-  memset (zerobuf, 0, MAX_REGISTER_SIZE);
+  memset (zerobuf, 0, max_register_size (gdbarch));

   for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
     supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
@@ -470,7 +471,7 @@ mips64_fill_gregset (const struct regcache *regcache,

   if (regaddr != -1)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
@@ -574,7 +575,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
     }
   else if (regno == mips_regnum (gdbarch)->fp_control_status)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
@@ -585,7 +586,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
     }
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));
       LONGEST val;

       regcache_raw_collect (regcache, regno, buf);
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 637b34edd7c2cf5676b5c359ca1acfe59f0ad6c8..1a427449e053bd9f5a61960bb0eed1b183ca3a2a 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -4523,10 +4523,10 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   /* Now load as many as possible of the first arguments into
      registers, and push the rest onto the stack.  Loop thru args
      from first to last.  */
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argnum = 0; argnum < nargs; argnum++)
     {
       const gdb_byte *val;
-      gdb_byte valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -5757,7 +5757,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      gdb_byte reg[MAX_REGISTER_SIZE];
+      gdb_byte *reg = (gdb_byte *) alloca (max_register_size (gdbarch));
       int regnum;
       int field;
       for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
@@ -6472,7 +6472,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   /* Do values for GP (int) regs.  */
-  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *raw_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
   int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8);    /* display cols
 							       per row.  */
   int col, byte;
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index 8c23f02b2b58b29b10a65df5ae0b4bcdce2925cd..8124d77049b1edfe3003b07cb87b06a4bbeb3c79 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -86,7 +86,9 @@ am33_supply_gregset_method (const struct regset *regset,
 			    struct regcache *regcache,
 			    int regnum, const void *gregs, size_t len)
 {
-  char zerobuf[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regsize = register_size (gdbarch, regnum);
+  char *zerobuf = (char *) alloca (regsize);
   const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
   int i;

@@ -188,15 +190,15 @@ am33_supply_gregset_method (const struct regset *regset,

     /* ssp, msp, and usp are inaccessible.  */
   case E_E8_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
     break;
   case E_E9_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
     break;
   case E_E10_REGNUM:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);

     break;
@@ -218,11 +220,11 @@ am33_supply_gregset_method (const struct regset *regset,
     break;
   case E_FPCR_REGNUM + 1:
     /* The two unused registers beyond fpcr are inaccessible.  */
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
     break;
   case E_FPCR_REGNUM + 2:
-    memset (zerobuf, 0, MAX_REGISTER_SIZE);
+    memset (zerobuf, 0, regsize);
     regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
     break;
   default:	/* An error, obviously, but should we error out?  */
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 5f5d5ca87b811d66da272036a515210cf2f17134..bce8d839f100b0fe851a8f526e521c3b2dda95f3 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -195,7 +195,7 @@ static void
 mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 			      struct regcache *regcache, void *valbuf)
 {
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));
   int len = TYPE_LENGTH (type);
   int reg, regsz;

@@ -1223,7 +1223,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
   int stack_offset = 0;
   int argnum;
   const gdb_byte *val;
-  gdb_byte valbuf[MAX_REGISTER_SIZE];
+  gdb_byte *valbuf = (gdb_byte *) alloca (max_register_size (gdbarch));

   /* This should be a nop, but align the stack just in case something
      went wrong.  Stacks are four byte aligned on the mn10300.  */
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index a56d154d3126c69431eff0717d6b4bcbe15f9d96..d9d0ad561f1b6b49324c9f516af1b732efad10b7 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -496,7 +496,7 @@ fetch_register (struct regcache *regcache, int tid, int regno)
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int bytes_transferred;
   unsigned int offset;         /* Offset of registers within the u area.  */
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   if (altivec_register_p (gdbarch, regno))
     {
@@ -983,7 +983,7 @@ store_register (const struct regcache *regcache, int tid, int regno)
   CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
   int i;
   size_t bytes_to_transfer;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, regno));

   if (altivec_register_p (gdbarch, regno))
     {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index ecae6363e3ae0a388bc5294aade5590c4b432d18..69401ea539cb3b97914eb9dc744b6d73b0c46913 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -69,6 +69,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   ULONGEST saved_sp;
   int argspace = 0;		/* 0 is an initial wrong guess.  */
   int write_pass;
+  gdb_byte *regval = (gdb_byte *) alloca (max_register_size (gdbarch));

   gdb_assert (tdep->wordsize == 4);

@@ -134,7 +135,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		    {
 		      /* Always store the floating point value using
 		         the register's floating-point format.  */
-		      gdb_byte regval[MAX_REGISTER_SIZE];
 		      struct type *regtype
 			= register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
 		      convert_typed_floating (val, type, regval, regtype);
@@ -278,7 +278,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		{
 		  if (write_pass)
 		    {
-		      gdb_byte regval[MAX_REGISTER_SIZE];
 		      const gdb_byte *p;

 		      /* 32-bit decimal floats are right aligned in the
@@ -364,7 +363,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 			  if (write_pass)
 			    {
 			      int regnum = tdep->ppc_fp0_regnum + freg;
-			      gdb_byte regval[MAX_REGISTER_SIZE];
 			      struct type *regtype
 				= register_type (gdbarch, regnum);
 			      convert_typed_floating (elval, eltype,
@@ -411,8 +409,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		    }
 		  else
 		    {
-		      gdb_byte word[MAX_REGISTER_SIZE];
-		      store_unsigned_integer (word, tdep->wordsize, byte_order,
+		      store_unsigned_integer (regval, tdep->wordsize, byte_order,
 					      unpack_long (eltype, elval));

 		      if (greg <= 10)
@@ -420,14 +417,14 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 			  if (write_pass)
 			    regcache_cooked_write (regcache,
 						   tdep->ppc_gp0_regnum + greg,
-						   word);
+						   regval);
 			  greg++;
 			}
 		      else
 			{
 			  argoffset = align_up (argoffset, tdep->wordsize);
 			  if (write_pass)
-			    write_memory (sp + argoffset, word, tdep->wordsize);
+			    write_memory (sp + argoffset, regval, tdep->wordsize);
 			  argoffset += tdep->wordsize;
 			}
 		    }
@@ -516,8 +513,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	    {
 	      /* Reduce the parameter down to something that fits in a
 	         "word".  */
-	      gdb_byte word[MAX_REGISTER_SIZE];
-	      memset (word, 0, MAX_REGISTER_SIZE);
+	      memset (regval, 0, max_register_size (gdbarch));
 	      if (len > tdep->wordsize
 		  || TYPE_CODE (type) == TYPE_CODE_STRUCT
 		  || TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -535,31 +531,31 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		    write_memory (sp + structoffset, val, len);
 		  /* ... and then a "word" pointing to that address is
 		     passed as the parameter.  */
-		  store_unsigned_integer (word, tdep->wordsize, byte_order,
+		  store_unsigned_integer (regval, tdep->wordsize, byte_order,
 					  sp + structoffset);
 		  structoffset += len;
 		}
 	      else if (TYPE_CODE (type) == TYPE_CODE_INT)
 		/* Sign or zero extend the "int" into a "word".  */
-		store_unsigned_integer (word, tdep->wordsize, byte_order,
+		store_unsigned_integer (regval, tdep->wordsize, byte_order,
 					unpack_long (type, val));
 	      else
 		/* Always goes in the low address.  */
-		memcpy (word, val, len);
+		memcpy (regval, val, len);
 	      /* Store that "word" in a register, or on the stack.
 	         The words have "4" byte alignment.  */
 	      if (greg <= 10)
 		{
 		  if (write_pass)
 		    regcache_cooked_write (regcache,
-					   tdep->ppc_gp0_regnum + greg, word);
+					   tdep->ppc_gp0_regnum + greg, regval);
 		  greg++;
 		}
 	      else
 		{
 		  argoffset = align_up (argoffset, tdep->wordsize);
 		  if (write_pass)
-		    write_memory (sp + argoffset, word, tdep->wordsize);
+		    write_memory (sp + argoffset, regval, tdep->wordsize);
 		  argoffset += tdep->wordsize;
 		}
 	    }
@@ -621,9 +617,11 @@ get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
   /* 32-bit and 64-bit decimal floats in f1.  */
   if (TYPE_LENGTH (valtype) <= 8)
     {
+      int regnum = tdep->ppc_fp0_regnum + 1;
       if (writebuf != NULL)
 	{
-	  gdb_byte regval[MAX_REGISTER_SIZE];
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));
 	  const gdb_byte *p;

 	  /* 32-bit decimal float is right aligned in the doubleword.  */
@@ -635,11 +633,11 @@ get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype,
 	  else
 	    p = writebuf;

-	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p);
+	  regcache_cooked_write (regcache, regnum, p);
 	}
       if (readbuf != NULL)
 	{
-	  regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf);
+	  regcache_cooked_read (regcache, regnum, readbuf);

 	  /* Left align 32-bit decimal float.  */
 	  if (TYPE_LENGTH (valtype) == 4)
@@ -695,6 +693,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int opencl_abi = func_type? ppc_sysv_use_opencl_abi (func_type) : 0;
+  gdb_byte *regval = (gdb_byte *) alloca (max_register_size (gdbarch));

   gdb_assert (tdep->wordsize == 4);

@@ -706,7 +705,6 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	{
 	  /* Floats and doubles stored in "f1".  Convert the value to
 	     the required type.  */
-	  gdb_byte regval[MAX_REGISTER_SIZE];
 	  struct type *regtype = register_type (gdbarch,
                                                 tdep->ppc_fp0_regnum + 1);
 	  regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
@@ -716,7 +714,6 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	{
 	  /* Floats and doubles stored in "f1".  Convert the value to
 	     the register's "double" type.  */
-	  gdb_byte regval[MAX_REGISTER_SIZE];
 	  struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
 	  convert_typed_floating (writebuf, type, regval, regtype);
 	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
@@ -847,7 +844,6 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  if (TYPE_CODE (eltype) == TYPE_CODE_FLT)
 	    {
 	      int regnum = tdep->ppc_fp0_regnum + 1 + i;
-	      gdb_byte regval[MAX_REGISTER_SIZE];
 	      struct type *regtype = register_type (gdbarch, regnum);

 	      if (writebuf != NULL)
@@ -972,12 +968,14 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	regcache_cooked_write (regcache, tdep->ppc_ev0_regnum + 3, writebuf);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
+
+  gdb_byte *regvals = (gdb_byte *) alloca (max_register_size (gdbarch) * 2);
+
   if (broken_gcc && TYPE_LENGTH (type) <= 8)
     {
       /* GCC screwed up for structures or unions whose size is less
 	 than or equal to 8 bytes..  Instead of left-aligning, it
 	 right-aligns the data into the buffer formed by r3, r4.  */
-      gdb_byte regvals[MAX_REGISTER_SIZE * 2];
       int len = TYPE_LENGTH (type);
       int offset = (2 * tdep->wordsize - len) % tdep->wordsize;

@@ -992,7 +990,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	}
       if (writebuf)
 	{
-	  memset (regvals, 0, sizeof regvals);
+	  memset (regvals, 0, max_register_size (gdbarch) * 2);
 	  memcpy (regvals + offset, writebuf, len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
 				 regvals + 0 * tdep->wordsize);
@@ -1010,7 +1008,6 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  /* This matches SVr4 PPC, it does not match GCC.  */
 	  /* The value is right-padded to 8 bytes and then loaded, as
 	     two "words", into r3/r4.  */
-	  gdb_byte regvals[MAX_REGISTER_SIZE * 2];
 	  regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
 				regvals + 0 * tdep->wordsize);
 	  if (TYPE_LENGTH (type) > tdep->wordsize)
@@ -1023,8 +1020,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	  /* This matches SVr4 PPC, it does not match GCC.  */
 	  /* The value is padded out to 8 bytes and then loaded, as
 	     two "words" into r3/r4.  */
-	  gdb_byte regvals[MAX_REGISTER_SIZE * 2];
-	  memset (regvals, 0, sizeof regvals);
+	  memset (regvals, 0, max_register_size (gdbarch) * 2);
 	  memcpy (regvals, writebuf, TYPE_LENGTH (type));
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
 				 regvals + 0 * tdep->wordsize);
@@ -1340,7 +1336,7 @@ ppc64_sysv_abi_push_integer (struct gdbarch *gdbarch, ULONGEST val,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte *buf = (gdb_byte *) alloca (max_register_size (gdbarch));

   if (argpos->regcache)
     store_unsigned_integer (buf, tdep->wordsize, byte_order, val);
@@ -1369,7 +1365,8 @@ ppc64_sysv_abi_push_freg (struct gdbarch *gdbarch,
 	{
 	  int regnum = tdep->ppc_fp0_regnum + argpos->freg;
 	  struct type *regtype = register_type (gdbarch, regnum);
-	  gdb_byte regval[MAX_REGISTER_SIZE];
+	  gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch,
+								 regnum));

 	  convert_typed_floating (val, type, regval, regtype);
 	  regcache_cooked_write (argpos->regcache, regnum, regval);
@@ -1814,7 +1811,7 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
     {
       int regnum = tdep->ppc_fp0_regnum + 1 + index;
       struct type *regtype = register_type (gdbarch, regnum);
-      gdb_byte regval[MAX_REGISTER_SIZE];
+      gdb_byte *regval = (gdb_byte *) alloca (register_size (gdbarch, regnum));

       if (writebuf != NULL)
 	{
@@ -2069,10 +2066,10 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
       int n_regs = ((TYPE_LENGTH (valtype) + tdep->wordsize - 1)
 		    / tdep->wordsize);
       int i;
+      gdb_byte *regval = (gdb_byte *) alloca (max_register_size (gdbarch));

       for (i = 0; i < n_regs; i++)
 	{
-	  gdb_byte regval[MAX_REGISTER_SIZE];
 	  int regnum = tdep->ppc_gp0_regnum + 3 + i;
 	  int offset = i * tdep->wordsize;
 	  int len = TYPE_LENGTH (valtype) - offset;
@@ -2082,7 +2079,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,

 	  if (writebuf != NULL)
 	    {
-	      memset (regval, 0, sizeof regval);
+	      memset (regval, 0, register_size (gdbarch, regnum));
 	      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
 		  && offset == 0)
 		memcpy (regval + tdep->wordsize - len, writebuf, len);
diff --git a/gdb/record-full.c b/gdb/record-full.c
index fdd613b6e41bbfcd8644b02ccfeb98b53b518bff..c634de5edc73572aee52517c13e205039e1f9dd0 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -698,7 +698,8 @@ record_full_exec_insn (struct regcache *regcache,
     {
     case record_full_reg: /* reg */
       {
-        gdb_byte reg[MAX_REGISTER_SIZE];
+	gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch,
+							    entry->u.reg.num));

         if (record_debug > 1)
           fprintf_unfiltered (gdb_stdlog,
@@ -792,15 +793,17 @@ static void
 record_full_core_open_1 (const char *name, int from_tty)
 {
   struct regcache *regcache = get_current_regcache ();
-  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regnum = gdbarch_num_regs (gdbarch);
+  int regmaxsize = max_register_size (gdbarch);
   int i;

   /* Get record_full_core_regbuf.  */
   target_fetch_registers (regcache, -1);
-  record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum);
+  record_full_core_regbuf = (gdb_byte *) xmalloc (regmaxsize * regnum);
   for (i = 0; i < regnum; i ++)
     regcache_raw_collect (regcache, i,
-			  record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			  record_full_core_regbuf + regmaxsize * i);

   /* Get record_full_core_start and record_full_core_end.  */
   if (build_section_table (core_bfd, &record_full_core_start,
@@ -2038,6 +2041,9 @@ record_full_core_fetch_registers (struct target_ops *ops,
 				  struct regcache *regcache,
 				  int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (regno < 0)
     {
       int num = gdbarch_num_regs (get_regcache_arch (regcache));
@@ -2045,11 +2051,11 @@ record_full_core_fetch_registers (struct target_ops *ops,

       for (i = 0; i < num; i ++)
         regcache_raw_supply (regcache, i,
-                             record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			     record_full_core_regbuf + regmaxsize * i);
     }
   else
     regcache_raw_supply (regcache, regno,
-                         record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			 record_full_core_regbuf + regmaxsize * regno);
 }

 /* "to_prepare_to_store" method for prec over corefile.  */
@@ -2067,9 +2073,12 @@ record_full_core_store_registers (struct target_ops *ops,
                              struct regcache *regcache,
                              int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (record_full_gdb_operation_disable)
     regcache_raw_collect (regcache, regno,
-                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			  record_full_core_regbuf + regmaxsize * regno);
   else
     error (_("You can't do that without a process to debug."));
 }
@@ -2265,7 +2274,7 @@ init_record_full_core_ops (void)
      record_full_reg:
        1 byte:  record type (record_full_reg, see enum record_full_type).
        8 bytes: register id (network byte order).
-       MAX_REGISTER_SIZE bytes: register value.
+       max_register_size bytes: register value.
      record_full_mem:
        1 byte:  record type (record_full_mem, see enum record_full_type).
        8 bytes: memory length (network byte order).
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index b0c68c617e365c0ea18ac2eca525598b688ffbb5..7402f3b11ab13ea1ada51b66125d5c5750209c62 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -439,6 +439,9 @@ gdbsim_fetch_register (struct target_ops *ops,
       return;
     }

+  int regsize = register_size (gdbarch, regno);
+  gdb_byte *buf = (gdb_byte *) alloca (regsize);
+
   switch (gdbarch_register_sim_regno (gdbarch, regno))
     {
     case LEGACY_SIM_REGNO_IGNORE:
@@ -447,10 +450,9 @@ gdbsim_fetch_register (struct target_ops *ops,
       {
 	/* For moment treat a `does not exist' register the same way
 	   as an ``unavailable'' register.  */
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	regcache_raw_supply (regcache, regno, buf);
 	break;
       }
@@ -458,18 +460,17 @@ gdbsim_fetch_register (struct target_ops *ops,
     default:
       {
 	static int warn_user = 1;
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

 	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
 				       gdbarch_register_sim_regno
 					 (gdbarch, regno),
 				       buf,
-				       register_size (gdbarch, regno));
+				       regsize);
 	if (nr_bytes > 0
-	    && nr_bytes != register_size (gdbarch, regno) && warn_user)
+	    && nr_bytes != regsize && warn_user)
 	  {
 	    fprintf_unfiltered (gdb_stderr,
 				"Size of register %s (%d/%d) "
@@ -478,7 +479,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 				regno,
 				gdbarch_register_sim_regno
 				  (gdbarch, regno),
-				nr_bytes, register_size (gdbarch, regno));
+				nr_bytes, regsize);
 	    warn_user = 0;
 	  }
 	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
@@ -492,7 +493,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 	    fprintf_unfiltered (gdb_stdlog,
 				"gdbsim_fetch_register: %d", regno);
 	    /* FIXME: We could print something more intelligible.  */
-	    dump_mem (buf, register_size (gdbarch, regno));
+	    dump_mem (buf, regsize);
 	  }
 	break;
       }
@@ -516,15 +517,16 @@ gdbsim_store_register (struct target_ops *ops,
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
     {
-      gdb_byte tmp[MAX_REGISTER_SIZE];
+      int regsize = register_size (gdbarch, regno);
+      gdb_byte *tmp = (gdb_byte *) alloca (regsize);
       int nr_bytes;

       regcache_cooked_read (regcache, regno, tmp);
       nr_bytes = sim_store_register (sim_data->gdbsim_desc,
 				     gdbarch_register_sim_regno
 				       (gdbarch, regno),
-				     tmp, register_size (gdbarch, regno));
-      if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno))
+				     tmp, regsize);
+      if (nr_bytes > 0 && nr_bytes != regsize)
 	internal_error (__FILE__, __LINE__,
 			_("Register size different to expected"));
       if (nr_bytes < 0)
@@ -538,7 +540,7 @@ gdbsim_store_register (struct target_ops *ops,
 	{
 	  fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno);
 	  /* FIXME: We could print something more intelligible.  */
-	  dump_mem (tmp, register_size (gdbarch, regno));
+	  dump_mem (tmp, regsize);
 	}
     }
 }
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 9841a60eafb0381cd2343dd3a8d5745571f5460e..eefd0d6a15f7a64eaa4bf10a72bde80a35646ac9 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -236,6 +236,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    User may have to cast\args to handle promotion correctly
    since gdb won't know if prototype supplied or not.  */

+  gdb_byte *word = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
       int reg_size = register_size (gdbarch, ii + 3);
@@ -253,14 +254,12 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	     Always store the floating point value using the register's
 	     floating-point format.  */
 	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
-	  gdb_byte reg_val[MAX_REGISTER_SIZE];
 	  struct type *reg_type = register_type (gdbarch, fp_regnum);

 	  gdb_assert (len <= 8);

-	  convert_typed_floating (value_contents (arg), type,
-				  reg_val, reg_type);
-	  regcache_cooked_write (regcache, fp_regnum, reg_val);
+	  convert_typed_floating (value_contents (arg), type, word, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, word);
 	  ++f_argno;
 	}

@@ -270,7 +269,6 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	  /* Argument takes more than one register.  */
 	  while (argbytes < len)
 	    {
-	      gdb_byte word[MAX_REGISTER_SIZE];
 	      memset (word, 0, reg_size);
 	      memcpy (word,
 		      ((char *) value_contents (arg)) + argbytes,
@@ -290,8 +288,6 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
 	{
 	  /* Argument can fit in one register.  No problem.  */
-	  gdb_byte word[MAX_REGISTER_SIZE];
-
 	  memset (word, 0, reg_size);
 	  memcpy (word, value_contents (arg), len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word);
diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c
index f2aa1f8448cf487b1522df89ef42a3937799d95f..3c8557a2893e403d802809223ea40a5eac51afa9 100644
--- a/gdb/rs6000-lynx178-tdep.c
+++ b/gdb/rs6000-lynx178-tdep.c
@@ -87,6 +87,7 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
      User may have to cast\args to handle promotion correctly
      since gdb won't know if prototype supplied or not.  */

+  gdb_byte *word = (gdb_byte *) alloca (max_register_size (gdbarch));
   for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
     {
       int reg_size = register_size (gdbarch, ii + 3);
@@ -105,24 +106,20 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
 	     Always store the floating point value using the register's
 	     floating-point format.  */
 	  const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno;
-	  gdb_byte reg_val[MAX_REGISTER_SIZE];
 	  struct type *reg_type = register_type (gdbarch, fp_regnum);

 	  gdb_assert (len <= 8);

-	  convert_typed_floating (value_contents (arg), type,
-				  reg_val, reg_type);
-	  regcache_cooked_write (regcache, fp_regnum, reg_val);
+	  convert_typed_floating (value_contents (arg), type, word, reg_type);
+	  regcache_cooked_write (regcache, fp_regnum, word);
 	  ++f_argno;
 	}

       if (len > reg_size)
 	{
-
 	  /* Argument takes more than one register.  */
 	  while (argbytes < len)
 	    {
-	      gdb_byte word[MAX_REGISTER_SIZE];
 	      memset (word, 0, reg_size);
 	      memcpy (word,
 		      ((char *) value_contents (arg)) + argbytes,
@@ -142,8 +139,6 @@ rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch,
       else
 	{
 	  /* Argument can fit in one register.  No problem.  */
-	  gdb_byte word[MAX_REGISTER_SIZE];
-
 	  memset (word, 0, reg_size);
 	  memcpy (word, value_contents (arg), len);
 	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word);
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index f42847bfeab8ad6d03c96a161238283a262f98d1..6f322ed465ee40f06fe35967104fc0c90fb88661 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -162,7 +162,7 @@ static void
 fetch_register (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int addr[MAX_REGISTER_SIZE];
+  int *addr = (int *) alloca (register_size (gdbarch, regno) * sizeof (int));
   int nr, isfloat;

   /* Retrieved values may be -1, so infer errors from errno.  */
@@ -222,7 +222,7 @@ static void
 store_register (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int addr[MAX_REGISTER_SIZE];
+  int *addr = (int *) alloca (register_size (gdbarch, regno) * sizeof (int));
   int nr, isfloat;

   /* Fetch the register's value from the register cache.  */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 527f643b7be833b4bf7a2386940f9764f8b81514..52bf957dd422deb41248dd8bb696dd0aae74c142 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2590,8 +2590,7 @@ rs6000_register_to_value (struct frame_info *frame,
 			  int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte from[MAX_REGISTER_SIZE];
-
+  gdb_byte *from = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

   if (!get_frame_register_bytes (frame, regnum, 0,
@@ -2612,7 +2611,7 @@ rs6000_value_to_register (struct frame_info *frame,
                           const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte to[MAX_REGISTER_SIZE];
+  gdb_byte *to = (gdb_byte *) alloca (register_size (gdbarch, regnum));

   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 9b3692dc0c32ffcb53d99f0fc095303d2c221fcb..ac59bdc051c5ce524b70af6d5d3b2942dffc2f1c 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1648,7 +1648,6 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 			 int reg_nr, gdb_byte *buffer)
 {
   int base_regnum;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
   enum register_status status;

   if (reg_nr == PSEUDO_BANK_REGNUM)
@@ -1656,6 +1655,8 @@ sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
       base_regnum = dr_reg_base_num (gdbarch, reg_nr);
+      gdb_byte *temp_buffer
+	= (gdb_byte *) alloca (register_size (gdbarch, base_regnum));

       /* Build the value in the provided buffer.  */
       /* Read the real regs for which this one is an alias.  */
@@ -1687,7 +1688,6 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			  int reg_nr, const gdb_byte *buffer)
 {
   int base_regnum, portion;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];

   if (reg_nr == PSEUDO_BANK_REGNUM)
     {
@@ -1704,6 +1704,8 @@ sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
     {
       base_regnum = dr_reg_base_num (gdbarch, reg_nr);
+      gdb_byte *temp_buffer
+	= (gdb_byte *) alloca (register_size (gdbarch, base_regnum));

       /* We must pay attention to the endiannes.  */
       sh_register_convert_to_raw (gdbarch, register_type (gdbarch, reg_nr),
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 23f5ade3b2e631eeb50cb918a4f36bb8cfbe6131..9e77bb9597354541a7fc5f7c92149074f5dce719 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1528,7 +1528,8 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum;
   int offset = 0;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *temp_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));
+
   enum register_status status;

   if (reg_nr >= DR0_REGNUM
@@ -1704,7 +1705,7 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int base_regnum, portion;
   int offset;
-  gdb_byte temp_buffer[MAX_REGISTER_SIZE];
+  gdb_byte *temp_buffer = (gdb_byte *) alloca (max_register_size (gdbarch));

   if (reg_nr >= DR0_REGNUM
       && reg_nr <= DR_LAST_REGNUM)
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index a09a3ab9a8bc56f367e3ba1537f5674f0a7f491f..4ac95ad5f726e57e5d7a9d2696fef33bbc52473d 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -514,6 +514,7 @@ sol_thread_store_registers (struct target_ops *ops,
   td_err_e val;
   prgregset_t gregset;
   prfpregset_t fpregset;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);

   if (!ptid_tid_p (inferior_ptid))
     {
@@ -535,7 +536,7 @@ sol_thread_store_registers (struct target_ops *ops,
   if (regnum != -1)
     {
       /* Not writing all the registers.  */
-      char old_value[MAX_REGISTER_SIZE];
+      char *old_value = (char *) alloca (register_size (gdbarch, regnum));

       /* Save new register value.  */
       regcache_raw_collect (regcache, regnum, old_value);
diff --git a/gdb/stack.c b/gdb/stack.c
index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..b76b2f540de3dce23dcb29a56280295790a7a533 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1667,7 +1667,7 @@ frame_info (char *addr_exp, int from_tty)
 	  {
 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
-	    gdb_byte value[MAX_REGISTER_SIZE];
+	    gdb_byte *value = (gdb_byte *) alloca (sp_size);
 	    CORE_ADDR sp;

 	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
diff --git a/gdb/target.c b/gdb/target.c
index 3c409f0f619141205dfdcbbf8e46a277585ed683..0c7af9948667242b3ef61c1c4620d8929b27a336 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3565,7 +3565,7 @@ debug_print_register (const char * func,
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       int i, size = register_size (gdbarch, regno);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      gdb_byte *buf = (gdb_byte *) alloca (size);

       regcache_raw_collect (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 978b13abc57a404974fc02dfd868977b3dab0290..d2e97f86705d13975e5db8d981acab1002cfd567 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -370,7 +370,10 @@ static void
 xtensa_register_write_masked (struct regcache *regcache,
 			      xtensa_register_t *reg, const gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
+						 + 1);
+
   const xtensa_mask_t *mask = reg->mask;

   int shift = 0;		/* Shift for next mask (mod 32).  */
@@ -454,7 +457,9 @@ static enum register_status
 xtensa_register_read_masked (struct regcache *regcache,
 			     xtensa_register_t *reg, gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
+						 + 1);
   const xtensa_mask_t *mask = reg->mask;

   int shift = 0;
@@ -559,12 +564,11 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
       && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+      int wb_regnum = gdbarch_tdep (gdbarch)->wb_regnum;
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, wb_regnum));
       enum register_status status;

-      status = regcache_raw_read (regcache,
-				  gdbarch_tdep (gdbarch)->wb_regnum,
-				  buf);
+      status = regcache_raw_read (regcache, wb_regnum, buf);
       if (status != REG_VALID)
 	return status;
       regnum = arreg_number (gdbarch, regnum,
@@ -655,10 +659,10 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
       && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+      int wb_regnum = gdbarch_tdep (gdbarch)->wb_regnum;
+      gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, wb_regnum));

-      regcache_raw_read (regcache,
-			 gdbarch_tdep (gdbarch)->wb_regnum, buf);
+      regcache_raw_read (regcache, wb_regnum, buf);
       regnum = arreg_number (gdbarch, regnum,
 			     extract_unsigned_integer (buf, 4, byte_order));
     }




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-01-27 12:11 ` Pedro Alves
  2017-01-27 16:46   ` Alan Hayward
@ 2017-02-01 12:45   ` Yao Qi
  2017-02-01 15:48     ` Pedro Alves
  1 sibling, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-01 12:45 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Alan Hayward, gdb-patches

On 17-01-27 12:11:09, Pedro Alves wrote:
> 
> Makes me wonder whether this is the right approach.  :-/
> (No, I don't have a formed opinion for what that would be.)
> 

Hi Pedro,
What do you mean by "this" here?  We can't take MAX_REGISTER_SIZE for
ever, as we may have bigger and bigger single register.  We do need a
gdbarch specific max register size.  Given there is no standard VLA in
C++, using alloca is the best way we can do so far.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-01 12:45   ` Yao Qi
@ 2017-02-01 15:48     ` Pedro Alves
  2017-02-02  9:40       ` Joel Brobecker
  0 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2017-02-01 15:48 UTC (permalink / raw)
  To: Yao Qi; +Cc: Alan Hayward, gdb-patches

On 02/01/2017 12:41 PM, Yao Qi wrote:
> On 17-01-27 12:11:09, Pedro Alves wrote:
>>
>> Makes me wonder whether this is the right approach.  :-/
>> (No, I don't have a formed opinion for what that would be.)
>>
> 
> Hi Pedro,
> What do you mean by "this" here?  We can't take MAX_REGISTER_SIZE for
> ever, as we may have bigger and bigger single register.  We do need a
> gdbarch specific max register size.  Given there is no standard VLA in
> C++, using alloca is the best way we can do so far.
> 

I meant "alloca".  And having to worry about loops.  Along with other
oddities that come with alloca, like alloca(-1), the most common type
of bad huge allocation (I think), crashing gdb vs
xmalloc/new -> malloc_failure causing a recoverable internal
error, for example.

Some options I was pondering:

#1 - Use VLAs anyway.

I.e., assume we can only build with C++ compilers that support VLAs as extension.
GCC does, clang does, Intel's does I believe.  ARM's probably does too?
I don't know whether there's actually any C++ compiler that does not.
Maybe MSVC, though I don't know of anyone trying to build GDB with that.
Though arguably, we shouldn't close the door on "standard" compilers like that.

#2 - Switch to heap allocation

Or std::vector or something like that that hides it.  It's not clear whether
that would have a noticeable performance impact.

#3 - Use alloca, move inner loop bodies to functions/lambdas

I.e., avoid having to put the allocas before the loops by moving the body
of loops to separate functions, or to lambdas (effectively
the same), like:

 void
 function ()
 {
   for (int regnum = 0; regnum < allregisters; regnum++)
     {
       [&] {
 	char *buf = (char *) alloca (register_size (gdbarch, regnum));
 
        /// do something with buf.
       } ();
     }
 }

though that may end up looking a bit ... odd if you're not too
familiar with alloca and lambdas.  It also has the problem that
a "return" inside that scope doesn't do what one would expect
if the lambda wasn't there (more on that below).

#4 - Like above, but wrap in macros.

I.e., make #3 a bit more explicit and to the point, by wrapping
the lambda syntax with a couple macros.  Like:

#define ALLOCA_SCOPE_START [&] ()
#define ALLOCA_SCOPE_END ();

void
function ()
{
  for (int regnum = 0; regnum < allregisters; regnum++)
    {
      ALLOCA_SCOPE_START
        {
          char *buf = (char *) alloca (register_size (gdbarch, regnum));

          // do something
        }
      ALLOCA_SCOPE_END
     }
 }

#5 - Like above, but fix the "return" issue too.

It's doable, but it'll require a bit more "magic".  See attached patch.
I picked a few random examples of cases where alloca was being moved
to outside a loops in Alan's patch, and converted them (against master).

I've never seen anyone do something like this.  I just thought of it
now, tried it, and it works (tried g++ 4.8 / 5.3 / 7)...

The main advantages of something like ALLOCA_SCOPE_START/ALLOCA_SCOPE_END
would be:

- ALLOCA_SCOPE_START/ALLOCA_SCOPE_END stand out, which in case of alloca
  is probably a good thing.
- Allows keeping the alloca buffer allocation closer to where it is used.

Disadvantages:

- Might not be up to everyone's taste?

From ce55d77461a5fa429cea8837b09679b301fa9b40 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Wed, 1 Feb 2017 15:41:14 +0000
Subject: [PATCH] Introduce and use ALLOCA_SCOPE_START / ALLOCA_SCOPE_END

Allows using alloca in loops.
---
 gdb/aarch64-tdep.c        | 25 ++++++++-----
 gdb/common/alloca-scope.h | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/common/common-defs.h  |  3 ++
 gdb/frame.c               | 21 ++++++++---
 gdb/ia64-tdep.c           | 15 ++++++--
 5 files changed, 136 insertions(+), 17 deletions(-)
 create mode 100644 gdb/common/alloca-scope.h

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 801c03d..accfadb 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -62,6 +62,7 @@
 
 #include "opcode/aarch64.h"
 #include <algorithm>
+#include "alloca-scope.h"
 
 #define submask(x) ((1L << ((x) + 1)) - 1)
 #define bit(obj,st) (((obj) >> (st)) & 1)
@@ -1982,18 +1983,24 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
       for (i = 0; i < elements; i++)
 	{
 	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte tmpbuf[MAX_REGISTER_SIZE];
 
-	  if (aarch64_debug)
+	  ALLOCA_SCOPE_START
 	    {
-	      debug_printf ("write HFA or HVA return value element %d to %s\n",
-			    i + 1,
-			    gdbarch_register_name (gdbarch, regno));
-	    }
+	      bfd_byte *tmpbuf
+		= (bfd_byte *) alloca (register_size (gdbarch, regno));
 
-	  memcpy (tmpbuf, valbuf, len);
-	  regcache_cooked_write (regs, regno, tmpbuf);
-	  valbuf += len;
+	      if (aarch64_debug)
+		{
+		  debug_printf ("write HFA or HVA return value element %d to %s\n",
+				i + 1,
+				gdbarch_register_name (gdbarch, regno));
+		}
+
+	      memcpy (tmpbuf, valbuf, len);
+	      regcache_cooked_write (regs, regno, tmpbuf);
+	      valbuf += len;
+	    }
+	  ALLOCA_SCOPE_END
 	}
     }
   else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
diff --git a/gdb/common/alloca-scope.h b/gdb/common/alloca-scope.h
new file mode 100644
index 0000000..311257c
--- /dev/null
+++ b/gdb/common/alloca-scope.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+/* Stack allocated with "alloca" is released on function exit, not
+   scope exit.  This makes it dangerous to use alloca in loops.  To
+   work around that, create an alloca scope using the
+   ALLOCA_SCOPE_START and ALLOCA_SCOPE_END macros like this:
+
+   for (...)
+     {
+       ALLOCA_SCOPE_START
+         {
+	    gdb_byte *buf = (gdb_byte *) alloca (some size);
+
+	    // use BUF
+	 }
+       ALLOCA_SCOPE_END
+     }
+
+   ALLOCA_SCOPE_START / ALLOCA_SCOPE_END define and call a lambda
+   behind the scenes.  Any memory allocated with alloca is thus
+   released when the lambda returns, since the lambda is just an
+   (inline) function.
+
+   Note that it's not possible to "return" directly from within an
+   alloca scope, since that would return from the lambda, instead of
+   from the lambda's caller.  The macros are defined in such a way
+   that return expressions won't even compile, to avoid such mistakes.
+
+   The scope defined by ALLOCA_SCOPE_START/END has access to all the
+   local variables of the containing scope (because the lambda
+   captures all by reference).
+
+   This wrapping has no run time overhead, since the lambda never
+   escapes out of the local, calling scope.
+   __attribute__((always_inline)) also helps a bit, by instructing the
+   compiler that it should inline everything about the lambda,
+   regardless of optimization level.
+*/
+
+#ifndef COMMON_ALLOCA_SCOPE_H
+#define COMMON_ALLOCA_SCOPE_H
+
+#include <alloca.h>
+
+/* A couple types used to prevent trying to "return" from within an
+   ALLOCA_SCOPE lambda.  */
+
+struct alloca_scopes_cannot_return_empty_base {};
+
+/* Inheriting from an empty class prevents "return {};" inside the
+   lambda, by making alloca_scopes_cannot_return a non-aggregate.  */
+struct alloca_scopes_cannot_return : alloca_scopes_cannot_return_empty_base
+{
+private:
+  alloca_scopes_cannot_return () = default;
+
+public:
+  static inline alloca_scopes_cannot_return make ()
+    ATTRIBUTE_ALWAYS_INLINE
+  { return alloca_scopes_cannot_return({}); }
+};
+
+/* Wraps a block in a lambda, so that stack memory "allocated" with
+   alloca is released on scope end.  */
+#define ALLOCA_SCOPE_START \
+  [&] () ATTRIBUTE_ALWAYS_INLINE -> alloca_scopes_cannot_return \
+    {
+
+#define ALLOCA_SCOPE_END			\
+    return alloca_scopes_cannot_return::make();	\
+  } ();
+
+#endif /* COMMON_ALLOCA_SCOPE_H */
diff --git a/gdb/common/common-defs.h b/gdb/common/common-defs.h
index af37111..ff54a45 100644
--- a/gdb/common/common-defs.h
+++ b/gdb/common/common-defs.h
@@ -69,6 +69,9 @@
 #undef ATTRIBUTE_PRINTF
 #define ATTRIBUTE_PRINTF _GL_ATTRIBUTE_FORMAT_PRINTF
 
+/* Could go to ansidecl.h.  */
+#define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+
 #include "libiberty.h"
 #include "pathmax.h"
 #include "gdb/signals.h"
diff --git a/gdb/frame.c b/gdb/frame.c
index d98003d..3fae7b4 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -42,6 +42,7 @@
 #include "tracepoint.h"
 #include "hashtab.h"
 #include "valprint.h"
+#include "alloca-scope.h"
 
 /* The sentinel frame terminates the innermost end of the frame chain.
    If unwound, it returns the information needed to construct an
@@ -1410,16 +1411,26 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
 	  enum lval_type lval;
 	  CORE_ADDR addr;
 	  int realnum;
+	  bool valid;
 
-	  frame_register (frame, regnum, optimizedp, unavailablep,
-			  &lval, &addr, &realnum, buf);
-	  if (*optimizedp || *unavailablep)
+	  ALLOCA_SCOPE_START
+	    {
+	      gdb_byte *buf
+		= (gdb_byte *) alloca (register_size (gdbarch, regnum));
+
+	      frame_register (frame, regnum, optimizedp, unavailablep,
+			      &lval, &addr, &realnum, buf);
+	      valid = !*optimizedp && !*unavailablep;
+	      if (valid)
+		memcpy (myaddr, buf + offset, curr_len);
+	    }
+	  ALLOCA_SCOPE_END
+
+	  if (!valid)
 	    return 0;
-	  memcpy (myaddr, buf + offset, curr_len);
 	}
 
       myaddr += curr_len;
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 4c53bc6..80e6764 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -38,6 +38,7 @@
 #include "osabi.h"
 #include "ia64-tdep.h"
 #include "cp-abi.h"
+#include "alloca-scope.h"
 
 #ifdef HAVE_LIBUNWIND_IA64_H
 #include "elf/ia64.h"           /* for PT_IA_64_UNWIND value */
@@ -1516,7 +1517,6 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 	  else if (qp == 0 && rN == 2 
 	        && ((rM == fp_reg && fp_reg != 0) || rM == 12))
 	    {
-	      gdb_byte buf[MAX_REGISTER_SIZE];
 	      CORE_ADDR saved_sp = 0;
 	      /* adds r2, spilloffset, rFramePointer 
 	           or
@@ -1534,8 +1534,17 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
 		{
 		  struct gdbarch *gdbarch = get_frame_arch (this_frame);
 		  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-		  get_frame_register (this_frame, sp_regnum, buf);
-		  saved_sp = extract_unsigned_integer (buf, 8, byte_order);
+
+		  ALLOCA_SCOPE_START
+		    {
+		      gdb_byte *buf
+			= (gdb_byte *) alloca (register_size (gdbarch,
+							      sp_regnum));
+
+		      get_frame_register (this_frame, sp_regnum, buf);
+		      saved_sp = extract_unsigned_integer (buf, 8, byte_order);
+		    }
+		  ALLOCA_SCOPE_END
 		}
 	      spill_addr  = saved_sp
 	                  + (rM == 12 ? 0 : mem_stack_frame_size) 
-- 
2.5.5


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-01-27 16:46   ` Alan Hayward
@ 2017-02-01 15:49     ` Pedro Alves
  0 siblings, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2017-02-01 15:49 UTC (permalink / raw)
  To: Alan Hayward; +Cc: gdb-patches, nd

On 01/27/2017 04:46 PM, Alan Hayward wrote:

> --- a/gdb/xtensa-tdep.c
> +++ b/gdb/xtensa-tdep.c
> @@ -370,7 +370,10 @@ static void
>  xtensa_register_write_masked (struct regcache *regcache,
>  			      xtensa_register_t *reg, const gdb_byte *buffer)
>  {
> -  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
> +  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
> +						 + 1);

I don't think I understand this +1.

AFAICS, the previous code was creating an array of ints
such that sizeof(value) is as big as MAX_REGISTER_SIZE, rounded up
to sizeof int.  Seems like a replacement would be:

 alloca (align_up (max_register_size (gdbarch), 4));
or better:
 alloca (align_up (max_register_size (gdbarch), sizeof (int)));

?

> +
>    const xtensa_mask_t *mask = reg->mask;
> 
>    int shift = 0;		/* Shift for next mask (mod 32).  */
> @@ -454,7 +457,9 @@ static enum register_status
>  xtensa_register_read_masked (struct regcache *regcache,
>  			     xtensa_register_t *reg, gdb_byte *buffer)
>  {
> -  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
> +  unsigned int *value = (unsigned int *) alloca (max_register_size (gdbarch)
> +						 + 1);

Ditto.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-01 15:48     ` Pedro Alves
@ 2017-02-02  9:40       ` Joel Brobecker
  2017-02-03  9:59         ` Alan Hayward
  0 siblings, 1 reply; 28+ messages in thread
From: Joel Brobecker @ 2017-02-02  9:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, Alan Hayward, gdb-patches

> #2 - Switch to heap allocation
> 
> Or std::vector or something like that that hides it.  It's not clear
> whether that would have a noticeable performance impact.

I would try that. I think using one of the standard C++ classes
looks a little more attractive to me, and would only consider
the lambda functions if we can show a noticeable performance
impact. Those two are not exclusive, by the way, but in the past,
we've always frowned on calls to alloca in a loop, and using
a xmalloc+cleanup combination has never been an issue in my cases.
I'd imagine that a standard C++ memory management class would be
fast enough for those same situations.

-- 
Joel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-02  9:40       ` Joel Brobecker
@ 2017-02-03  9:59         ` Alan Hayward
  2017-02-03 10:28           ` Yao Qi
  0 siblings, 1 reply; 28+ messages in thread
From: Alan Hayward @ 2017-02-03  9:59 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Pedro Alves, Yao Qi, gdb-patches, nd


> On 2 Feb 2017, at 09:40, Joel Brobecker <brobecker@adacore.com> wrote:
> 
>> #2 - Switch to heap allocation
>> 
>> Or std::vector or something like that that hides it.  It's not clear
>> whether that would have a noticeable performance impact.
> 
> I would try that. I think using one of the standard C++ classes
> looks a little more attractive to me, and would only consider
> the lambda functions if we can show a noticeable performance
> impact. Those two are not exclusive, by the way, but in the past,
> we've always frowned on calls to alloca in a loop, and using
> a xmalloc+cleanup combination has never been an issue in my cases.
> I'd imagine that a standard C++ memory management class would be
> fast enough for those same situations.
> 
> -- 
> Joel

We're not allocating much space, so I'd hope std::vector didn't cause much
of a slowdown. Also, the allocas with lamdba's approach feels a little
overcomplicated.

Reworking my patch that adds max_register_size (), I've replaced the allocas
with std::vector.

This patch ok? If people are happy, I'll then rework the larger patch.

Please let me know if there's a particular test you want me to run to
test performance (although I suspect it would need the larger patch
to get meaningful results). 

Thanks,
Alan.

2017-02-03  Alan Hayward  <alan.hayward@arm.com>

	* regcache.c (struct regcache_descr): Add max_register_size.
	(max_register_size): New.
	(init_regcache_descr): Find max register size.
	(regcache_save): Use std::vector.
	(regcache_restore): Likewise.
	(regcache_dump): Likewise.
	* regcache.h (max_register_size): New.
	* remote.c (remote_prepare_to_store): Use std::vector.
	* frame.c (frame_unwind_register_signed): Likewise.
	(frame_unwind_register_unsigned): Likewise.
	(get_frame_register_bytes): Likewise.
	(put_frame_register_bytes): Likewise.


diff --git a/gdb/frame.c b/gdb/frame.c
index d98003dee7c34a63bd25356e6674721664a4b2f3..135ca2b753cf4d64d0322331199d008548839c8d 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1252,10 +1252,10 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (size);

-  frame_unwind_register (frame, regnum, buf);
-  return extract_signed_integer (buf, size, byte_order);
+  frame_unwind_register (frame, regnum, buf.data ());
+  return extract_signed_integer (buf.data (), size, byte_order);
 }

 LONGEST
@@ -1270,10 +1270,10 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (size);

-  frame_unwind_register (frame, regnum, buf);
-  return extract_unsigned_integer (buf, size, byte_order);
+  frame_unwind_register (frame, regnum, buf.data ());
+  return extract_unsigned_integer (buf.data (), size, byte_order);
 }

 ULONGEST
@@ -1410,16 +1410,16 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
+	  std::vector<gdb_byte> buf (max_register_size (gdbarch));
 	  enum lval_type lval;
 	  CORE_ADDR addr;
 	  int realnum;

 	  frame_register (frame, regnum, optimizedp, unavailablep,
-			  &lval, &addr, &realnum, buf);
+			  &lval, &addr, &realnum, buf.data ());
 	  if (*optimizedp || *unavailablep)
 	    return 0;
-	  memcpy (myaddr, buf + offset, curr_len);
+	  memcpy (myaddr, buf.data () + offset, curr_len);
 	}

       myaddr += curr_len;
@@ -1460,11 +1460,11 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
+	  std::vector<gdb_byte> buf (max_register_size (gdbarch));

-	  deprecated_frame_register_read (frame, regnum, buf);
-	  memcpy (buf + offset, myaddr, curr_len);
-	  put_frame_register (frame, regnum, buf);
+	  deprecated_frame_register_read (frame, regnum, buf.data ());
+	  memcpy (buf.data () + offset, myaddr, curr_len);
+	  put_frame_register (frame, regnum, buf.data ());
 	}

       myaddr += curr_len;
diff --git a/gdb/regcache.h b/gdb/regcache.h
index e5a7cf553279b8cc0d546ec1b8274cbf97e246d5..5bc99f5c1ef87318edf4e934ec60c7f1225e7561 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -202,6 +202,8 @@ extern struct type *register_type (struct gdbarch *gdbarch, int regnum);

 extern int register_size (struct gdbarch *gdbarch, int regnum);

+/* Return the size of the largest register.  */
+extern long max_register_size (struct gdbarch *gdbarch);

 /* Save/restore a register cache.  The set of registers saved /
    restored into the DST regcache determined by the save_reggroup /
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 9d28aa2c2114e0f1c52758bb2fbe9669a329c13e..522633ae0fdf6d80508d725bc1d68d05567fd9ff 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -73,6 +73,9 @@ struct regcache_descr

   /* Cached table containing the type of each register.  */
   struct type **register_type;
+
+  /* Size of the largest register.  */
+  long max_register_size;
 };

 static void *
@@ -126,6 +129,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the raw register cache buffer.  */
     descr->sizeof_raw_registers = offset;
@@ -136,6 +141,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the readonly register cache buffer.  */
     descr->sizeof_cooked_registers = offset;
@@ -187,6 +194,13 @@ regcache_register_size (const struct regcache *regcache, int n)
   return register_size (get_regcache_arch (regcache), n);
 }

+long
+max_register_size (struct gdbarch *gdbarch)
+{
+  struct regcache_descr *descr = regcache_descr (gdbarch);
+  return descr->max_register_size;
+}
+
 /* The register cache for storing raw register values.  */

 struct regcache
@@ -327,7 +341,7 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
 	       void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
   int regnum;

   /* The DST should be `read-only', if it wasn't then the save would
@@ -346,10 +360,10 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
 	{
-	  enum register_status status = cooked_read (src, regnum, buf);
+	  enum register_status status = cooked_read (src, regnum, buf.data ());

 	  if (status == REG_VALID)
-	    memcpy (register_buffer (dst, regnum), buf,
+	    memcpy (register_buffer (dst, regnum), buf.data (),
 		    register_size (gdbarch, regnum));
 	  else
 	    {
@@ -369,7 +383,7 @@ regcache_restore (struct regcache *dst,
 		  void *cooked_read_context)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
   int regnum;

   /* The dst had better not be read-only.  If it is, the `restore'
@@ -385,9 +399,9 @@ regcache_restore (struct regcache *dst,
 	{
 	  enum register_status status;

-	  status = cooked_read (cooked_read_context, regnum, buf);
+	  status = cooked_read (cooked_read_context, regnum, buf.data ());
 	  if (status == REG_VALID)
-	    regcache_cooked_write (dst, regnum, buf);
+	    regcache_cooked_write (dst, regnum, buf.data ());
 	}
     }
 }
@@ -1279,7 +1293,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
   int footnote_register_offset = 0;
   int footnote_register_type_name_null = 0;
   long register_offset = 0;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));

 #if 0
   fprintf_unfiltered (file, "nr_raw_registers %d\n",
@@ -1406,8 +1420,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    fprintf_unfiltered (file, "<unavailable>");
 	  else
 	    {
-	      regcache_raw_read (regcache, regnum, buf);
-	      print_hex_chars (file, buf,
+	      regcache_raw_read (regcache, regnum, buf.data ());
+	      print_hex_chars (file, buf.data (),
 			       regcache->descr->sizeof_register[regnum],
 			       gdbarch_byte_order (gdbarch));
 	    }
@@ -1422,13 +1436,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    {
 	      enum register_status status;

-	      status = regcache_cooked_read (regcache, regnum, buf);
+	      status = regcache_cooked_read (regcache, regnum, buf.data ());
 	      if (status == REG_UNKNOWN)
 		fprintf_unfiltered (file, "<invalid>");
 	      else if (status == REG_UNAVAILABLE)
 		fprintf_unfiltered (file, "<unavailable>");
 	      else
-		print_hex_chars (file, buf,
+		print_hex_chars (file, buf.data (),
 				 regcache->descr->sizeof_register[regnum],
 				 gdbarch_byte_order (gdbarch));
 	    }
diff --git a/gdb/remote.c b/gdb/remote.c
index c4cec910c44cf91cc7f36b7f2d87cde3f46de41e..157a1b1789d2a248c11dcc4efebd8ce54da82045 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -7757,9 +7757,10 @@ remote_fetch_registers (struct target_ops *ops,
 static void
 remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));

   /* Make sure the entire registers array is valid.  */
   switch (packet_support (PACKET_P))
@@ -7769,7 +7770,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
       /* Make sure all the necessary registers are cached.  */
       for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
 	if (rsa->regs[i].in_g_packet)
-	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
+	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf.data ());
       break;
     case PACKET_ENABLE:
       break;


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-03  9:59         ` Alan Hayward
@ 2017-02-03 10:28           ` Yao Qi
  2017-02-03 11:00             ` Pedro Alves
  0 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-03 10:28 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Joel Brobecker, Pedro Alves, gdb-patches

On Fri, Feb 3, 2017 at 9:59 AM, Alan Hayward <Alan.Hayward@arm.com> wrote:
>
>> On 2 Feb 2017, at 09:40, Joel Brobecker <brobecker@adacore.com> wrote:
>>
>>> #2 - Switch to heap allocation
>>>
>>> Or std::vector or something like that that hides it.  It's not clear
>>> whether that would have a noticeable performance impact.
>>
>> I would try that. I think using one of the standard C++ classes
>> looks a little more attractive to me, and would only consider
>> the lambda functions if we can show a noticeable performance
>> impact. Those two are not exclusive, by the way, but in the past,
>> we've always frowned on calls to alloca in a loop, and using
>> a xmalloc+cleanup combination has never been an issue in my cases.
>> I'd imagine that a standard C++ memory management class would be
>> fast enough for those same situations.
>>
>> --
>> Joel
>
> We're not allocating much space, so I'd hope std::vector didn't cause much
> of a slowdown. Also, the allocas with lamdba's approach feels a little
> overcomplicated.
>
> Reworking my patch that adds max_register_size (), I've replaced the allocas
> with std::vector.
>
> This patch ok? If people are happy, I'll then rework the larger patch.

I don't think we have to replace all MAX_REGISTER_SIZE with std::vector.
MAX_REGISTER_SIZE is mostly used in arch-dependent code (*-tdep.c
and *-nat.c), where the register size or max register size is known.  For
example, MAX_REGISTER_SIZE is used only once in arm-tdep.c, and
it can be replaced with FP_REGISTER_SIZE, because 'buf' is to get the
contents for FPA register.  Similarly, MAX_REGISTER_SIZE is used three
times in aarch64-tdep.c, all of them can be repalced by V_REGISTER_SIZE.
Also, MAX_REGISTER_SIZE can be replaced by
I386_MAX_REGISTER_SIZE in i386-tdep.c.  I would like to examine the
usages of MAX_REGISTER_SIZE in each target-dependent code, and
replace MAX_REGISTER_SIZE with known constants as much as we can.
I don't think anyone has objections on replacing one constant
MAX_REGISTER_SIZE with other smaller constants :)

Then, let us discuss how to remove MAX_REGISTER_SIZE from
arch-independent code after all above is done.

-- 
Yao (齐尧)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 801c03d..1f82187 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1982,7 +1982,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
       for (i = 0; i < elements; i++)
 	{
 	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte tmpbuf[MAX_REGISTER_SIZE];
+	  bfd_byte tmpbuf[V_REGISTER_SIZE];
 
 	  if (aarch64_debug)
 	    {
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 0ae311f..42a39dc 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -69,6 +69,10 @@
 #include "features/arm/arm-with-vfpv3.c"
 #include "features/arm/arm-with-neon.c"
 
+#if GDB_SELF_TEST
+#include "selftest.h"
+#endif
+
 static int arm_debug;
 
 /* Macros for setting and testing a bit in a minimal symbol that marks
@@ -4237,6 +4241,23 @@ convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr,
 			       &d, dbl);
 }
 
+#if GDB_SELF_TEST
+
+namespace selftests {
+
+static void
+arm_floatformat_test (void)
+{
+  SELF_CHECK (floatformat_totalsize_bytes (&floatformat_arm_ext_big)
+	      == FP_REGISTER_SIZE);
+  SELF_CHECK (floatformat_totalsize_bytes (&floatformat_arm_ext_littlebyte_bigword)
+	      == FP_REGISTER_SIZE);
+}
+
+} // namespace selftests
+
+#endif /* GDB_SELF_TEST */
+
 /* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
    the buffer to be NEW_LEN bytes ending at ENDADDR.  Return
    NULL if an error occurs.  BUF is freed.  */
@@ -8153,11 +8174,10 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
     {
-      gdb_byte buf[MAX_REGISTER_SIZE];
-
       switch (gdbarch_tdep (gdbarch)->fp_model)
 	{
 	case ARM_FLOAT_FPA:
+	  gdb_byte buf[FP_REGISTER_SIZE];
 
 	  convert_to_extended (floatformat_from_type (type), buf, valbuf,
 			       gdbarch_byte_order (gdbarch));
@@ -9717,6 +9737,10 @@ vfp - VFP co-processor."),
 			   NULL,
 			   NULL, /* FIXME: i18n: "ARM debugging is %s.  */
 			   &setdebuglist, &showdebuglist);
+
+#if GDB_SELF_TEST
+  register_self_test (selftests::arm_floatformat_test);
+#endif
 }
 
 /* ARM-reversible process record data structures.  */

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-03 10:28           ` Yao Qi
@ 2017-02-03 11:00             ` Pedro Alves
  2017-02-03 11:25               ` Alan Hayward
  0 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2017-02-03 11:00 UTC (permalink / raw)
  To: Yao Qi, Alan Hayward; +Cc: Joel Brobecker, gdb-patches

On 02/03/2017 10:28 AM, Yao Qi wrote:

> I don't think we have to replace all MAX_REGISTER_SIZE with std::vector.
> MAX_REGISTER_SIZE is mostly used in arch-dependent code (*-tdep.c
> and *-nat.c), where the register size or max register size is known.  For
> example, MAX_REGISTER_SIZE is used only once in arm-tdep.c, and
> it can be replaced with FP_REGISTER_SIZE, because 'buf' is to get the
> contents for FPA register.  Similarly, MAX_REGISTER_SIZE is used three
> times in aarch64-tdep.c, all of them can be repalced by V_REGISTER_SIZE.
> Also, MAX_REGISTER_SIZE can be replaced by
> I386_MAX_REGISTER_SIZE in i386-tdep.c.  I would like to examine the
> usages of MAX_REGISTER_SIZE in each target-dependent code, and
> replace MAX_REGISTER_SIZE with known constants as much as we can.
> I don't think anyone has objections on replacing one constant
> MAX_REGISTER_SIZE with other smaller constants :)
> 
> Then, let us discuss how to remove MAX_REGISTER_SIZE from
> arch-independent code after all above is done.
> 

+1.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-03 11:00             ` Pedro Alves
@ 2017-02-03 11:25               ` Alan Hayward
  2017-02-03 16:50                 ` Yao Qi
  0 siblings, 1 reply; 28+ messages in thread
From: Alan Hayward @ 2017-02-03 11:25 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, Joel Brobecker, gdb-patches, nd


> On 3 Feb 2017, at 10:59, Pedro Alves <palves@redhat.com> wrote:
> 
> On 02/03/2017 10:28 AM, Yao Qi wrote:
> 
>> I don't think we have to replace all MAX_REGISTER_SIZE with std::vector.
>> MAX_REGISTER_SIZE is mostly used in arch-dependent code (*-tdep.c
>> and *-nat.c), where the register size or max register size is known.  For
>> example, MAX_REGISTER_SIZE is used only once in arm-tdep.c, and
>> it can be replaced with FP_REGISTER_SIZE, because 'buf' is to get the
>> contents for FPA register.  Similarly, MAX_REGISTER_SIZE is used three
>> times in aarch64-tdep.c, all of them can be repalced by V_REGISTER_SIZE.
>> Also, MAX_REGISTER_SIZE can be replaced by
>> I386_MAX_REGISTER_SIZE in i386-tdep.c.  I would like to examine the
>> usages of MAX_REGISTER_SIZE in each target-dependent code, and
>> replace MAX_REGISTER_SIZE with known constants as much as we can.
>> I don't think anyone has objections on replacing one constant
>> MAX_REGISTER_SIZE with other smaller constants :)
>> 
>> Then, let us discuss how to remove MAX_REGISTER_SIZE from
>> arch-independent code after all above is done.
>> 
> 
> +1.
> 
> Thanks,
> Pedro Alves
> 

If someone can ok the common patch, then I’ll make a second patch with the
replacement of all remaining uses of MAX_REGISTER_SIZE in common code.
Ensuring it’s not used in common code will allow me to continue moving with the
aarch64 SVE code.


There are quite a lot of arch specific functions where we have a register number
from which the register size could be extracted.  Eg:

void
SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
			    int regnum, const gdb_byte *buf)
{
  gdb_byte raw_buf[MAX_REGISTER_SIZE];


This could become:

void
SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
			    int regnum, const gdb_byte *buf)
{
  gdb_byte buf[SOMEARCH_MAX_REGISTER_SIZE];


Or:

void
SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
			    int regnum, const gdb_byte *buf)
{
  std::vector<gdb_byte> buf (register_size (gdbarch, regnum));


I suspect people will want the first approach? It will result in quite a few new
defines - ALPHA_MAX_REGISTER_SIZE, PPC_MAX_REGISTER_SIZE etc etc.


Alan.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-03 11:25               ` Alan Hayward
@ 2017-02-03 16:50                 ` Yao Qi
  2017-02-06  9:33                   ` Alan Hayward
  0 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-03 16:50 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd

On 17-02-03 11:25:43, Alan Hayward wrote:
> If someone can ok the common patch, then I’ll make a second patch with the
> replacement of all remaining uses of MAX_REGISTER_SIZE in common code.

I'd like to do it in an iterative way, start from some simple places, like
arm, aarch64, and i386, in which you don't need to define new macros.  Then,
move to some *-tdep.c and *-nat.c, define ${ARCH}_MAX_REGISTER_SIZE when
necessary.  Finally, figure out how to remove MAX_REGISTER_SIZE from
arch-independent code.

> Ensuring it’s not used in common code will allow me to continue moving with the
> aarch64 SVE code.
> 
> 
> There are quite a lot of arch specific functions where we have a register number
> from which the register size could be extracted.  Eg:
> 
> void
> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
> 			    int regnum, const gdb_byte *buf)
> {
>   gdb_byte raw_buf[MAX_REGISTER_SIZE];
> 
> 
> This could become:
> 
> void
> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
> 			    int regnum, const gdb_byte *buf)
> {
>   gdb_byte buf[SOMEARCH_MAX_REGISTER_SIZE];
> 
> 
> Or:
> 
> void
> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
> 			    int regnum, const gdb_byte *buf)
> {
>   std::vector<gdb_byte> buf (register_size (gdbarch, regnum));
> 
> 
> I suspect people will want the first approach? It will result in quite a few new
> defines - ALPHA_MAX_REGISTER_SIZE, PPC_MAX_REGISTER_SIZE etc etc.
> 

That is fine, we've already had I386_MAX_REGISTER_SIZE and M68K_MAX_REGISTER_SIZE.
However, I think that we only have to add these macros when necessary.


-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-03 16:50                 ` Yao Qi
@ 2017-02-06  9:33                   ` Alan Hayward
       [not found]                     ` <20170206152635.GE11916@E107787-LIN>
  0 siblings, 1 reply; 28+ messages in thread
From: Alan Hayward @ 2017-02-06  9:33 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 3 Feb 2017, at 16:50, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> On 17-02-03 11:25:43, Alan Hayward wrote:
>> If someone can ok the common patch, then I’ll make a second patch with the
>> replacement of all remaining uses of MAX_REGISTER_SIZE in common code.
> 
> I'd like to do it in an iterative way, start from some simple places, like
> arm, aarch64, and i386, in which you don't need to define new macros.  Then,
> move to some *-tdep.c and *-nat.c, define ${ARCH}_MAX_REGISTER_SIZE when
> necessary.  Finally, figure out how to remove MAX_REGISTER_SIZE from
> arch-independent code.
> 
>> Ensuring it’s not used in common code will allow me to continue moving with the
>> aarch64 SVE code.
>> 
>> 
>> There are quite a lot of arch specific functions where we have a register number
>> from which the register size could be extracted.  Eg:
>> 
>> void
>> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>> 			    int regnum, const gdb_byte *buf)
>> {
>>  gdb_byte raw_buf[MAX_REGISTER_SIZE];
>> 
>> 
>> This could become:
>> 
>> void
>> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>> 			    int regnum, const gdb_byte *buf)
>> {
>>  gdb_byte buf[SOMEARCH_MAX_REGISTER_SIZE];
>> 
>> 
>> Or:
>> 
>> void
>> SOMEARCH_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>> 			    int regnum, const gdb_byte *buf)
>> {
>>  std::vector<gdb_byte> buf (register_size (gdbarch, regnum));
>> 
>> 
>> I suspect people will want the first approach? It will result in quite a few new
>> defines - ALPHA_MAX_REGISTER_SIZE, PPC_MAX_REGISTER_SIZE etc etc.
>> 
> 
> That is fine, we've already had I386_MAX_REGISTER_SIZE and M68K_MAX_REGISTER_SIZE.
> However, I think that we only have to add these macros when necessary.
> 
> 
> -- 
> Yao (齐尧)


Ok, Given that, I've put together a quick patch to:
* Use M68K_MAX_REGISTER_SIZE and I386_MAX_REGISTER_SIZE where possible.
* Add max_register_size() function
* Remove MAX_REGISTER_SIZE from all common files by using std::vector.
Contents should be very similar to previous patches posted.

This patch ok?

2017-02-06  Alan Hayward  <alan.hayward@arm.com\\>

	* frame.c (frame_unwind_register_signed): Use std::vector.
	(frame_unwind_register_unsigned): Likewise.
	(get_frame_register_bytes): Likewise.
	(put_frame_register_bytes): Likewise.
	* i386-tdep.c (i386_pseudo_register_read_into_value): Use
	I386_MAX_REGISTER_SIZE.
	(i386_pseudo_register_write): Likewise.
	(i386_process_record): Likewise.
	* i387-tdep.c (i387_supply_xsave): Likewise.
	* m68k-linux-nat.c (fetch_register): Use M68K_MAX_REGISTER_SIZE.
	(store_register): Likewise.
	* mi/mi-main.c (register_changed_p): Use std::vector.
	* record-full.c (record_full_exec_insn): Likewise.
	(record_full_core_open_1): Use max_register_size ().
	(record_full_core_fetch_registers): Likewise.
	(record_full_core_store_registers): Likewise.
	(init_record_full_core_ops): Likewise.
	* remote-sim.c (gdbsim_fetch_register): Likewise.
	(gdbsim_store_register): Likewise.
	* regcache.c (struct regcache_descr): Add max_register_size.
	(max_register_size): New.
	(init_regcache_descr): Find max register size.
	(regcache_save): Use std::vector.
	(regcache_restore): Likewise.
	(regcache_dump): Likewise.
	* regcache.h (max_register_size): New.
	* remote.c (remote_prepare_to_store): Use std::vector.
	* sol-thread.c (sol_thread_store_registers): Likewise.
	* stack.c (frame_info): Likewise.
	* target.c (debug_print_register): Likewise.


diff --git a/gdb/frame.c b/gdb/frame.c
index d98003dee7c34a63bd25356e6674721664a4b2f3..1700308371d9d795545c0a8bb26dba289b18217d 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1252,10 +1252,10 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (size);

-  frame_unwind_register (frame, regnum, buf);
-  return extract_signed_integer (buf, size, byte_order);
+  frame_unwind_register (frame, regnum, buf.data ());
+  return extract_signed_integer (buf.data (), size, byte_order);
 }

 LONGEST
@@ -1270,10 +1270,10 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (size);

-  frame_unwind_register (frame, regnum, buf);
-  return extract_unsigned_integer (buf, size, byte_order);
+  frame_unwind_register (frame, regnum, buf.data ());
+  return extract_unsigned_integer (buf.data (), size, byte_order);
 }

 ULONGEST
@@ -1389,6 +1389,8 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
     error (_("Bad debug information detected: "
 	     "Attempt to read %d bytes from registers."), len);

+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
+
   /* Copy the data.  */
   while (len > 0)
     {
@@ -1410,16 +1412,15 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
 	  enum lval_type lval;
 	  CORE_ADDR addr;
 	  int realnum;

 	  frame_register (frame, regnum, optimizedp, unavailablep,
-			  &lval, &addr, &realnum, buf);
+			  &lval, &addr, &realnum, buf.data ());
 	  if (*optimizedp || *unavailablep)
 	    return 0;
-	  memcpy (myaddr, buf + offset, curr_len);
+	  memcpy (myaddr, buf.data () + offset, curr_len);
 	}

       myaddr += curr_len;
@@ -1446,6 +1447,8 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
       regnum++;
     }

+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
+
   /* Copy the data.  */
   while (len > 0)
     {
@@ -1460,11 +1463,9 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
-
-	  deprecated_frame_register_read (frame, regnum, buf);
-	  memcpy (buf + offset, myaddr, curr_len);
-	  put_frame_register (frame, regnum, buf);
+	  deprecated_frame_register_read (frame, regnum, buf.data ());
+	  memcpy (buf.data () + offset, myaddr, curr_len);
+	  put_frame_register (frame, regnum, buf.data ());
 	}

       myaddr += curr_len;
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..081a16c6896ce7aee4db3b0be45fbbdd2c23dbdb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 				      int regnum,
 				      struct value *result_value)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);

@@ -3455,7 +3455,7 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];

   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[I386_MAX_REGISTER_SIZE];
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index adbe72133089bc371108d5dd79bf8d8e61ba259c..fcd5ad248d6b737b9f27e294ce166a118e4bdcad 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -899,7 +899,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = (const gdb_byte *) xsave;
   int i;
   unsigned int clear_bv;
-  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
+  static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
   enum
     {
       none = 0x0,
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 6944c74eb198381135fda3ddf01b9da3a63e62d5..e5182caf39197f759c85c2321e4d66c428f5911e 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   long regaddr, val;
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
   int tid;

   /* Overload thread id onto process id.  */
@@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
   long regaddr, val;
   int i;
   int tid;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];

   /* Overload thread id onto process id.  */
   tid = ptid_get_lwp (inferior_ptid);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..b07335d82723f3ee9c7602a8fa284acb7e3b3a25 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
 		    struct regcache *this_regs)
 {
   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
-  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
-  gdb_byte this_buffer[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> prev_buffer (max_register_size (gdbarch));
+  std::vector<gdb_byte> this_buffer (max_register_size (gdbarch));
   enum register_status prev_status;
   enum register_status this_status;

@@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
     return 1;

   /* Get register contents and compare.  */
-  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
-  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
+  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
+  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());

   if (this_status != prev_status)
     return 1;
   else if (this_status == REG_VALID)
-    return memcmp (prev_buffer, this_buffer,
+    return memcmp (prev_buffer.data (), this_buffer.data (),
 		   register_size (gdbarch, regnum)) != 0;
   else
     return 0;
diff --git a/gdb/record-full.c b/gdb/record-full.c
index fdd613b6e41bbfcd8644b02ccfeb98b53b518bff..a619e09a646c48c632a60407d7018979d805a08f 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -698,7 +698,7 @@ record_full_exec_insn (struct regcache *regcache,
     {
     case record_full_reg: /* reg */
       {
-        gdb_byte reg[MAX_REGISTER_SIZE];
+	std::vector<gdb_byte> reg (register_size (gdbarch, entry->u.reg.num));

         if (record_debug > 1)
           fprintf_unfiltered (gdb_stdlog,
@@ -707,10 +707,10 @@ record_full_exec_insn (struct regcache *regcache,
                               host_address_to_string (entry),
                               entry->u.reg.num);

-        regcache_cooked_read (regcache, entry->u.reg.num, reg);
-        regcache_cooked_write (regcache, entry->u.reg.num,
+	regcache_cooked_read (regcache, entry->u.reg.num, reg.data ());
+	regcache_cooked_write (regcache, entry->u.reg.num,
 			       record_full_get_loc (entry));
-        memcpy (record_full_get_loc (entry), reg, entry->u.reg.len);
+	memcpy (record_full_get_loc (entry), reg.data (), entry->u.reg.len);
       }
       break;

@@ -792,15 +792,17 @@ static void
 record_full_core_open_1 (const char *name, int from_tty)
 {
   struct regcache *regcache = get_current_regcache ();
-  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regnum = gdbarch_num_regs (gdbarch);
+  int regmaxsize = max_register_size (gdbarch);
   int i;

   /* Get record_full_core_regbuf.  */
   target_fetch_registers (regcache, -1);
-  record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum);
+  record_full_core_regbuf = (gdb_byte *) xmalloc (regmaxsize * regnum);
   for (i = 0; i < regnum; i ++)
     regcache_raw_collect (regcache, i,
-			  record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			  record_full_core_regbuf + regmaxsize * i);

   /* Get record_full_core_start and record_full_core_end.  */
   if (build_section_table (core_bfd, &record_full_core_start,
@@ -2038,6 +2040,9 @@ record_full_core_fetch_registers (struct target_ops *ops,
 				  struct regcache *regcache,
 				  int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (regno < 0)
     {
       int num = gdbarch_num_regs (get_regcache_arch (regcache));
@@ -2045,11 +2050,11 @@ record_full_core_fetch_registers (struct target_ops *ops,

       for (i = 0; i < num; i ++)
         regcache_raw_supply (regcache, i,
-                             record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			     record_full_core_regbuf + regmaxsize * i);
     }
   else
     regcache_raw_supply (regcache, regno,
-                         record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			 record_full_core_regbuf + regmaxsize * regno);
 }

 /* "to_prepare_to_store" method for prec over corefile.  */
@@ -2067,9 +2072,12 @@ record_full_core_store_registers (struct target_ops *ops,
                              struct regcache *regcache,
                              int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (record_full_gdb_operation_disable)
     regcache_raw_collect (regcache, regno,
-                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			  record_full_core_regbuf + regmaxsize * regno);
   else
     error (_("You can't do that without a process to debug."));
 }
@@ -2265,7 +2273,7 @@ init_record_full_core_ops (void)
      record_full_reg:
        1 byte:  record type (record_full_reg, see enum record_full_type).
        8 bytes: register id (network byte order).
-       MAX_REGISTER_SIZE bytes: register value.
+       max_register_size bytes: register value.
      record_full_mem:
        1 byte:  record type (record_full_mem, see enum record_full_type).
        8 bytes: memory length (network byte order).
diff --git a/gdb/regcache.h b/gdb/regcache.h
index e5a7cf553279b8cc0d546ec1b8274cbf97e246d5..5bc99f5c1ef87318edf4e934ec60c7f1225e7561 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -202,6 +202,8 @@ extern struct type *register_type (struct gdbarch *gdbarch, int regnum);

 extern int register_size (struct gdbarch *gdbarch, int regnum);

+/* Return the size of the largest register.  */
+extern long max_register_size (struct gdbarch *gdbarch);

 /* Save/restore a register cache.  The set of registers saved /
    restored into the DST regcache determined by the save_reggroup /
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 9d28aa2c2114e0f1c52758bb2fbe9669a329c13e..522633ae0fdf6d80508d725bc1d68d05567fd9ff 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -73,6 +73,9 @@ struct regcache_descr

   /* Cached table containing the type of each register.  */
   struct type **register_type;
+
+  /* Size of the largest register.  */
+  long max_register_size;
 };

 static void *
@@ -126,6 +129,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the raw register cache buffer.  */
     descr->sizeof_raw_registers = offset;
@@ -136,6 +141,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the readonly register cache buffer.  */
     descr->sizeof_cooked_registers = offset;
@@ -187,6 +194,13 @@ regcache_register_size (const struct regcache *regcache, int n)
   return register_size (get_regcache_arch (regcache), n);
 }

+long
+max_register_size (struct gdbarch *gdbarch)
+{
+  struct regcache_descr *descr = regcache_descr (gdbarch);
+  return descr->max_register_size;
+}
+
 /* The register cache for storing raw register values.  */

 struct regcache
@@ -327,7 +341,7 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
 	       void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
   int regnum;

   /* The DST should be `read-only', if it wasn't then the save would
@@ -346,10 +360,10 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
 	{
-	  enum register_status status = cooked_read (src, regnum, buf);
+	  enum register_status status = cooked_read (src, regnum, buf.data ());

 	  if (status == REG_VALID)
-	    memcpy (register_buffer (dst, regnum), buf,
+	    memcpy (register_buffer (dst, regnum), buf.data (),
 		    register_size (gdbarch, regnum));
 	  else
 	    {
@@ -369,7 +383,7 @@ regcache_restore (struct regcache *dst,
 		  void *cooked_read_context)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
   int regnum;

   /* The dst had better not be read-only.  If it is, the `restore'
@@ -385,9 +399,9 @@ regcache_restore (struct regcache *dst,
 	{
 	  enum register_status status;

-	  status = cooked_read (cooked_read_context, regnum, buf);
+	  status = cooked_read (cooked_read_context, regnum, buf.data ());
 	  if (status == REG_VALID)
-	    regcache_cooked_write (dst, regnum, buf);
+	    regcache_cooked_write (dst, regnum, buf.data ());
 	}
     }
 }
@@ -1279,7 +1293,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
   int footnote_register_offset = 0;
   int footnote_register_type_name_null = 0;
   long register_offset = 0;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));

 #if 0
   fprintf_unfiltered (file, "nr_raw_registers %d\n",
@@ -1406,8 +1420,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    fprintf_unfiltered (file, "<unavailable>");
 	  else
 	    {
-	      regcache_raw_read (regcache, regnum, buf);
-	      print_hex_chars (file, buf,
+	      regcache_raw_read (regcache, regnum, buf.data ());
+	      print_hex_chars (file, buf.data (),
 			       regcache->descr->sizeof_register[regnum],
 			       gdbarch_byte_order (gdbarch));
 	    }
@@ -1422,13 +1436,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    {
 	      enum register_status status;

-	      status = regcache_cooked_read (regcache, regnum, buf);
+	      status = regcache_cooked_read (regcache, regnum, buf.data ());
 	      if (status == REG_UNKNOWN)
 		fprintf_unfiltered (file, "<invalid>");
 	      else if (status == REG_UNAVAILABLE)
 		fprintf_unfiltered (file, "<unavailable>");
 	      else
-		print_hex_chars (file, buf,
+		print_hex_chars (file, buf.data (),
 				 regcache->descr->sizeof_register[regnum],
 				 gdbarch_byte_order (gdbarch));
 	    }
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index b0c68c617e365c0ea18ac2eca525598b688ffbb5..c5b1a480c52e12af01dc2d6c959fd429735bc805 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -439,6 +439,9 @@ gdbsim_fetch_register (struct target_ops *ops,
       return;
     }

+  int regsize = register_size (gdbarch, regno);
+  std::vector<gdb_byte> buf (regsize);
+
   switch (gdbarch_register_sim_regno (gdbarch, regno))
     {
     case LEGACY_SIM_REGNO_IGNORE:
@@ -447,10 +450,9 @@ gdbsim_fetch_register (struct target_ops *ops,
       {
 	/* For moment treat a `does not exist' register the same way
 	   as an ``unavailable'' register.  */
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	regcache_raw_supply (regcache, regno, buf);
 	break;
       }
@@ -458,18 +460,17 @@ gdbsim_fetch_register (struct target_ops *ops,
     default:
       {
 	static int warn_user = 1;
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

 	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
-	memset (buf, 0, MAX_REGISTER_SIZE);
+	memset (buf, 0, regsize);
 	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
 				       gdbarch_register_sim_regno
 					 (gdbarch, regno),
 				       buf,
-				       register_size (gdbarch, regno));
+				       regsize);
 	if (nr_bytes > 0
-	    && nr_bytes != register_size (gdbarch, regno) && warn_user)
+	    && nr_bytes != regsize && warn_user)
 	  {
 	    fprintf_unfiltered (gdb_stderr,
 				"Size of register %s (%d/%d) "
@@ -478,7 +479,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 				regno,
 				gdbarch_register_sim_regno
 				  (gdbarch, regno),
-				nr_bytes, register_size (gdbarch, regno));
+				nr_bytes, regsize);
 	    warn_user = 0;
 	  }
 	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
@@ -492,7 +493,7 @@ gdbsim_fetch_register (struct target_ops *ops,
 	    fprintf_unfiltered (gdb_stdlog,
 				"gdbsim_fetch_register: %d", regno);
 	    /* FIXME: We could print something more intelligible.  */
-	    dump_mem (buf, register_size (gdbarch, regno));
+	    dump_mem (buf, regsize);
 	  }
 	break;
       }
@@ -516,15 +517,16 @@ gdbsim_store_register (struct target_ops *ops,
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
     {
-      gdb_byte tmp[MAX_REGISTER_SIZE];
+      int regsize = register_size (gdbarch, regno);
+      std::vector<gdb_byte> tmp (regsize);
       int nr_bytes;

       regcache_cooked_read (regcache, regno, tmp);
       nr_bytes = sim_store_register (sim_data->gdbsim_desc,
 				     gdbarch_register_sim_regno
 				       (gdbarch, regno),
-				     tmp, register_size (gdbarch, regno));
-      if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno))
+				     tmp, regsize);
+      if (nr_bytes > 0 && nr_bytes != regsize)
 	internal_error (__FILE__, __LINE__,
 			_("Register size different to expected"));
       if (nr_bytes < 0)
@@ -538,7 +540,7 @@ gdbsim_store_register (struct target_ops *ops,
 	{
 	  fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno);
 	  /* FIXME: We could print something more intelligible.  */
-	  dump_mem (tmp, register_size (gdbarch, regno));
+	  dump_mem (tmp, regsize);
 	}
     }
 }
diff --git a/gdb/remote.c b/gdb/remote.c
index c4cec910c44cf91cc7f36b7f2d87cde3f46de41e..157a1b1789d2a248c11dcc4efebd8ce54da82045 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -7757,9 +7757,10 @@ remote_fetch_registers (struct target_ops *ops,
 static void
 remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));

   /* Make sure the entire registers array is valid.  */
   switch (packet_support (PACKET_P))
@@ -7769,7 +7770,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
       /* Make sure all the necessary registers are cached.  */
       for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
 	if (rsa->regs[i].in_g_packet)
-	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
+	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf.data ());
       break;
     case PACKET_ENABLE:
       break;
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index a09a3ab9a8bc56f367e3ba1537f5674f0a7f491f..5e7443a97624fbeae5b65cb534401e6371755423 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -514,6 +514,7 @@ sol_thread_store_registers (struct target_ops *ops,
   td_err_e val;
   prgregset_t gregset;
   prfpregset_t fpregset;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);

   if (!ptid_tid_p (inferior_ptid))
     {
@@ -535,10 +536,10 @@ sol_thread_store_registers (struct target_ops *ops,
   if (regnum != -1)
     {
       /* Not writing all the registers.  */
-      char old_value[MAX_REGISTER_SIZE];
+      std::vector<gdb_byte> old_value (register_size (gdbarch, regnum));

       /* Save new register value.  */
-      regcache_raw_collect (regcache, regnum, old_value);
+      regcache_raw_collect (regcache, regnum, old_value.data ());

       val = p_td_thr_getgregs (&thandle, gregset);
       if (val != TD_OK)
@@ -550,7 +551,7 @@ sol_thread_store_registers (struct target_ops *ops,
 	       td_err_string (val));

       /* Restore new register value.  */
-      regcache_raw_supply (regcache, regnum, old_value);
+      regcache_raw_supply (regcache, regnum, old_value.data ());
     }

   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
diff --git a/gdb/stack.c b/gdb/stack.c
index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..9b84435fe73b9af9b13f01c819f77f83bbb7117b 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1667,16 +1667,16 @@ frame_info (char *addr_exp, int from_tty)
 	  {
 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
-	    gdb_byte value[MAX_REGISTER_SIZE];
+	    std::vector<gdb_byte> value (sp_size);
 	    CORE_ADDR sp;

 	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
 				   &optimized, &unavailable, &lval, &addr,
-				   &realnum, value);
+				   &realnum, value.data ());
 	    /* NOTE: cagney/2003-05-22: This is assuming that the
                stack pointer was packed as an unsigned integer.  That
                may or may not be valid.  */
-	    sp = extract_unsigned_integer (value, sp_size, byte_order);
+	    sp = extract_unsigned_integer (value.data (), sp_size, byte_order);
 	    printf_filtered (" Previous frame's sp is ");
 	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
 	    printf_filtered ("\n");
diff --git a/gdb/target.c b/gdb/target.c
index 3c409f0f619141205dfdcbbf8e46a277585ed683..52bb59255fcbdc74a674e08f6e168be5b6294819 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3565,17 +3565,18 @@ debug_print_register (const char * func,
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       int i, size = register_size (gdbarch, regno);
-      gdb_byte buf[MAX_REGISTER_SIZE];
+      std::vector<gdb_byte> buf (size);

-      regcache_raw_collect (regcache, regno, buf);
+      regcache_raw_collect (regcache, regno, buf.data ());
       fprintf_unfiltered (gdb_stdlog, " = ");
       for (i = 0; i < size; i++)
 	{
-	  fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+	  fprintf_unfiltered (gdb_stdlog, "%02x", buf.data ()[i]);
 	}
       if (size <= sizeof (LONGEST))
 	{
-	  ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
+	  ULONGEST val = extract_unsigned_integer (buf.data (), size,
+						   byte_order);

 	  fprintf_unfiltered (gdb_stdlog, " %s %s",
 			      core_addr_to_string_nz (val), plongest (val));



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
       [not found]                     ` <20170206152635.GE11916@E107787-LIN>
@ 2017-02-07 16:33                       ` Alan Hayward
  2017-02-08 10:47                         ` Yao Qi
                                           ` (5 more replies)
  0 siblings, 6 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-07 16:33 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 6 Feb 2017, at 15:26, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> On 17-02-06 09:33:25, Alan Hayward wrote:
>> 
>> Ok, Given that, I've put together a quick patch to:
>> * Use M68K_MAX_REGISTER_SIZE and I386_MAX_REGISTER_SIZE where possible.
> 
> They can be in a separate patch if you want.
> 
>> * Add max_register_size() function
>> * Remove MAX_REGISTER_SIZE from all common files by using std::vector.
>> Contents should be very similar to previous patches posted.
>> 
>> This patch ok?
>> 
>> 2017-02-06  Alan Hayward  <alan.hayward@arm.com\\>
>> 
>> 	* frame.c (frame_unwind_register_signed): Use std::vector.
>> 	(frame_unwind_register_unsigned): Likewise.
>> 	(get_frame_register_bytes): Likewise.
>> 	(put_frame_register_bytes): Likewise.
>> 	* i386-tdep.c (i386_pseudo_register_read_into_value): Use
>> 	I386_MAX_REGISTER_SIZE.
>> 	(i386_pseudo_register_write): Likewise.
>> 	(i386_process_record): Likewise.
>> 	* i387-tdep.c (i387_supply_xsave): Likewise.
>> 	* m68k-linux-nat.c (fetch_register): Use M68K_MAX_REGISTER_SIZE.
>> 	(store_register): Likewise.
>> 	* mi/mi-main.c (register_changed_p): Use std::vector.
>> 	* record-full.c (record_full_exec_insn): Likewise.
>> 	(record_full_core_open_1): Use max_register_size ().
>> 	(record_full_core_fetch_registers): Likewise.
>> 	(record_full_core_store_registers): Likewise.
>> 	(init_record_full_core_ops): Likewise.
>> 	* remote-sim.c (gdbsim_fetch_register): Likewise.
>> 	(gdbsim_store_register): Likewise.
>> 	* regcache.c (struct regcache_descr): Add max_register_size.
>> 	(max_register_size): New.
>> 	(init_regcache_descr): Find max register size.
>> 	(regcache_save): Use std::vector.
>> 	(regcache_restore): Likewise.
>> 	(regcache_dump): Likewise.
>> 	* regcache.h (max_register_size): New.
>> 	* remote.c (remote_prepare_to_store): Use std::vector.
>> 	* sol-thread.c (sol_thread_store_registers): Likewise.
>> 	* stack.c (frame_info): Likewise.
>> 	* target.c (debug_print_register): Likewise.
>> 
>> 
>> diff --git a/gdb/frame.c b/gdb/frame.c
>> index d98003dee7c34a63bd25356e6674721664a4b2f3..1700308371d9d795545c0a8bb26dba289b18217d 100644
>> --- a/gdb/frame.c
>> +++ b/gdb/frame.c
>> @@ -1252,10 +1252,10 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
>>   struct gdbarch *gdbarch = frame_unwind_arch (frame);
>>   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>>   int size = register_size (gdbarch, regnum);
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (size);
>> 
>> -  frame_unwind_register (frame, regnum, buf);
>> -  return extract_signed_integer (buf, size, byte_order);
>> +  frame_unwind_register (frame, regnum, buf.data ());
>> +  return extract_signed_integer (buf.data (), size, byte_order);
> 
> We can replace MAX_REGISTER_SIZE with 'sizeof (LONGEST)', because
> extract_signed_integer checks 'size' shouldn't be greater than
> 'sizeof (LONGEST)'.
> 
>  if (len > (int) sizeof (LONGEST))
>    error (_("\
> That operation is not available on integers of more than %d bytes."),
> 	   (int) sizeof (LONGEST));

Ok.

> 
>> }
>> 
>> LONGEST
>> @@ -1270,10 +1270,10 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
>>   struct gdbarch *gdbarch = frame_unwind_arch (frame);
>>   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>>   int size = register_size (gdbarch, regnum);
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (size);
> 
> Likewise,
> replace MAX_REGISTER_SIZE with 'sizeof (ULONGEST)’

Ok.

> 
>> 
>> -  frame_unwind_register (frame, regnum, buf);
>> -  return extract_unsigned_integer (buf, size, byte_order);
>> +  frame_unwind_register (frame, regnum, buf.data ());
>> +  return extract_unsigned_integer (buf.data (), size, byte_order);
>> }
>> 
>> ULONGEST
>> @@ -1389,6 +1389,8 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
>>     error (_("Bad debug information detected: "
>> 	     "Attempt to read %d bytes from registers."), len);
>> 
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>> +
>>   /* Copy the data.  */
>>   while (len > 0)
>>     {
>> @@ -1410,16 +1412,15 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
>> 	}
>>       else
>> 	{
>> -	  gdb_byte buf[MAX_REGISTER_SIZE];
>> 	  enum lval_type lval;
>> 	  CORE_ADDR addr;
>> 	  int realnum;
>> 
>> 	  frame_register (frame, regnum, optimizedp, unavailablep,
>> -			  &lval, &addr, &realnum, buf);
>> +			  &lval, &addr, &realnum, buf.data ());
> 
> I am wondering that we can replace frame_register with
> 
> value = frame_unwind_register_value (frame->next, regnum);
> 
> because frame_register -> frame_register_unwind  -> frame_unwind_register_value
> and we can get register contents from value, so we don't need 'buf' at all.

Ok.

> 
>> 	  if (*optimizedp || *unavailablep)
>> 	    return 0;
>> -	  memcpy (myaddr, buf + offset, curr_len);
>> +	  memcpy (myaddr, buf.data () + offset, curr_len);
>> 	}
>> 
>>       myaddr += curr_len;
>> @@ -1446,6 +1447,8 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
>>       regnum++;
>>     }
>> 
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>> +
>>   /* Copy the data.  */
>>   while (len > 0)
>>     {
>> @@ -1460,11 +1463,9 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
>> 	}
>>       else
>> 	{
>> -	  gdb_byte buf[MAX_REGISTER_SIZE];
>> -
>> -	  deprecated_frame_register_read (frame, regnum, buf);
>> -	  memcpy (buf + offset, myaddr, curr_len);
>> -	  put_frame_register (frame, regnum, buf);
>> +	  deprecated_frame_register_read (frame, regnum, buf.data ());
>> +	  memcpy (buf.data () + offset, myaddr, curr_len);
>> +	  put_frame_register (frame, regnum, buf.data ());
> 
> Can you try using frame_unwind_register_value to read the register value?
> Get the value content, patch it, and pass it to put_frame_register.

Yes. Technically, the value content is a const, but we need to cast from void* to char* anyway.

> 
>> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
>> index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..b07335d82723f3ee9c7602a8fa284acb7e3b3a25 100644
>> --- a/gdb/mi/mi-main.c
>> +++ b/gdb/mi/mi-main.c
>> @@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>> 		    struct regcache *this_regs)
>> {
>>   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
>> -  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
>> -  gdb_byte this_buffer[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> prev_buffer (max_register_size (gdbarch));
> 
> register_size (gdbarch, regnum) instead of max_register_size?

Ok.

> 
>> +  std::vector<gdb_byte> this_buffer (max_register_size (gdbarch));
>>   enum register_status prev_status;
>>   enum register_status this_status;
>> 
>> @@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>>     return 1;
>> 
>>   /* Get register contents and compare.  */
>> -  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
>> -  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
>> +  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
>> +  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());
>> 
>>   if (this_status != prev_status)
>>     return 1;
>>   else if (this_status == REG_VALID)
>> -    return memcmp (prev_buffer, this_buffer,
>> +    return memcmp (prev_buffer.data (), this_buffer.data (),
>> 		   register_size (gdbarch, regnum)) != 0;
>>   else
>>     return 0;
> 
>> diff --git a/gdb/record-full.c b/gdb/record-full.c
>> index fdd613b6e41bbfcd8644b02ccfeb98b53b518bff..a619e09a646c48c632a60407d7018979d805a08f 100644
>> --- a/gdb/record-full.c
>> +++ b/gdb/record-full.c
>> @@ -698,7 +698,7 @@ record_full_exec_insn (struct regcache *regcache,
>>     {
>>     case record_full_reg: /* reg */
>>       {
>> -        gdb_byte reg[MAX_REGISTER_SIZE];
>> +	std::vector<gdb_byte> reg (register_size (gdbarch, entry->u.reg.num));
>> 
>>         if (record_debug > 1)
>>           fprintf_unfiltered (gdb_stdlog,
>> @@ -707,10 +707,10 @@ record_full_exec_insn (struct regcache *regcache,
>>                               host_address_to_string (entry),
>>                               entry->u.reg.num);
>> 
>> -        regcache_cooked_read (regcache, entry->u.reg.num, reg);
>> -        regcache_cooked_write (regcache, entry->u.reg.num,
>> +	regcache_cooked_read (regcache, entry->u.reg.num, reg.data ());
>> +	regcache_cooked_write (regcache, entry->u.reg.num,
>> 			       record_full_get_loc (entry));
>> -        memcpy (record_full_get_loc (entry), reg, entry->u.reg.len);
>> +	memcpy (record_full_get_loc (entry), reg.data (), entry->u.reg.len);
> 
> Looks the code above copies register entry->u.reg.num contents from
> regcache to record_full_get_loc (entry), so we may rewrite the code using
> regcache_raw_collect,
> 
> regcache_raw_collect (regcache, entry->u.reg.num, record_full_get_loc (entry));
> 
> so array reg is not needed anymore.  Let me post a patch to fix it.

Looks to me like the three lines of code are swapping the contents of regcache
and record_full_get_loc.

temp <= regcache
regcache <= record_full_get_loc
record_full_get_loc <= temp

I can’t see a way of doing this without the buffer.
Left code as is in patch.


> 
>>       }
>>       break;
>> 
>> @@ -792,15 +792,17 @@ static void
>> record_full_core_open_1 (const char *name, int from_tty)
>> {
>>   struct regcache *regcache = get_current_regcache ();
>> -  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
>> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
>> +  int regnum = gdbarch_num_regs (gdbarch);
>> +  int regmaxsize = max_register_size (gdbarch);
>>   int i;
>> 
>>   /* Get record_full_core_regbuf.  */
>>   target_fetch_registers (regcache, -1);
>> -  record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum);
>> +  record_full_core_regbuf = (gdb_byte *) xmalloc (regmaxsize * regnum);
>>   for (i = 0; i < regnum; i ++)
>>     regcache_raw_collect (regcache, i,
>> -			  record_full_core_regbuf + MAX_REGISTER_SIZE * i);
>> +			  record_full_core_regbuf + regmaxsize * i);
>> 
>>   /* Get record_full_core_start and record_full_core_end.  */
>>   if (build_section_table (core_bfd, &record_full_core_start,
>> @@ -2038,6 +2040,9 @@ record_full_core_fetch_registers (struct target_ops *ops,
>> 				  struct regcache *regcache,
>> 				  int regno)
>> {
>> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
>> +  int regmaxsize = max_register_size (gdbarch);
>> +
>>   if (regno < 0)
>>     {
>>       int num = gdbarch_num_regs (get_regcache_arch (regcache));
>> @@ -2045,11 +2050,11 @@ record_full_core_fetch_registers (struct target_ops *ops,
>> 
>>       for (i = 0; i < num; i ++)
>>         regcache_raw_supply (regcache, i,
>> -                             record_full_core_regbuf + MAX_REGISTER_SIZE * i);
>> +			     record_full_core_regbuf + regmaxsize * i);
>>     }
>>   else
>>     regcache_raw_supply (regcache, regno,
>> -                         record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
>> +			 record_full_core_regbuf + regmaxsize * regno);
>> }
>> 
>> /* "to_prepare_to_store" method for prec over corefile.  */
>> @@ -2067,9 +2072,12 @@ record_full_core_store_registers (struct target_ops *ops,
>>                              struct regcache *regcache,
>>                              int regno)
>> {
>> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
>> +  int regmaxsize = max_register_size (gdbarch);
>> +
>>   if (record_full_gdb_operation_disable)
>>     regcache_raw_collect (regcache, regno,
>> -                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
>> +			  record_full_core_regbuf + regmaxsize * regno);
>>   else
>>     error (_("You can't do that without a process to debug."));
>> }
>> @@ -2265,7 +2273,7 @@ init_record_full_core_ops (void)
>>      record_full_reg:
>>        1 byte:  record type (record_full_reg, see enum record_full_type).
>>        8 bytes: register id (network byte order).
>> -       MAX_REGISTER_SIZE bytes: register value.
>> +       max_register_size bytes: register value.
>>      record_full_mem:
>>        1 byte:  record type (record_full_mem, see enum record_full_type).
>>        8 bytes: memory length (network byte order).
> 
> This comment is about log file format version 1, but we are using version 2, IIUC.
> We probably need to remove all the comments for version 1.
> 

Ok, removed all of Version 1 from section.

> 
>> @@ -327,7 +341,7 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
>> 	       void *src)
>> {
>>   struct gdbarch *gdbarch = dst->descr->gdbarch;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>>   int regnum;
>> 
>>   /* The DST should be `read-only', if it wasn't then the save would
>> @@ -346,10 +360,10 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
>>     {
>>       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
>> 	{
>> -	  enum register_status status = cooked_read (src, regnum, buf);
>> +	  enum register_status status = cooked_read (src, regnum, buf.data ());
>> 
>> 	  if (status == REG_VALID)
>> -	    memcpy (register_buffer (dst, regnum), buf,
>> +	    memcpy (register_buffer (dst, regnum), buf.data (),
>> 		    register_size (gdbarch, regnum));
>> 	  else
>> 	    {
> 
> Did you try removing variable 'buf'? like this,
> 
>  enum register_status status = cooked_read (src, regnum, register_buffer (dst, regnum));
> 
>  if (status != REG_VALID)
>    {
>       gdb_assert (status != REG_UNKNOWN);
> 
>      memset (register_buffer (dst, regnum), 0,
> 	      register_size (gdbarch, regnum));
>    }
> 
> I suppose function cooked_read shouldn't overflow the buffer (its third
> argument).

Ok.

> 
>> @@ -369,7 +383,7 @@ regcache_restore (struct regcache *dst,
>> 		  void *cooked_read_context)
>> {
>>   struct gdbarch *gdbarch = dst->descr->gdbarch;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>>   int regnum;
>> 
>>   /* The dst had better not be read-only.  If it is, the `restore'
>> @@ -385,9 +399,9 @@ regcache_restore (struct regcache *dst,
>> 	{
>> 	  enum register_status status;
>> 
>> -	  status = cooked_read (cooked_read_context, regnum, buf);
>> +	  status = cooked_read (cooked_read_context, regnum, buf.data ());
>> 	  if (status == REG_VALID)
>> -	    regcache_cooked_write (dst, regnum, buf);
>> +	    regcache_cooked_write (dst, regnum, buf.data ());
>> 	}
>>     }
>> }
>> @@ -1279,7 +1293,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>>   int footnote_register_offset = 0;
>>   int footnote_register_type_name_null = 0;
>>   long register_offset = 0;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>> 
>> #if 0
>>   fprintf_unfiltered (file, "nr_raw_registers %d\n",
>> @@ -1406,8 +1420,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>> 	    fprintf_unfiltered (file, "<unavailable>");
>> 	  else
>> 	    {
>> -	      regcache_raw_read (regcache, regnum, buf);
>> -	      print_hex_chars (file, buf,
>> +	      regcache_raw_read (regcache, regnum, buf.data ());
>> +	      print_hex_chars (file, buf.data (),
> 
> We can get register contents buffer by register_buffer (regcache, regnum),
> but we need to make sure that regcache is up-to-date.
> 
> Probably, we can add a function,
> 
> void
> regcache_raw_update (struct regcache *regcache, int regnum)
> {
>    if (!regcache->readonly_p
>      && regcache_register_status (regcache, regnum) == REG_UNKNOWN)
>    {
>      struct cleanup *old_chain = save_inferior_ptid ();
> 
>      inferior_ptid = regcache->ptid;
>      target_fetch_registers (regcache, regnum);
>      do_cleanups (old_chain);
> 
>      /* A number of targets can't access the whole set of raw
> 	 registers (because the debug API provides no means to get at
> 	 them).  */
>      if (regcache->register_status[regnum] == REG_UNKNOWN)
> 	regcache->register_status[regnum] = REG_UNAVAILABLE;
>    }
> }
> 
> in regcache_dump, we can call regcache_raw_update, and then get
> register contents from register_buffer (regcache, regnum).

Ok.

> 
>> 			       regcache->descr->sizeof_register[regnum],
>> 			       gdbarch_byte_order (gdbarch));
> 
> 
>> 	    }
>> @@ -1422,13 +1436,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>> 	    {
>> 	      enum register_status status;
>> 
>> -	      status = regcache_cooked_read (regcache, regnum, buf);
>> +	      status = regcache_cooked_read (regcache, regnum, buf.data ());
>> 	      if (status == REG_UNKNOWN)
>> 		fprintf_unfiltered (file, "<invalid>");
>> 	      else if (status == REG_UNAVAILABLE)
>> 		fprintf_unfiltered (file, "<unavailable>");
>> 	      else
>> -		print_hex_chars (file, buf,
>> +		print_hex_chars (file, buf.data (),
>> 				 regcache->descr->sizeof_register[regnum],
>> 				 gdbarch_byte_order (gdbarch));
>> 	    }
>> diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
>> index b0c68c617e365c0ea18ac2eca525598b688ffbb5..c5b1a480c52e12af01dc2d6c959fd429735bc805 100644
>> --- a/gdb/remote-sim.c
>> +++ b/gdb/remote-sim.c
>> @@ -439,6 +439,9 @@ gdbsim_fetch_register (struct target_ops *ops,
>>       return;
>>     }
>> 
>> +  int regsize = register_size (gdbarch, regno);
>> +  std::vector<gdb_byte> buf (regsize);
>> +
>>   switch (gdbarch_register_sim_regno (gdbarch, regno))
>>     {
>>     case LEGACY_SIM_REGNO_IGNORE:
>> @@ -447,10 +450,9 @@ gdbsim_fetch_register (struct target_ops *ops,
>>       {
>> 	/* For moment treat a `does not exist' register the same way
>> 	   as an ``unavailable'' register.  */
>> -	gdb_byte buf[MAX_REGISTER_SIZE];
>> 	int nr_bytes;
>> 
>> -	memset (buf, 0, MAX_REGISTER_SIZE);
>> +	memset (buf, 0, regsize);
> 
> memset to std::vector?

Doh!

> 
>> 	regcache_raw_supply (regcache, regno, buf);
>> 	break;
>>       }
>> @@ -458,18 +460,17 @@ gdbsim_fetch_register (struct target_ops *ops,
>>     default:
>>       {
>> 	static int warn_user = 1;
>> -	gdb_byte buf[MAX_REGISTER_SIZE];
>> 	int nr_bytes;
>> 
>> 	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
>> -	memset (buf, 0, MAX_REGISTER_SIZE);
>> +	memset (buf, 0, regsize);
>> 	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
>> 				       gdbarch_register_sim_regno
>> 					 (gdbarch, regno),
>> 				       buf,
> 
> 'buf' is a std::vector, so how does it compile?

Looks like remote-sim.c doesn’t get complied in if you don’t specify a sim at config time.
Hacking the makefile, I can get this to build, but I don’t have a sim, so can’t link the code.
Fixed up.


> 
>> diff --git a/gdb/remote.c b/gdb/remote.c
>> index c4cec910c44cf91cc7f36b7f2d87cde3f46de41e..157a1b1789d2a248c11dcc4efebd8ce54da82045 100644
>> --- a/gdb/remote.c
>> +++ b/gdb/remote.c
>> @@ -7757,9 +7757,10 @@ remote_fetch_registers (struct target_ops *ops,
>> static void
>> remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
>> {
>> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
>>   struct remote_arch_state *rsa = get_remote_arch_state ();
>>   int i;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>> 
>>   /* Make sure the entire registers array is valid.  */
>>   switch (packet_support (PACKET_P))
>> @@ -7769,7 +7770,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
>>       /* Make sure all the necessary registers are cached.  */
>>       for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
>> 	if (rsa->regs[i].in_g_packet)
>> -	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
>> +	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf.data ());
> 
> Use regcache_raw_update.

Ok.

> 
>>       break;
>>     case PACKET_ENABLE:
>>       break;
>> diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
>> index a09a3ab9a8bc56f367e3ba1537f5674f0a7f491f..5e7443a97624fbeae5b65cb534401e6371755423 100644
>> --- a/gdb/sol-thread.c
>> +++ b/gdb/sol-thread.c
>> @@ -514,6 +514,7 @@ sol_thread_store_registers (struct target_ops *ops,
>>   td_err_e val;
>>   prgregset_t gregset;
>>   prfpregset_t fpregset;
>> +  struct gdbarch *gdbarch = get_regcache_arch (regcache);
>> 
>>   if (!ptid_tid_p (inferior_ptid))
>>     {
>> @@ -535,10 +536,10 @@ sol_thread_store_registers (struct target_ops *ops,
>>   if (regnum != -1)
>>     {
>>       /* Not writing all the registers.  */
>> -      char old_value[MAX_REGISTER_SIZE];
>> +      std::vector<gdb_byte> old_value (register_size (gdbarch, regnum));
>> 
>>       /* Save new register value.  */
>> -      regcache_raw_collect (regcache, regnum, old_value);
>> +      regcache_raw_collect (regcache, regnum, old_value.data ());
>> 
>>       val = p_td_thr_getgregs (&thandle, gregset);
>>       if (val != TD_OK)
>> @@ -550,7 +551,7 @@ sol_thread_store_registers (struct target_ops *ops,
>> 	       td_err_string (val));
>> 
>>       /* Restore new register value.  */
>> -      regcache_raw_supply (regcache, regnum, old_value);
>> +      regcache_raw_supply (regcache, regnum, old_value.data ());
> 
> I don't understand why we collect all registers and restore them later.
> Will take a deeper look.

Looks like the collect and supply are entirely redundant!
p_td_thr_getgregs and p_td_thr_getfpregs are simple writing into the newly created
gregset/fpregset

The function should be doing:

* If regnum is a real register number then: read all registers from OS into gregset/fpregset,
  copy regnum from recache into struct, write struct back to OS
* If regnum is -1 then: copy all registers from regcache into gregset/fpregset, write struct to OS.
 
I’ll remove the bogus code.

> 
>>     }
>> 
>>   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
>> diff --git a/gdb/stack.c b/gdb/stack.c
>> index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..9b84435fe73b9af9b13f01c819f77f83bbb7117b 100644
>> --- a/gdb/stack.c
>> +++ b/gdb/stack.c
>> @@ -1667,16 +1667,16 @@ frame_info (char *addr_exp, int from_tty)
>> 	  {
>> 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>> 	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
>> -	    gdb_byte value[MAX_REGISTER_SIZE];
>> +	    std::vector<gdb_byte> value (sp_size);
>> 	    CORE_ADDR sp;
>> 
>> 	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
>> 				   &optimized, &unavailable, &lval, &addr,
>> -				   &realnum, value);
>> +				   &realnum, value.data ());
> 
> We can use frame_unwind_register_value.
> 

Ok.

>> 	    /* NOTE: cagney/2003-05-22: This is assuming that the
>>                stack pointer was packed as an unsigned integer.  That
>>                may or may not be valid.  */
>> -	    sp = extract_unsigned_integer (value, sp_size, byte_order);
>> +	    sp = extract_unsigned_integer (value.data (), sp_size, byte_order);
>> 	    printf_filtered (" Previous frame's sp is ");
>> 	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
>> 	    printf_filtered ("\n");
>> diff --git a/gdb/target.c b/gdb/target.c
>> index 3c409f0f619141205dfdcbbf8e46a277585ed683..52bb59255fcbdc74a674e08f6e168be5b6294819 100644
>> --- a/gdb/target.c
>> +++ b/gdb/target.c
>> @@ -3565,17 +3565,18 @@ debug_print_register (const char * func,
>>     {
>>       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>>       int i, size = register_size (gdbarch, regno);
>> -      gdb_byte buf[MAX_REGISTER_SIZE];
>> +      std::vector<gdb_byte> buf (size);
>> 
>> -      regcache_raw_collect (regcache, regno, buf);
>> +      regcache_raw_collect (regcache, regno, buf.data ());
>>       fprintf_unfiltered (gdb_stdlog, " = ");
>>       for (i = 0; i < size; i++)
>> 	{
>> -	  fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
>> +	  fprintf_unfiltered (gdb_stdlog, "%02x", buf.data ()[i]);
>> 	}
>>       if (size <= sizeof (LONGEST))
>> 	{
>> -	  ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
>> +	  ULONGEST val = extract_unsigned_integer (buf.data (), size,
>> +						   byte_order);
>> 
>> 	  fprintf_unfiltered (gdb_stdlog, " %s %s",
>> 			      core_addr_to_string_nz (val), plongest (val));
>> 
>> 
> 
> We can move debug_print_register to regcache.c, so that we can access
> register_buffer, and don't need 'buf' at all.
> 

Ok.

> -- 
> Yao (齐尧)


New version of the patch with all the changes above.

Alan.


2017-02-07  Alan Hayward  <alan.hayward@arm.com>

	* frame.c (frame_unwind_register_signed): Use LONGEST for size.
	(frame_unwind_register_unsigned): Use ULONGEST for size.
	(get_frame_register_bytes): Unwind register.
	(put_frame_register_bytes): Likewise.
	* i386-tdep.c (i386_pseudo_register_read_into_value): Use
	I386_MAX_REGISTER_SIZE.
	(i386_pseudo_register_write): Likewise.
	(i386_process_record): Likewise.
	* i387-tdep.c (i387_supply_xsave): Likewise.
	* m68k-linux-nat.c (fetch_register): Use M68K_MAX_REGISTER_SIZE.
	(store_register): Likewise.
	* mi/mi-main.c (register_changed_p): Use std::vector.
	* record-full.c (record_full_exec_insn): Likewise.
	(record_full_core_open_1): Use max_register_size ().
	(record_full_core_fetch_registers): Likewise.
	(record_full_core_store_registers): Likewise.
	(init_record_full_core_ops): Likewise.
	* remote-sim.c (gdbsim_fetch_register): Likewise.
	(gdbsim_store_register): Likewise.
	* regcache.c (struct regcache_descr): Add max_register_size.
	(max_register_size): New.
	(init_regcache_descr): Find max register size.
	(regcache_save): Use std::vector.
	(regcache_restore): Likewise.
	(regcache_raw_update): New function.
	(regcache_raw_read): Move checks to regcache_raw_update.
	(regcache_debug_print_register): New function.
	(regcache_dump): Call regcache_raw_update. Use std::vector.
	* regcache.h (max_register_size): New.
	(regcache_raw_update): New declaration.
	(regcache_debug_print_register): New declaration.
	* remote.c (remote_prepare_to_store): Call regcache_raw_update.
	* sol-thread.c (sol_thread_store_registers): Remove superfluous code.
	* stack.c (frame_info): Unwind sp register.
	* target.c (debug_print_register): Move to regcache.c
	(target_fetch_registers): Call regcache_debug_print_register.
	(target_store_registers): Likewise.



diff --git a/gdb/frame.c b/gdb/frame.c
index d98003dee7c34a63bd25356e6674721664a4b2f3..22cfdea4bcb20582229ffc360ead060c43d7cd81 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1252,7 +1252,11 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[sizeof (LONGEST)];
+
+  if (size > (int) sizeof (LONGEST))
+    error (_("Cannot unwind integers more than %d bytes."),
+	   (int) sizeof (LONGEST));

   frame_unwind_register (frame, regnum, buf);
   return extract_signed_integer (buf, size, byte_order);
@@ -1270,7 +1274,11 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[sizeof (ULONGEST)];
+
+  if (size > (int) sizeof (ULONGEST))
+    error (_("Cannot unwind integers more than %d bytes."),
+	   (int) sizeof (ULONGEST));

   frame_unwind_register (frame, regnum, buf);
   return extract_unsigned_integer (buf, size, byte_order);
@@ -1410,16 +1418,21 @@ get_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
-	  enum lval_type lval;
-	  CORE_ADDR addr;
-	  int realnum;
+	  struct value *value = frame_unwind_register_value (frame->next,
+							     regnum);
+	  gdb_assert (value != NULL);
+	  *optimizedp = value_optimized_out (value);
+	  *unavailablep = !value_entirely_available (value);

-	  frame_register (frame, regnum, optimizedp, unavailablep,
-			  &lval, &addr, &realnum, buf);
 	  if (*optimizedp || *unavailablep)
-	    return 0;
-	  memcpy (myaddr, buf + offset, curr_len);
+	    {
+	      release_value (value);
+	      value_free (value);
+	      return 0;
+	    }
+	  memcpy (myaddr, value_contents_all (value) + offset, curr_len);
+	  release_value (value);
+	  value_free (value);
 	}

       myaddr += curr_len;
@@ -1460,11 +1473,15 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  gdb_byte buf[MAX_REGISTER_SIZE];
-
-	  deprecated_frame_register_read (frame, regnum, buf);
-	  memcpy (buf + offset, myaddr, curr_len);
-	  put_frame_register (frame, regnum, buf);
+	  struct value *value = frame_unwind_register_value (frame->next,
+							     regnum);
+	  gdb_assert (value != NULL);
+
+	  memcpy ((char *) value_contents_all (value) + offset, myaddr,
+		  curr_len);
+	  put_frame_register (frame, regnum, value_contents_all (value));
+	  release_value (value);
+	  value_free (value);
 	}

       myaddr += curr_len;
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..081a16c6896ce7aee4db3b0be45fbbdd2c23dbdb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 				      int regnum,
 				      struct value *result_value)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);

@@ -3455,7 +3455,7 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 			    int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];

   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[I386_MAX_REGISTER_SIZE];
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index adbe72133089bc371108d5dd79bf8d8e61ba259c..fcd5ad248d6b737b9f27e294ce166a118e4bdcad 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -899,7 +899,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = (const gdb_byte *) xsave;
   int i;
   unsigned int clear_bv;
-  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
+  static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
   enum
     {
       none = 0x0,
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 6944c74eb198381135fda3ddf01b9da3a63e62d5..e5182caf39197f759c85c2321e4d66c428f5911e 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   long regaddr, val;
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
   int tid;

   /* Overload thread id onto process id.  */
@@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
   long regaddr, val;
   int i;
   int tid;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];

   /* Overload thread id onto process id.  */
   tid = ptid_get_lwp (inferior_ptid);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..11702c6c06c5cd791e03d99d56ef93d2c234862b 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
 		    struct regcache *this_regs)
 {
   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
-  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
-  gdb_byte this_buffer[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> prev_buffer (register_size (gdbarch, regnum));
+  std::vector<gdb_byte> this_buffer (register_size (gdbarch, regnum));
   enum register_status prev_status;
   enum register_status this_status;

@@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
     return 1;

   /* Get register contents and compare.  */
-  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
-  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
+  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
+  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());

   if (this_status != prev_status)
     return 1;
   else if (this_status == REG_VALID)
-    return memcmp (prev_buffer, this_buffer,
+    return memcmp (prev_buffer.data (), this_buffer.data (),
 		   register_size (gdbarch, regnum)) != 0;
   else
     return 0;
diff --git a/gdb/record-full.c b/gdb/record-full.c
index fdd613b6e41bbfcd8644b02ccfeb98b53b518bff..ada86cf6726176d93f61d85ef67290bca46c5b1a 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -698,7 +698,7 @@ record_full_exec_insn (struct regcache *regcache,
     {
     case record_full_reg: /* reg */
       {
-        gdb_byte reg[MAX_REGISTER_SIZE];
+	std::vector<gdb_byte> reg (register_size (gdbarch, entry->u.reg.num));

         if (record_debug > 1)
           fprintf_unfiltered (gdb_stdlog,
@@ -707,10 +707,10 @@ record_full_exec_insn (struct regcache *regcache,
                               host_address_to_string (entry),
                               entry->u.reg.num);

-        regcache_cooked_read (regcache, entry->u.reg.num, reg);
-        regcache_cooked_write (regcache, entry->u.reg.num,
+	regcache_cooked_read (regcache, entry->u.reg.num, reg.data ());
+	regcache_cooked_write (regcache, entry->u.reg.num,
 			       record_full_get_loc (entry));
-        memcpy (record_full_get_loc (entry), reg, entry->u.reg.len);
+	memcpy (record_full_get_loc (entry), reg.data (), entry->u.reg.len);
       }
       break;

@@ -792,15 +792,17 @@ static void
 record_full_core_open_1 (const char *name, int from_tty)
 {
   struct regcache *regcache = get_current_regcache ();
-  int regnum = gdbarch_num_regs (get_regcache_arch (regcache));
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regnum = gdbarch_num_regs (gdbarch);
+  int regmaxsize = max_register_size (gdbarch);
   int i;

   /* Get record_full_core_regbuf.  */
   target_fetch_registers (regcache, -1);
-  record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum);
+  record_full_core_regbuf = (gdb_byte *) xmalloc (regmaxsize * regnum);
   for (i = 0; i < regnum; i ++)
     regcache_raw_collect (regcache, i,
-			  record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			  record_full_core_regbuf + regmaxsize * i);

   /* Get record_full_core_start and record_full_core_end.  */
   if (build_section_table (core_bfd, &record_full_core_start,
@@ -2038,6 +2040,9 @@ record_full_core_fetch_registers (struct target_ops *ops,
 				  struct regcache *regcache,
 				  int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (regno < 0)
     {
       int num = gdbarch_num_regs (get_regcache_arch (regcache));
@@ -2045,11 +2050,11 @@ record_full_core_fetch_registers (struct target_ops *ops,

       for (i = 0; i < num; i ++)
         regcache_raw_supply (regcache, i,
-                             record_full_core_regbuf + MAX_REGISTER_SIZE * i);
+			     record_full_core_regbuf + regmaxsize * i);
     }
   else
     regcache_raw_supply (regcache, regno,
-                         record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			 record_full_core_regbuf + regmaxsize * regno);
 }

 /* "to_prepare_to_store" method for prec over corefile.  */
@@ -2067,9 +2072,12 @@ record_full_core_store_registers (struct target_ops *ops,
                              struct regcache *regcache,
                              int regno)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int regmaxsize = max_register_size (gdbarch);
+
   if (record_full_gdb_operation_disable)
     regcache_raw_collect (regcache, regno,
-                          record_full_core_regbuf + MAX_REGISTER_SIZE * regno);
+			  record_full_core_regbuf + regmaxsize * regno);
   else
     error (_("You can't do that without a process to debug."));
 }
@@ -2253,25 +2261,6 @@ init_record_full_core_ops (void)
 }

 /* Record log save-file format
-   Version 1 (never released)
-
-   Header:
-     4 bytes: magic number htonl(0x20090829).
-       NOTE: be sure to change whenever this file format changes!
-
-   Records:
-     record_full_end:
-       1 byte:  record type (record_full_end, see enum record_full_type).
-     record_full_reg:
-       1 byte:  record type (record_full_reg, see enum record_full_type).
-       8 bytes: register id (network byte order).
-       MAX_REGISTER_SIZE bytes: register value.
-     record_full_mem:
-       1 byte:  record type (record_full_mem, see enum record_full_type).
-       8 bytes: memory length (network byte order).
-       8 bytes: memory address (network byte order).
-       n bytes: memory value (n == memory length).
-
    Version 2
      4 bytes: magic number netorder32(0x20091016).
        NOTE: be sure to change whenever this file format changes!
diff --git a/gdb/regcache.h b/gdb/regcache.h
index e5a7cf553279b8cc0d546ec1b8274cbf97e246d5..f8d8f2f84887cb9bb2541f68367f5269b75deb56 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -50,6 +50,12 @@ extern struct address_space *get_regcache_aspace (const struct regcache *);
 enum register_status regcache_register_status (const struct regcache *regcache,
 					       int regnum);

+/* Make certain that the register cache is up-to-date with respect to the
+   current thread.  */
+void regcache_raw_update (struct regcache *regcache, int regnum);
+
+enum register_status regcache_raw_read (struct regcache *regcache,
+					int rawnum, gdb_byte *buf);
 /* Transfer a raw register [0..NUM_REGS) between core-gdb and the
    regcache.  The read variants return the status of the register.  */

@@ -202,6 +208,8 @@ extern struct type *register_type (struct gdbarch *gdbarch, int regnum);

 extern int register_size (struct gdbarch *gdbarch, int regnum);

+/* Return the size of the largest register.  */
+extern long max_register_size (struct gdbarch *gdbarch);

 /* Save/restore a register cache.  The set of registers saved /
    restored into the DST regcache determined by the save_reggroup /
@@ -228,4 +236,8 @@ extern void regcache_cpy (struct regcache *dest, struct regcache *src);
 extern void registers_changed (void);
 extern void registers_changed_ptid (ptid_t);

+extern void regcache_debug_print_register (const char *func,
+					   struct regcache *regcache,
+					   int regno);
+
 #endif /* REGCACHE_H */
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 9d28aa2c2114e0f1c52758bb2fbe9669a329c13e..7d693ac616c3c8e692d369d748937ac4662c849a 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -73,6 +73,9 @@ struct regcache_descr

   /* Cached table containing the type of each register.  */
   struct type **register_type;
+
+  /* Size of the largest register.  */
+  long max_register_size;
 };

 static void *
@@ -126,6 +129,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the raw register cache buffer.  */
     descr->sizeof_raw_registers = offset;
@@ -136,6 +141,8 @@ init_regcache_descr (struct gdbarch *gdbarch)
 	descr->register_offset[i] = offset;
 	offset += descr->sizeof_register[i];
 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
+	descr->max_register_size = std::max (descr->max_register_size,
+					     descr->sizeof_register[i]);
       }
     /* Set the real size of the readonly register cache buffer.  */
     descr->sizeof_cooked_registers = offset;
@@ -187,6 +194,13 @@ regcache_register_size (const struct regcache *regcache, int n)
   return register_size (get_regcache_arch (regcache), n);
 }

+long
+max_register_size (struct gdbarch *gdbarch)
+{
+  struct regcache_descr *descr = regcache_descr (gdbarch);
+  return descr->max_register_size;
+}
+
 /* The register cache for storing raw register values.  */

 struct regcache
@@ -327,7 +341,6 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
 	       void *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
   int regnum;

   /* The DST should be `read-only', if it wasn't then the save would
@@ -346,12 +359,10 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
 	{
+	  gdb_byte *buf = register_buffer (dst, regnum);
 	  enum register_status status = cooked_read (src, regnum, buf);

-	  if (status == REG_VALID)
-	    memcpy (register_buffer (dst, regnum), buf,
-		    register_size (gdbarch, regnum));
-	  else
+	  if (status != REG_VALID)
 	    {
 	      gdb_assert (status != REG_UNKNOWN);

@@ -369,7 +380,7 @@ regcache_restore (struct regcache *dst,
 		  void *cooked_read_context)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));
   int regnum;

   /* The dst had better not be read-only.  If it is, the `restore'
@@ -385,9 +396,9 @@ regcache_restore (struct regcache *dst,
 	{
 	  enum register_status status;

-	  status = cooked_read (cooked_read_context, regnum, buf);
+	  status = cooked_read (cooked_read_context, regnum, buf.data ());
 	  if (status == REG_VALID)
-	    regcache_cooked_write (dst, regnum, buf);
+	    regcache_cooked_write (dst, regnum, buf.data ());
 	}
     }
 }
@@ -642,15 +653,17 @@ registers_changed (void)
   alloca (0);
 }

-enum register_status
-regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+void
+regcache_raw_update (struct regcache *regcache, int regnum)
 {
-  gdb_assert (regcache != NULL && buf != NULL);
-  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   /* Make certain that the register cache is up-to-date with respect
      to the current thread.  This switching shouldn't be necessary
      only there is still only one target side register cache.  Sigh!
      On the bright side, at least there is a regcache object.  */
+
+  gdb_assert (regcache != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+
   if (!regcache->readonly_p
       && regcache_register_status (regcache, regnum) == REG_UNKNOWN)
     {
@@ -666,6 +679,13 @@ regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
       if (regcache->register_status[regnum] == REG_UNKNOWN)
 	regcache->register_status[regnum] = REG_UNAVAILABLE;
     }
+}
+
+enum register_status
+regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+{
+  gdb_assert (buf != NULL);
+  regcache_raw_update (regcache, regnum);

   if (regcache->register_status[regnum] != REG_VALID)
     memset (buf, 0, regcache->descr->sizeof_register[regnum]);
@@ -1250,6 +1270,42 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
   reinit_frame_cache ();
 }

+void
+regcache_debug_print_register (const char *func, struct regcache *regcache,
+			       int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+  fprintf_unfiltered (gdb_stdlog, "%s ", func);
+  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
+      && gdbarch_register_name (gdbarch, regno) != NULL
+      && gdbarch_register_name (gdbarch, regno)[0] != '\0')
+    fprintf_unfiltered (gdb_stdlog, "(%s)",
+			gdbarch_register_name (gdbarch, regno));
+  else
+    fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
+    {
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      int i, size = register_size (gdbarch, regno);
+      gdb_byte *buf = register_buffer (regcache, regno);
+
+      regcache_raw_collect (regcache, regno, buf);
+      fprintf_unfiltered (gdb_stdlog, " = ");
+      for (i = 0; i < size; i++)
+	{
+	  fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+	}
+      if (size <= sizeof (LONGEST))
+	{
+	  ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
+
+	  fprintf_unfiltered (gdb_stdlog, " %s %s",
+			      core_addr_to_string_nz (val), plongest (val));
+	}
+    }
+  fprintf_unfiltered (gdb_stdlog, "\n");
+}

 static void
 reg_flush_command (char *command, int from_tty)
@@ -1279,7 +1335,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
   int footnote_register_offset = 0;
   int footnote_register_type_name_null = 0;
   long register_offset = 0;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  std::vector<gdb_byte> buf (max_register_size (gdbarch));

 #if 0
   fprintf_unfiltered (file, "nr_raw_registers %d\n",
@@ -1406,8 +1462,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    fprintf_unfiltered (file, "<unavailable>");
 	  else
 	    {
-	      regcache_raw_read (regcache, regnum, buf);
-	      print_hex_chars (file, buf,
+	      regcache_raw_update (regcache, regnum);
+	      print_hex_chars (file, register_buffer (regcache, regnum),
 			       regcache->descr->sizeof_register[regnum],
 			       gdbarch_byte_order (gdbarch));
 	    }
@@ -1422,13 +1478,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
 	    {
 	      enum register_status status;

-	      status = regcache_cooked_read (regcache, regnum, buf);
+	      status = regcache_cooked_read (regcache, regnum, buf.data ());
 	      if (status == REG_UNKNOWN)
 		fprintf_unfiltered (file, "<invalid>");
 	      else if (status == REG_UNAVAILABLE)
 		fprintf_unfiltered (file, "<unavailable>");
 	      else
-		print_hex_chars (file, buf,
+		print_hex_chars (file, buf.data (),
 				 regcache->descr->sizeof_register[regnum],
 				 gdbarch_byte_order (gdbarch));
 	    }
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index b0c68c617e365c0ea18ac2eca525598b688ffbb5..0dd901377e53eafc27e4fb39a1453380779ae361 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -439,6 +439,9 @@ gdbsim_fetch_register (struct target_ops *ops,
       return;
     }

+  int regsize = register_size (gdbarch, regno);
+  std::vector<gdb_byte> buf (regsize);
+
   switch (gdbarch_register_sim_regno (gdbarch, regno))
     {
     case LEGACY_SIM_REGNO_IGNORE:
@@ -447,38 +450,32 @@ gdbsim_fetch_register (struct target_ops *ops,
       {
 	/* For moment treat a `does not exist' register the same way
 	   as an ``unavailable'' register.  */
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

-	memset (buf, 0, MAX_REGISTER_SIZE);
-	regcache_raw_supply (regcache, regno, buf);
+	regcache_raw_supply (regcache, regno, buf.data ());
 	break;
       }

     default:
       {
 	static int warn_user = 1;
-	gdb_byte buf[MAX_REGISTER_SIZE];
 	int nr_bytes;

 	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
-	memset (buf, 0, MAX_REGISTER_SIZE);
 	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
 				       gdbarch_register_sim_regno
 					 (gdbarch, regno),
-				       buf,
-				       register_size (gdbarch, regno));
+				       buf.data (), regsize);
 	if (nr_bytes > 0
-	    && nr_bytes != register_size (gdbarch, regno) && warn_user)
+	    && nr_bytes != regsize && warn_user)
 	  {
 	    fprintf_unfiltered (gdb_stderr,
 				"Size of register %s (%d/%d) "
 				"incorrect (%d instead of %d))",
 				gdbarch_register_name (gdbarch, regno),
 				regno,
-				gdbarch_register_sim_regno
-				  (gdbarch, regno),
-				nr_bytes, register_size (gdbarch, regno));
+				gdbarch_register_sim_regno (gdbarch, regno),
+				nr_bytes, regsize);
 	    warn_user = 0;
 	  }
 	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
@@ -486,13 +483,13 @@ gdbsim_fetch_register (struct target_ops *ops,
 	   which registers are fetchable.  */
 	/* Else if (nr_bytes < 0): an old simulator, that doesn't
 	   think to return the register size.  Just assume all is ok.  */
-	regcache_raw_supply (regcache, regno, buf);
+	regcache_raw_supply (regcache, regno, buf.data ());
 	if (remote_debug)
 	  {
 	    fprintf_unfiltered (gdb_stdlog,
 				"gdbsim_fetch_register: %d", regno);
 	    /* FIXME: We could print something more intelligible.  */
-	    dump_mem (buf, register_size (gdbarch, regno));
+	    dump_mem (buf.data (), regsize);
 	  }
 	break;
       }
@@ -516,15 +513,16 @@ gdbsim_store_register (struct target_ops *ops,
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
     {
-      gdb_byte tmp[MAX_REGISTER_SIZE];
+      int regsize = register_size (gdbarch, regno);
+      std::vector<gdb_byte> tmp (regsize);
       int nr_bytes;

-      regcache_cooked_read (regcache, regno, tmp);
+      regcache_cooked_read (regcache, regno, tmp.data ());
       nr_bytes = sim_store_register (sim_data->gdbsim_desc,
 				     gdbarch_register_sim_regno
 				       (gdbarch, regno),
-				     tmp, register_size (gdbarch, regno));
-      if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno))
+				     tmp.data (), regsize);
+      if (nr_bytes > 0 && nr_bytes != regsize)
 	internal_error (__FILE__, __LINE__,
 			_("Register size different to expected"));
       if (nr_bytes < 0)
@@ -538,7 +536,7 @@ gdbsim_store_register (struct target_ops *ops,
 	{
 	  fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno);
 	  /* FIXME: We could print something more intelligible.  */
-	  dump_mem (tmp, register_size (gdbarch, regno));
+	  dump_mem (tmp.data (), regsize);
 	}
     }
 }
diff --git a/gdb/remote.c b/gdb/remote.c
index c4cec910c44cf91cc7f36b7f2d87cde3f46de41e..0eeba218ea4846466746817e8e79a5bbe84fba95 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -7759,7 +7759,6 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 {
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];

   /* Make sure the entire registers array is valid.  */
   switch (packet_support (PACKET_P))
@@ -7769,7 +7768,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
       /* Make sure all the necessary registers are cached.  */
       for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
 	if (rsa->regs[i].in_g_packet)
-	  regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
+	  regcache_raw_update (regcache, rsa->regs[i].regnum);
       break;
     case PACKET_ENABLE:
       break;
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index a09a3ab9a8bc56f367e3ba1537f5674f0a7f491f..06b146c314a10be0e360a7242bab229ced1c00b1 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -534,12 +534,6 @@ sol_thread_store_registers (struct target_ops *ops,

   if (regnum != -1)
     {
-      /* Not writing all the registers.  */
-      char old_value[MAX_REGISTER_SIZE];
-
-      /* Save new register value.  */
-      regcache_raw_collect (regcache, regnum, old_value);
-
       val = p_td_thr_getgregs (&thandle, gregset);
       if (val != TD_OK)
 	error (_("sol_thread_store_registers: td_thr_getgregs %s"),
@@ -548,9 +542,6 @@ sol_thread_store_registers (struct target_ops *ops,
       if (val != TD_OK)
 	error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
 	       td_err_string (val));
-
-      /* Restore new register value.  */
-      regcache_raw_supply (regcache, regnum, old_value);
     }

   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
diff --git a/gdb/stack.c b/gdb/stack.c
index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..7ba7d68bde8d83ea1e700faa466c6951979e0f76 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1650,33 +1650,35 @@ frame_info (char *addr_exp, int from_tty)
     int count;
     int i;
     int need_nl = 1;
+    int sp_regnum = gdbarch_sp_regnum (gdbarch);

     /* The sp is special; what's displayed isn't the save address, but
        the value of the previous frame's sp.  This is a legacy thing,
        at one stage the frame cached the previous frame's SP instead
        of its address, hence it was easiest to just display the cached
        value.  */
-    if (gdbarch_sp_regnum (gdbarch) >= 0)
+    if (sp_regnum >= 0)
       {
 	/* Find out the location of the saved stack pointer with out
            actually evaluating it.  */
-	frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
-			       &optimized, &unavailable, &lval, &addr,
-			       &realnum, NULL);
+	frame_register_unwind (fi, sp_regnum, &optimized, &unavailable, &lval,
+			       &addr, &realnum, NULL);
 	if (!optimized && !unavailable && lval == not_lval)
 	  {
 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
-	    gdb_byte value[MAX_REGISTER_SIZE];
+	    int sp_size = register_size (gdbarch, sp_regnum);
 	    CORE_ADDR sp;
+	    struct value *value = frame_unwind_register_value (fi, sp_regnum);

-	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
-				   &optimized, &unavailable, &lval, &addr,
-				   &realnum, value);
+	    gdb_assert (value != NULL);
 	    /* NOTE: cagney/2003-05-22: This is assuming that the
                stack pointer was packed as an unsigned integer.  That
                may or may not be valid.  */
-	    sp = extract_unsigned_integer (value, sp_size, byte_order);
+	    sp = extract_unsigned_integer (value_contents_all (value), sp_size,
+					   byte_order);
+	    release_value (value);
+	    value_free (value);
+
 	    printf_filtered (" Previous frame's sp is ");
 	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
 	    printf_filtered ("\n");
@@ -1702,7 +1704,7 @@ frame_info (char *addr_exp, int from_tty)
     numregs = gdbarch_num_regs (gdbarch)
 	      + gdbarch_num_pseudo_regs (gdbarch);
     for (i = 0; i < numregs; i++)
-      if (i != gdbarch_sp_regnum (gdbarch)
+      if (i != sp_regnum
 	  && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
 	{
 	  /* Find out the location of the saved register without
diff --git a/gdb/target.c b/gdb/target.c
index 3c409f0f619141205dfdcbbf8e46a277585ed683..ae1321c57983fe3446148090e1d0a4aa823a3b19 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3547,49 +3547,12 @@ target_options_to_string (int target_options)
   return ret;
 }

-static void
-debug_print_register (const char * func,
-		      struct regcache *regcache, int regno)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
-  fprintf_unfiltered (gdb_stdlog, "%s ", func);
-  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
-      && gdbarch_register_name (gdbarch, regno) != NULL
-      && gdbarch_register_name (gdbarch, regno)[0] != '\0')
-    fprintf_unfiltered (gdb_stdlog, "(%s)",
-			gdbarch_register_name (gdbarch, regno));
-  else
-    fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
-  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
-    {
-      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      int i, size = register_size (gdbarch, regno);
-      gdb_byte buf[MAX_REGISTER_SIZE];
-
-      regcache_raw_collect (regcache, regno, buf);
-      fprintf_unfiltered (gdb_stdlog, " = ");
-      for (i = 0; i < size; i++)
-	{
-	  fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
-	}
-      if (size <= sizeof (LONGEST))
-	{
-	  ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
-
-	  fprintf_unfiltered (gdb_stdlog, " %s %s",
-			      core_addr_to_string_nz (val), plongest (val));
-	}
-    }
-  fprintf_unfiltered (gdb_stdlog, "\n");
-}
-
 void
 target_fetch_registers (struct regcache *regcache, int regno)
 {
   current_target.to_fetch_registers (&current_target, regcache, regno);
   if (targetdebug)
-    debug_print_register ("target_fetch_registers", regcache, regno);
+    regcache_debug_print_register ("target_fetch_registers", regcache, regno);
 }

 void
@@ -3601,7 +3564,8 @@ target_store_registers (struct regcache *regcache, int regno)
   current_target.to_store_registers (&current_target, regcache, regno);
   if (targetdebug)
     {
-      debug_print_register ("target_store_registers", regcache, regno);
+      regcache_debug_print_register ("target_store_registers", regcache,
+				     regno);
     }
 }





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
@ 2017-02-08 10:47                         ` Yao Qi
  2017-02-08 14:17                           ` Alan Hayward
  2017-02-08 12:06                         ` Yao Qi
                                           ` (4 subsequent siblings)
  5 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-08 10:47 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

On 17-02-07 16:33:19, Alan Hayward wrote:

Hi Alan,
We end up having multiple different ways removing MAX_REGISTER_SIZE, and
each change is quite independent.  I'll split it in my review, and you can
to post a patch set in the next version.

> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..081a16c6896ce7aee4db3b0be45fbbdd2c23dbdb 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
>  				      int regnum,
>  				      struct value *result_value)
>  {
> -  gdb_byte raw_buf[MAX_REGISTER_SIZE];
> +  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
>    enum register_status status;
>    gdb_byte *buf = value_contents_raw (result_value);
> 
> @@ -3455,7 +3455,7 @@ void
>  i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>  			    int regnum, const gdb_byte *buf)
>  {
> -  gdb_byte raw_buf[MAX_REGISTER_SIZE];
> +  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
> 
>    if (i386_mmx_regnum_p (gdbarch, regnum))
>      {
> @@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>    uint32_t opcode;
>    uint8_t opcode8;
>    ULONGEST addr;
> -  gdb_byte buf[MAX_REGISTER_SIZE];
> +  gdb_byte buf[I386_MAX_REGISTER_SIZE];
>    struct i386_record_s ir;
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>    uint8_t rex_w = -1;
> diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
> index adbe72133089bc371108d5dd79bf8d8e61ba259c..fcd5ad248d6b737b9f27e294ce166a118e4bdcad 100644
> --- a/gdb/i387-tdep.c
> +++ b/gdb/i387-tdep.c
> @@ -899,7 +899,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>    const gdb_byte *regs = (const gdb_byte *) xsave;
>    int i;
>    unsigned int clear_bv;
> -  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
> +  static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
>    enum
>      {
>        none = 0x0,
> diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
> index 6944c74eb198381135fda3ddf01b9da3a63e62d5..e5182caf39197f759c85c2321e4d66c428f5911e 100644
> --- a/gdb/m68k-linux-nat.c
> +++ b/gdb/m68k-linux-nat.c
> @@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
>    struct gdbarch *gdbarch = get_regcache_arch (regcache);
>    long regaddr, val;
>    int i;
> -  gdb_byte buf[MAX_REGISTER_SIZE];
> +  gdb_byte buf[M68K_MAX_REGISTER_SIZE];

Nit, we can even reduce the size of 'buf' to sizeof (long), because the
code read/write register by PTRACE_PEEKUSER/PTRACE_POKEUSER which is
word-wide operation.

>    int tid;
> 
>    /* Overload thread id onto process id.  */
> @@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
>    long regaddr, val;
>    int i;
>    int tid;
> -  gdb_byte buf[MAX_REGISTER_SIZE];
> +  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
> 
>    /* Overload thread id onto process id.  */
>    tid = ptid_get_lwp (inferior_ptid);

This part is OK.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
  2017-02-08 10:47                         ` Yao Qi
@ 2017-02-08 12:06                         ` Yao Qi
  2017-02-08 12:24                         ` Yao Qi
                                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 28+ messages in thread
From: Yao Qi @ 2017-02-08 12:06 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd

On Tue, Feb 7, 2017 at 4:33 PM, Alan Hayward <Alan.Hayward@arm.com> wrote:

> diff --git a/gdb/stack.c b/gdb/stack.c
> index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..7ba7d68bde8d83ea1e700faa466c6951979e0f76 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -1650,33 +1650,35 @@ frame_info (char *addr_exp, int from_tty)
>      int count;
>      int i;
>      int need_nl = 1;
> +    int sp_regnum = gdbarch_sp_regnum (gdbarch);
>
>      /* The sp is special; what's displayed isn't the save address, but
>         the value of the previous frame's sp.  This is a legacy thing,
>         at one stage the frame cached the previous frame's SP instead
>         of its address, hence it was easiest to just display the cached
>         value.  */
> -    if (gdbarch_sp_regnum (gdbarch) >= 0)
> +    if (sp_regnum >= 0)
>        {
>         /* Find out the location of the saved stack pointer with out
>             actually evaluating it.  */
> -       frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
> -                              &optimized, &unavailable, &lval, &addr,
> -                              &realnum, NULL);
> +       frame_register_unwind (fi, sp_regnum, &optimized, &unavailable, &lval,
> +                              &addr, &realnum, NULL);
>         if (!optimized && !unavailable && lval == not_lval)
>           {
>             enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -           int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
> -           gdb_byte value[MAX_REGISTER_SIZE];
> +           int sp_size = register_size (gdbarch, sp_regnum);
>             CORE_ADDR sp;
> +           struct value *value = frame_unwind_register_value (fi, sp_regnum);
>

Why don't you hoist frame_unwind_register_value above?, so the
frame_register_unwind call is no longer needed,

  struct value *value = frame_unwind_register_value (fi, sp_regnum);

  gdb_assert (value != NULL);

  if (!value_optimized_out (value) && value_entirely_available (value))
     {
       if (VALUE_LVAL (value) == not_lval)
         {
            sp = extract_unsigned_integer (value_contents_all (value),
                                          sp_size, byte_order);
         }
       else if (VALUE_LVAL (value) == lval_memory)
         {
            // use value_address (value);
         }
       else if (VALUE_LVAL (value) == lval_register)
         {
            // use VALUE_REGNUM (value);
         }
     }
   /* else keep quiet.  */

   release_value (value);
   value_free (value);

> -           frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
> -                                  &optimized, &unavailable, &lval, &addr,
> -                                  &realnum, value);
> +           gdb_assert (value != NULL);
>             /* NOTE: cagney/2003-05-22: This is assuming that the
>                 stack pointer was packed as an unsigned integer.  That
>                 may or may not be valid.  */
> -           sp = extract_unsigned_integer (value, sp_size, byte_order);
> +           sp = extract_unsigned_integer (value_contents_all (value), sp_size,
> +                                          byte_order);
> +           release_value (value);
> +           value_free (value);
> +
>             printf_filtered (" Previous frame's sp is ");
>             fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
>             printf_filtered ("\n");

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
  2017-02-08 10:47                         ` Yao Qi
  2017-02-08 12:06                         ` Yao Qi
@ 2017-02-08 12:24                         ` Yao Qi
  2017-02-08 14:44                           ` Alan Hayward
  2017-02-08 15:32                         ` Yao Qi
                                           ` (2 subsequent siblings)
  5 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-08 12:24 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

Alan Hayward <Alan.Hayward@arm.com> writes:

> diff --git a/gdb/stack.c b/gdb/stack.c
> index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..7ba7d68bde8d83ea1e700faa466c6951979e0f76 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -1650,33 +1650,35 @@ frame_info (char *addr_exp, int from_tty)
>      int count;
>      int i;
>      int need_nl = 1;
> +    int sp_regnum = gdbarch_sp_regnum (gdbarch);
>
>      /* The sp is special; what's displayed isn't the save address, but
>         the value of the previous frame's sp.  This is a legacy thing,
>         at one stage the frame cached the previous frame's SP instead
>         of its address, hence it was easiest to just display the cached
>         value.  */
> -    if (gdbarch_sp_regnum (gdbarch) >= 0)
> +    if (sp_regnum >= 0)
>        {
>  	/* Find out the location of the saved stack pointer with out
>             actually evaluating it.  */
> -	frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
> -			       &optimized, &unavailable, &lval, &addr,
> -			       &realnum, NULL);
> +	frame_register_unwind (fi, sp_regnum, &optimized, &unavailable, &lval,
> +			       &addr, &realnum, NULL);
>  	if (!optimized && !unavailable && lval == not_lval)
>  	  {
>  	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
> -	    gdb_byte value[MAX_REGISTER_SIZE];
> +	    int sp_size = register_size (gdbarch, sp_regnum);
>  	    CORE_ADDR sp;
> +	    struct value *value = frame_unwind_register_value (fi, sp_regnum);
>
> -	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
> -				   &optimized, &unavailable, &lval, &addr,
> -				   &realnum, value);
> +	    gdb_assert (value != NULL);

Why don't you hoist frame_unwind_register_value above?, so the
frame_register_unwind call is no longer needed,


  struct value *value = frame_unwind_register_value (fi, sp_regnum);

  gdb_assert (value != NULL);

  if (!value_optimized_out (value) && value_entirely_available (value))
     {
       if (VALUE_LVAL (value) == not_lval)
         {
            sp = extract_unsigned_integer (value_contents_all (value),
                                          sp_size, byte_order);
         }
       else if (VALUE_LVAL (value) == lval_memory)
         {
            // use value_address (value);
         }
       else if (VALUE_LVAL (value) == lval_register)
         {
            // use VALUE_REGNUM (value);
         }
     }
   /* else keep quiet.  */

   release_value (value);
   value_free (value);

>  	    /* NOTE: cagney/2003-05-22: This is assuming that the
>                 stack pointer was packed as an unsigned integer.  That
>                 may or may not be valid.  */
> -	    sp = extract_unsigned_integer (value, sp_size, byte_order);
> +	    sp = extract_unsigned_integer (value_contents_all (value), sp_size,
> +					   byte_order);
> +	    release_value (value);
> +	    value_free (value);
> +
>  	    printf_filtered (" Previous frame's sp is ");
>  	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
>  	    printf_filtered ("\n");
> @@ -1702,7 +1704,7 @@ frame_info (char *addr_exp, int from_tty)
>      numregs = gdbarch_num_regs (gdbarch)
>  	      + gdbarch_num_pseudo_regs (gdbarch);
>      for (i = 0; i < numregs; i++)
> -      if (i != gdbarch_sp_regnum (gdbarch)
> +      if (i != sp_regnum
>  	  && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
>  	{
>  	  /* Find out the location of the saved register without

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 10:47                         ` Yao Qi
@ 2017-02-08 14:17                           ` Alan Hayward
  0 siblings, 0 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-08 14:17 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd

(Resend, in plain text format)

> On 8 Feb 2017, at 10:47, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> On 17-02-07 16:33:19, Alan Hayward wrote:
> 
> Hi Alan,
> We end up having multiple different ways removing MAX_REGISTER_SIZE, and
> each change is quite independent.  I'll split it in my review, and you can
> to post a patch set in the next version.
> 
>> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
>> index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..081a16c6896ce7aee4db3b0be45fbbdd2c23dbdb 100644
>> --- a/gdb/i386-tdep.c
>> +++ b/gdb/i386-tdep.c
>> @@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
>> 				      int regnum,
>> 				      struct value *result_value)
>> {
>> -  gdb_byte raw_buf[MAX_REGISTER_SIZE];
>> +  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
>>   enum register_status status;
>>   gdb_byte *buf = value_contents_raw (result_value);
>> 
>> @@ -3455,7 +3455,7 @@ void
>> i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>> 			    int regnum, const gdb_byte *buf)
>> {
>> -  gdb_byte raw_buf[MAX_REGISTER_SIZE];
>> +  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
>> 
>>   if (i386_mmx_regnum_p (gdbarch, regnum))
>>     {
>> @@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>>   uint32_t opcode;
>>   uint8_t opcode8;
>>   ULONGEST addr;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  gdb_byte buf[I386_MAX_REGISTER_SIZE];
>>   struct i386_record_s ir;
>>   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>>   uint8_t rex_w = -1;
>> diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
>> index adbe72133089bc371108d5dd79bf8d8e61ba259c..fcd5ad248d6b737b9f27e294ce166a118e4bdcad 100644
>> --- a/gdb/i387-tdep.c
>> +++ b/gdb/i387-tdep.c
>> @@ -899,7 +899,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>>   const gdb_byte *regs = (const gdb_byte *) xsave;
>>   int i;
>>   unsigned int clear_bv;
>> -  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
>> +  static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
>>   enum
>>     {
>>       none = 0x0,
>> diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
>> index 6944c74eb198381135fda3ddf01b9da3a63e62d5..e5182caf39197f759c85c2321e4d66c428f5911e 100644
>> --- a/gdb/m68k-linux-nat.c
>> +++ b/gdb/m68k-linux-nat.c
>> @@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
>>   struct gdbarch *gdbarch = get_regcache_arch (regcache);
>>   long regaddr, val;
>>   int i;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
> 
> Nit, we can even reduce the size of 'buf' to sizeof (long), because the
> code read/write register by PTRACE_PEEKUSER/PTRACE_POKEUSER which is
> word-wide operation.

That wouldn't work.
The code calls memcpy on the buffer using buf[i] up to max size of register_size (gdbarch, regno).

> 
>>   int tid;
>> 
>>   /* Overload thread id onto process id.  */
>> @@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
>>   long regaddr, val;
>>   int i;
>>   int tid;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
>> 
>>   /* Overload thread id onto process id.  */
>>   tid = ptid_get_lwp (inferior_ptid);
> 
> This part is OK.
> 
> -- 
> Yao (齐尧)

The full M68K_MAX_REGISTER_SIZE/I386_MAX_REGISTER_SIZE changes as a single patch:

2017-02-08  Alan Hayward  <alan.hayward@arm.com>

	* i386-tdep.c (i386_pseudo_register_read_into_value): Use
	I386_MAX_REGISTER_SIZE.
	(i386_pseudo_register_write): Likewise.
	(i386_process_record): Likewise.
	* i387-tdep.c (i387_supply_xsave): Likewise.
	* m68k-linux-nat.c (fetch_register): Use M68K_MAX_REGISTER_SIZE.
	(store_register): Likewise.


Alan.


diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f6fdae8ec785462d0ceedcd6501b955cf0..081a16c6896ce7aee4db3b0be45fbbdd2c23dbdb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3250,7 +3250,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
				      int regnum,
				      struct value *result_value)
{
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
  enum register_status status;
  gdb_byte *buf = value_contents_raw (result_value);

@@ -3455,7 +3455,7 @@ void
i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
			    int regnum, const gdb_byte *buf)
{
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];

  if (i386_mmx_regnum_p (gdbarch, regnum))
    {
@@ -5037,7 +5037,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
  uint32_t opcode;
  uint8_t opcode8;
  ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[I386_MAX_REGISTER_SIZE];
  struct i386_record_s ir;
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  uint8_t rex_w = -1;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index adbe72133089bc371108d5dd79bf8d8e61ba259c..fcd5ad248d6b737b9f27e294ce166a118e4bdcad 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -899,7 +899,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
  const gdb_byte *regs = (const gdb_byte *) xsave;
  int i;
  unsigned int clear_bv;
-  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
+  static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
  enum
    {
      none = 0x0,
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 6944c74eb198381135fda3ddf01b9da3a63e62d5..e5182caf39197f759c85c2321e4d66c428f5911e 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -105,7 +105,7 @@ fetch_register (struct regcache *regcache, int regno)
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  long regaddr, val;
  int i;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];
  int tid;

  /* Overload thread id onto process id.  */
@@ -160,7 +160,7 @@ store_register (const struct regcache *regcache, int regno)
  long regaddr, val;
  int i;
  int tid;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[M68K_MAX_REGISTER_SIZE];

  /* Overload thread id onto process id.  */
  tid = ptid_get_lwp (inferior_ptid);




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 12:24                         ` Yao Qi
@ 2017-02-08 14:44                           ` Alan Hayward
  2017-02-18 23:19                             ` Yao Qi
  0 siblings, 1 reply; 28+ messages in thread
From: Alan Hayward @ 2017-02-08 14:44 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 8 Feb 2017, at 12:24, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> Alan Hayward <Alan.Hayward@arm.com> writes:
> 
>> diff --git a/gdb/stack.c b/gdb/stack.c
>> index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..7ba7d68bde8d83ea1e700faa466c6951979e0f76 100644
>> --- a/gdb/stack.c
>> +++ b/gdb/stack.c
>> @@ -1650,33 +1650,35 @@ frame_info (char *addr_exp, int from_tty)
>>     int count;
>>     int i;
>>     int need_nl = 1;
>> +    int sp_regnum = gdbarch_sp_regnum (gdbarch);
>> 
>>     /* The sp is special; what's displayed isn't the save address, but
>>        the value of the previous frame's sp.  This is a legacy thing,
>>        at one stage the frame cached the previous frame's SP instead
>>        of its address, hence it was easiest to just display the cached
>>        value.  */
>> -    if (gdbarch_sp_regnum (gdbarch) >= 0)
>> +    if (sp_regnum >= 0)
>>       {
>> 	/* Find out the location of the saved stack pointer with out
>>            actually evaluating it.  */
>> -	frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
>> -			       &optimized, &unavailable, &lval, &addr,
>> -			       &realnum, NULL);
>> +	frame_register_unwind (fi, sp_regnum, &optimized, &unavailable, &lval,
>> +			       &addr, &realnum, NULL);
>> 	if (!optimized && !unavailable && lval == not_lval)
>> 	  {
>> 	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>> -	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
>> -	    gdb_byte value[MAX_REGISTER_SIZE];
>> +	    int sp_size = register_size (gdbarch, sp_regnum);
>> 	    CORE_ADDR sp;
>> +	    struct value *value = frame_unwind_register_value (fi, sp_regnum);
>> 
>> -	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
>> -				   &optimized, &unavailable, &lval, &addr,
>> -				   &realnum, value);
>> +	    gdb_assert (value != NULL);
> 
> Why don't you hoist frame_unwind_register_value above?, so the
> frame_register_unwind call is no longer needed,
> 
> 
>  struct value *value = frame_unwind_register_value (fi, sp_regnum);
> 
>  gdb_assert (value != NULL);
> 
>  if (!value_optimized_out (value) && value_entirely_available (value))
>     {
>       if (VALUE_LVAL (value) == not_lval)
>         {
>            sp = extract_unsigned_integer (value_contents_all (value),
>                                          sp_size, byte_order);
>         }
>       else if (VALUE_LVAL (value) == lval_memory)
>         {
>            // use value_address (value);
>         }
>       else if (VALUE_LVAL (value) == lval_register)
>         {
>            // use VALUE_REGNUM (value);
>         }
>     }
>   /* else keep quiet.  */
> 
>   release_value (value);
>   value_free (value);
> 
>> 	    /* NOTE: cagney/2003-05-22: This is assuming that the
>>                stack pointer was packed as an unsigned integer.  That
>>                may or may not be valid.  */
>> -	    sp = extract_unsigned_integer (value, sp_size, byte_order);
>> +	    sp = extract_unsigned_integer (value_contents_all (value), sp_size,
>> +					   byte_order);
>> +	    release_value (value);
>> +	    value_free (value);
>> +
>> 	    printf_filtered (" Previous frame's sp is ");
>> 	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
>> 	    printf_filtered ("\n");
>> @@ -1702,7 +1704,7 @@ frame_info (char *addr_exp, int from_tty)
>>     numregs = gdbarch_num_regs (gdbarch)
>> 	      + gdbarch_num_pseudo_regs (gdbarch);
>>     for (i = 0; i < numregs; i++)
>> -      if (i != gdbarch_sp_regnum (gdbarch)
>> +      if (i != sp_regnum
>> 	  && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
>> 	{
>> 	  /* Find out the location of the saved register without
> 
> -- 
> Yao (齐尧)


Ok, changed as requested.

Alan.

2017-02-08  Alan Hayward  <alan.hayward@arm.com>

	* stack.c (frame_info): Use frame_unwind_register_value to avoid buf.


diff --git a/gdb/stack.c b/gdb/stack.c
index e00e2972cf20bc63917af19f86bf57f1c6b0b5b0..97b600b6b7bb6b450e54c947dc6178be03f31e6b 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1642,57 +1642,52 @@ frame_info (char *addr_exp, int from_tty)
   /* Print as much information as possible on the location of all the
      registers.  */
   {
-    enum lval_type lval;
-    int optimized;
-    int unavailable;
-    CORE_ADDR addr;
-    int realnum;
     int count;
     int i;
     int need_nl = 1;
+    int sp_regnum = gdbarch_sp_regnum (gdbarch);

     /* The sp is special; what's displayed isn't the save address, but
        the value of the previous frame's sp.  This is a legacy thing,
        at one stage the frame cached the previous frame's SP instead
        of its address, hence it was easiest to just display the cached
        value.  */
-    if (gdbarch_sp_regnum (gdbarch) >= 0)
+    if (sp_regnum >= 0)
       {
-	/* Find out the location of the saved stack pointer with out
-           actually evaluating it.  */
-	frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
-			       &optimized, &unavailable, &lval, &addr,
-			       &realnum, NULL);
-	if (!optimized && !unavailable && lval == not_lval)
-	  {
-	    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-	    int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
-	    gdb_byte value[MAX_REGISTER_SIZE];
-	    CORE_ADDR sp;
-
-	    frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
-				   &optimized, &unavailable, &lval, &addr,
-				   &realnum, value);
-	    /* NOTE: cagney/2003-05-22: This is assuming that the
-               stack pointer was packed as an unsigned integer.  That
-               may or may not be valid.  */
-	    sp = extract_unsigned_integer (value, sp_size, byte_order);
-	    printf_filtered (" Previous frame's sp is ");
-	    fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
-	    printf_filtered ("\n");
-	    need_nl = 0;
-	  }
-	else if (!optimized && !unavailable && lval == lval_memory)
-	  {
-	    printf_filtered (" Previous frame's sp at ");
-	    fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
-	    printf_filtered ("\n");
-	    need_nl = 0;
-	  }
-	else if (!optimized && !unavailable && lval == lval_register)
+	struct value *value = frame_unwind_register_value (fi, sp_regnum);
+	gdb_assert (value != NULL);
+
+	if (!value_optimized_out (value) && value_entirely_available (value))
 	  {
-	    printf_filtered (" Previous frame's sp in %s\n",
-			     gdbarch_register_name (gdbarch, realnum));
+	    if (VALUE_LVAL (value) == not_lval)
+	      {
+		CORE_ADDR sp;
+		enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+		int sp_size = register_size (gdbarch, sp_regnum);
+
+		sp = extract_unsigned_integer (value_contents_all (value),
+					       sp_size, byte_order);
+
+		printf_filtered (" Previous frame's sp is ");
+		fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
+		printf_filtered ("\n");
+	      }
+	    else if (VALUE_LVAL (value) == lval_memory)
+	      {
+		printf_filtered (" Previous frame's sp at ");
+		fputs_filtered (paddress (gdbarch, value_address (value)),
+				gdb_stdout);
+		printf_filtered ("\n");
+	      }
+	    else if (VALUE_LVAL (value) == lval_register)
+	      {
+		printf_filtered (" Previous frame's sp in %s\n",
+				 gdbarch_register_name (gdbarch,
+							VALUE_REGNUM (value)));
+	      }
+
+	    release_value (value);
+	    value_free (value);
 	    need_nl = 0;
 	  }
 	/* else keep quiet.  */
@@ -1702,9 +1697,15 @@ frame_info (char *addr_exp, int from_tty)
     numregs = gdbarch_num_regs (gdbarch)
 	      + gdbarch_num_pseudo_regs (gdbarch);
     for (i = 0; i < numregs; i++)
-      if (i != gdbarch_sp_regnum (gdbarch)
+      if (i != sp_regnum
 	  && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
 	{
+	  enum lval_type lval;
+	  int optimized;
+	  int unavailable;
+	  CORE_ADDR addr;
+	  int realnum;
+
 	  /* Find out the location of the saved register without
              fetching the corresponding value.  */
 	  frame_register_unwind (fi, i, &optimized, &unavailable,



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
                                           ` (2 preceding siblings ...)
  2017-02-08 12:24                         ` Yao Qi
@ 2017-02-08 15:32                         ` Yao Qi
  2017-02-08 17:10                         ` Yao Qi
  2017-02-08 17:36                         ` Yao Qi
  5 siblings, 0 replies; 28+ messages in thread
From: Yao Qi @ 2017-02-08 15:32 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

Alan Hayward <Alan.Hayward@arm.com> writes:

> +/* Make certain that the register cache is up-to-date with respect to the
> +   current thread.  */

Only register REGNUM is up-to-date.  REGCACHE has ptid, which may not be
the current thread.

/* Make certain that the register REGNUM in REGCACHE is up-to-date.  */

> +void regcache_raw_update (struct regcache *regcache, int regnum);
> +
> +enum register_status regcache_raw_read (struct regcache *regcache,
> +					int rawnum, gdb_byte *buf);

We've already had the declaration.

>  /* Transfer a raw register [0..NUM_REGS) between core-gdb and the
>     regcache.  The read variants return the status of the register.  */

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
                                           ` (3 preceding siblings ...)
  2017-02-08 15:32                         ` Yao Qi
@ 2017-02-08 17:10                         ` Yao Qi
  2017-02-09 13:26                           ` Alan Hayward
  2017-02-14 11:24                           ` Alan Hayward
  2017-02-08 17:36                         ` Yao Qi
  5 siblings, 2 replies; 28+ messages in thread
From: Yao Qi @ 2017-02-08 17:10 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

Alan Hayward <Alan.Hayward@arm.com> writes:

> @@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>  		    struct regcache *this_regs)
>  {
>    struct gdbarch *gdbarch = get_regcache_arch (this_regs);
> -  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
> -  gdb_byte this_buffer[MAX_REGISTER_SIZE];
> +  std::vector<gdb_byte> prev_buffer (register_size (gdbarch, regnum));
> +  std::vector<gdb_byte> this_buffer (register_size (gdbarch, regnum));
>    enum register_status prev_status;
>    enum register_status this_status;
>

This function should be moved to regcache.c, because it is about
comparing bytes of a certain register in both regcaches.  Then, wen can
compare raw registers from register_buffer, and pseudo registers from
the values.

> @@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>      return 1;
>
>    /* Get register contents and compare.  */
> -  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
> -  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
> +  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
> +  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());
>
>    if (this_status != prev_status)
>      return 1;
>    else if (this_status == REG_VALID)
> -    return memcmp (prev_buffer, this_buffer,
> +    return memcmp (prev_buffer.data (), this_buffer.data (),
>  		   register_size (gdbarch, regnum)) != 0;
>    else
>      return 0;

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-07 16:33                       ` Alan Hayward
                                           ` (4 preceding siblings ...)
  2017-02-08 17:10                         ` Yao Qi
@ 2017-02-08 17:36                         ` Yao Qi
  2017-02-13 11:59                           ` Alan Hayward
  5 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-08 17:36 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

Alan Hayward <Alan.Hayward@arm.com> writes:

> @@ -1279,7 +1335,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>    int footnote_register_offset = 0;
>    int footnote_register_type_name_null = 0;
>    long register_offset = 0;
> -  gdb_byte buf[MAX_REGISTER_SIZE];
> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>
>  #if 0
>    fprintf_unfiltered (file, "nr_raw_registers %d\n",
> @@ -1406,8 +1462,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>  	    fprintf_unfiltered (file, "<unavailable>");
>  	  else
>  	    {
> -	      regcache_raw_read (regcache, regnum, buf);
> -	      print_hex_chars (file, buf,
> +	      regcache_raw_update (regcache, regnum);
> +	      print_hex_chars (file, register_buffer (regcache, regnum),
>  			       regcache->descr->sizeof_register[regnum],
>  			       gdbarch_byte_order (gdbarch));
>  	    }
> @@ -1422,13 +1478,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>  	    {
>  	      enum register_status status;
>
> -	      status = regcache_cooked_read (regcache, regnum, buf);
> +	      status = regcache_cooked_read (regcache, regnum, buf.data ());

Can we use regcache_cooked_read_value so that we don't need buf at all.

>  	      if (status == REG_UNKNOWN)
>  		fprintf_unfiltered (file, "<invalid>");
>  	      else if (status == REG_UNAVAILABLE)
>  		fprintf_unfiltered (file, "<unavailable>");
>  	      else
> -		print_hex_chars (file, buf,
> +		print_hex_chars (file, buf.data (),
>  				 regcache->descr->sizeof_register[regnum],
>  				 gdbarch_byte_order (gdbarch));
>  	    }

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 17:10                         ` Yao Qi
@ 2017-02-09 13:26                           ` Alan Hayward
  2017-02-14 11:24                           ` Alan Hayward
  1 sibling, 0 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-09 13:26 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 8 Feb 2017, at 17:09, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> Alan Hayward <Alan.Hayward@arm.com> writes:
> 
>> @@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>> 		    struct regcache *this_regs)
>> {
>>   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
>> -  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
>> -  gdb_byte this_buffer[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> prev_buffer (register_size (gdbarch, regnum));
>> +  std::vector<gdb_byte> this_buffer (register_size (gdbarch, regnum));
>>   enum register_status prev_status;
>>   enum register_status this_status;
>> 
> 
> This function should be moved to regcache.c, because it is about
> comparing bytes of a certain register in both regcaches.  Then, wen can
> compare raw registers from register_buffer, and pseudo registers from
> the values.

Trying to remove the buffer results in quite a lot of code, as you can’t assume
the register has the same state in both prev_regs and this_regs.
For pseudo cases, it will still result in buffer usage.
(Attempted code pasted below).

I feel this is adding a whole lot of complexity and mostly duplicates code from
regcache_cooked_read.

Unless you really feel this case is going to hit performance, then I think the
existing code is much simpler and easier to read.

(Happy to move the function to regcache and change result to a bool).



Maybe a long term solution would be an alternative additional version of
regcache_cooked_read:

enum register_status
regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte **buf, 
		      bool *requires_deallocation)

The function returns you a ptr in **buf. If *requires_deallocation is true then you
need to free buf once you have finished with it.

Or maybe a version of regcache_cooked_read which returns a struct *value
(assuming it’s possible to set the buffer in a struct value to be an existing pointer).

This could then be used throughout the codebase, preventing lots of small memcpy.
However, that would then open a rabbit hole of changes to common functions, which is
all far out of the scope of these patches.

It’s possible that all that is not possible because we don’t want to expose the
internal regcache pointers in case the values move.



This was my work in progress:


bool
regcache_register_changed_p (int regnum, struct regcache *prev_regs,
			     struct regcache *this_regs)
{
  struct gdbarch *this_gdbarch = get_regcache_arch (this_regs);
  struct gdbarch *prev_gdbarch;
  gdb_byte *prev_buffer = NULL;
  gdb_byte *this_buffer = NULL;
  enum register_status prev_status;
  enum register_status this_status;
  gdb_assert (regnum >= 0);
  gdb_assert (regnum < this_regs->descr->nr_cooked_registers);

  /* if there are no previous registers consider all registers as changed.  */
  if (!prev_regs)
    return true;
  gdb_assert (regnum < regcache->descr->nr_cooked_registers);

  prev_gdbarch = get_regcache_arch (prev_regs);

  /* If arches don't match then consider all registers as changed.  */
  if (prev_gdbarch != gdbarch)
    return true;

  if (regnum < regcache->descr->nr_raw_registers)
  {
    prev_status = prev_regs->register_status[regnum];
    this_status = this_status->register_status[regnum];
    prev_buffer = register_buffer (prev_regs, regnum);
    this_buffer = register_buffer (this_regs, regnum);
  }
  else
  {
    if (prev_regs->readonly_p
	&& prev_regs->register_status[regnum] != REG_UNKNOWN)
      {
      	prev_status = prev_regs->register_status[regnum];
      	prev_buffer = register_buffer (prev_regs, regnum);
      }
     else if (gdbarch_pseudo_register_read_value_p (prev_regs->descr->gdbarch))
      {
	struct value *mark, *computed;

	mark = value_mark ();

	computed = gdbarch_pseudo_register_read_value (prev_gdbarch,
						       prev_regs, regnum);
	if (value_entirely_available (computed))
	  {
	    prev_buffer = value_contents_raw (computed);
	    prev_status = REG_VALID;
	  }
	else
	  prev_status = REG_UNAVAILABLE;
	}
      }
     else
      {
      	prev_buffer = xmalloc (register_size (prev_gdbarch, regnum));
      	gdbarch_pseudo_register_read (prev_gdbarch, prev_regcache, regnum, prev_buffer);
      }

      ....duplicate above code for this_regcache....
      Possibly put above code into a static function (but then you still have to deal
      with allocation and frees spanning the functions)

  }


  if (this_status != prev_status)
    ret = true;
  else if (this_status == REG_VALID)
    ret = memcmp (prev_buffer, this_buffer,
		  register_size (gdbarch, regnum)) != 0;
  else
    ret = false;

  ...code to free any buf or mark for created for either prev and this...

  return ret;
}




> 
>> @@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>>     return 1;
>> 
>>   /* Get register contents and compare.  */
>> -  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
>> -  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
>> +  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
>> +  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());
>> 
>>   if (this_status != prev_status)
>>     return 1;
>>   else if (this_status == REG_VALID)
>> -    return memcmp (prev_buffer, this_buffer,
>> +    return memcmp (prev_buffer.data (), this_buffer.data (),
>> 		   register_size (gdbarch, regnum)) != 0;
>>   else
>>     return 0;
> 
> -- 
> Yao (齐尧)


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 17:36                         ` Yao Qi
@ 2017-02-13 11:59                           ` Alan Hayward
  0 siblings, 0 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-13 11:59 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 8 Feb 2017, at 17:36, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> Alan Hayward <Alan.Hayward@arm.com> writes:
> 
>> @@ -1279,7 +1335,7 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>>   int footnote_register_offset = 0;
>>   int footnote_register_type_name_null = 0;
>>   long register_offset = 0;
>> -  gdb_byte buf[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> buf (max_register_size (gdbarch));
>> 
>> #if 0
>>   fprintf_unfiltered (file, "nr_raw_registers %d\n",
>> @@ -1406,8 +1462,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>> 	    fprintf_unfiltered (file, "<unavailable>");
>> 	  else
>> 	    {
>> -	      regcache_raw_read (regcache, regnum, buf);
>> -	      print_hex_chars (file, buf,
>> +	      regcache_raw_update (regcache, regnum);
>> +	      print_hex_chars (file, register_buffer (regcache, regnum),
>> 			       regcache->descr->sizeof_register[regnum],
>> 			       gdbarch_byte_order (gdbarch));
>> 	    }
>> @@ -1422,13 +1478,13 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
>> 	    {
>> 	      enum register_status status;
>> 
>> -	      status = regcache_cooked_read (regcache, regnum, buf);
>> +	      status = regcache_cooked_read (regcache, regnum, buf.data ());
> 
> Can we use regcache_cooked_read_value so that we don't need buf at all.

Yes, that would work.
However, this cooked read is in the middle of a for() loop of every register value.

With the patch currently, we have the allocation of buf once, and then re-use it for each
iteration.

Switching to regcache_cooked_read_value() would result in a call to allocate_value()
(within the regcache_cooked_read_value code) every iteration, which would then be freed
after printing it.


> 
>> 	      if (status == REG_UNKNOWN)
>> 		fprintf_unfiltered (file, "<invalid>");
>> 	      else if (status == REG_UNAVAILABLE)
>> 		fprintf_unfiltered (file, "<unavailable>");
>> 	      else
>> -		print_hex_chars (file, buf,
>> +		print_hex_chars (file, buf.data (),
>> 				 regcache->descr->sizeof_register[regnum],
>> 				 gdbarch_byte_order (gdbarch));
>> 	    }
> 
> -- 
> Yao (齐尧)


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 17:10                         ` Yao Qi
  2017-02-09 13:26                           ` Alan Hayward
@ 2017-02-14 11:24                           ` Alan Hayward
  1 sibling, 0 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-14 11:24 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 8 Feb 2017, at 17:09, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> Alan Hayward <Alan.Hayward@arm.com> writes:
> 
>> @@ -1135,8 +1135,8 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>> 		    struct regcache *this_regs)
>> {
>>   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
>> -  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
>> -  gdb_byte this_buffer[MAX_REGISTER_SIZE];
>> +  std::vector<gdb_byte> prev_buffer (register_size (gdbarch, regnum));
>> +  std::vector<gdb_byte> this_buffer (register_size (gdbarch, regnum));
>>   enum register_status prev_status;
>>   enum register_status this_status;
>> 
> 
> This function should be moved to regcache.c, because it is about
> comparing bytes of a certain register in both regcaches.  Then, wen can
> compare raw registers from register_buffer, and pseudo registers from
> the values.
> 
>> @@ -1146,13 +1146,13 @@ register_changed_p (int regnum, struct regcache *prev_regs,
>>     return 1;
>> 
>>   /* Get register contents and compare.  */
>> -  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
>> -  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
>> +  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer.data ());
>> +  this_status = regcache_cooked_read (this_regs, regnum, this_buffer.data ());
>> 
>>   if (this_status != prev_status)
>>     return 1;
>>   else if (this_status == REG_VALID)
>> -    return memcmp (prev_buffer, this_buffer,
>> +    return memcmp (prev_buffer.data (), this_buffer.data (),
>> 		   register_size (gdbarch, regnum)) != 0;
>>   else
>>     return 0;
> 
> -- 
> Yao (齐尧)


Ignore my previous reply to this comment. I've since noticed you can just use
regcache_cooked_read_value.

New patch below.

I removed the error case from mi-main becuase it was impossible for the code
to get here - register_changed_p would always return 0 or 1.

Tested on a build of all targets using make check with target boards unix and
native-gdbserver. This testing also included the two patches:
* M68K_MAX_REGISTER_SIZE and I386_MAX_REGISTER_SIZE changes
* stack.c changes

Ok?

Alan.


2017-02-13  Alan Hayward  <alan.hayward@arm.com>

	* gdb/mi/mi-main.c (mi_cmd_data_list_changed_registers): Use
	regcache_register_changed_p
	(register_changed_p): Remove.
	* gdb/regcache.c (regcache_register_changed_p): New function.
	* gdb/regcache.h (regcache_register_changed_p): New declaration.


diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..d22cb9b59d3c5d65609bf3762457bba90401fd8f 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -91,8 +91,6 @@ static void mi_execute_cli_command (const char *cmd, int args_p,
 				    const char *args);
 static void mi_execute_async_cli_command (char *cli_command,
 					  char **argv, int argc);
-static int register_changed_p (int regnum, struct regcache *,
-			       struct regcache *);
 static void output_register (struct frame_info *, int regnum, int format,
 			     int skip_unavailable);

@@ -1098,11 +1096,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
 	  if (gdbarch_register_name (gdbarch, regnum) == NULL
 	      || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
 	    continue;
-	  changed = register_changed_p (regnum, prev_regs, this_regs);
-	  if (changed < 0)
-	    error (_("-data-list-changed-registers: "
-		     "Unable to read register contents."));
-	  else if (changed)
+	  if (regcache_register_changed_p (regnum, prev_regs, this_regs))
 	    uiout->field_int (NULL, regnum);
 	}
     }
@@ -1117,11 +1111,7 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
 	  && gdbarch_register_name (gdbarch, regnum) != NULL
 	  && *gdbarch_register_name (gdbarch, regnum) != '\000')
 	{
-	  changed = register_changed_p (regnum, prev_regs, this_regs);
-	  if (changed < 0)
-	    error (_("-data-list-changed-registers: "
-		     "Unable to read register contents."));
-	  else if (changed)
+	  if (regcache_register_changed_p (regnum, prev_regs, this_regs))
 	    uiout->field_int (NULL, regnum);
 	}
       else
@@ -1130,34 +1120,6 @@ mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
   do_cleanups (cleanup);
 }

-static int
-register_changed_p (int regnum, struct regcache *prev_regs,
-		    struct regcache *this_regs)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (this_regs);
-  gdb_byte prev_buffer[MAX_REGISTER_SIZE];
-  gdb_byte this_buffer[MAX_REGISTER_SIZE];
-  enum register_status prev_status;
-  enum register_status this_status;
-
-  /* First time through or after gdbarch change consider all registers
-     as changed.  */
-  if (!prev_regs || get_regcache_arch (prev_regs) != gdbarch)
-    return 1;
-
-  /* Get register contents and compare.  */
-  prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
-  this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
-
-  if (this_status != prev_status)
-    return 1;
-  else if (this_status == REG_VALID)
-    return memcmp (prev_buffer, this_buffer,
-		   register_size (gdbarch, regnum)) != 0;
-  else
-    return 0;
-}
-
 /* Return a list of register number and value pairs.  The valid
    arguments expected are: a letter indicating the format in which to
    display the registers contents.  This can be one of: x
diff --git a/gdb/regcache.h b/gdb/regcache.h
index e5a7cf553279b8cc0d546ec1b8274cbf97e246d5..174aa0166f419b40b0509b1be5c6dce3c2373fd0 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -228,4 +228,11 @@ extern void regcache_cpy (struct regcache *dest, struct regcache *src);
 extern void registers_changed (void);
 extern void registers_changed_ptid (ptid_t);

+/* Return true if the register value of regnum differs between prev_regs and
+   this_regs.  prev_regs can be null, but this_regs must be set.  */
+
+extern bool regcache_register_changed_p (int regnum,
+					 struct regcache *prev_regs,
+					 struct regcache *this_regs);
+
 #endif /* REGCACHE_H */
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 9d28aa2c2114e0f1c52758bb2fbe9669a329c13e..96cc94ee7cfeb60d3b6541ca0b49871e6087aa8a 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1251,6 +1251,74 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
 }


+/* Return true if the register value of regnum differs between prev_regs and
+   this_regs.  prev_regs can be null, but this_regs must be set.  */
+
+bool
+regcache_register_changed_p (int regnum, struct regcache *prev_regs,
+			     struct regcache *this_regs)
+{
+  struct gdbarch *gdbarch;
+  gdb_assert (regnum >= 0);
+  gdb_assert (this_regs);
+
+  /* if there are no previous registers consider all registers as changed.  */
+  if (!prev_regs)
+    return true;
+
+  gdb_assert (regnum < prev_regs->descr->nr_cooked_registers);
+  gdb_assert (regnum < this_regs->descr->nr_cooked_registers);
+  gdbarch = get_regcache_arch (this_regs);
+
+  /* If arches don't match then consider all registers as changed.  */
+  if (gdbarch != get_regcache_arch (prev_regs))
+    return true;
+
+  if (regnum < this_regs->descr->nr_raw_registers)
+    {
+      enum register_status prev_status, this_status;
+
+      prev_status = (enum register_status) prev_regs->register_status[regnum];
+      this_status = (enum register_status) this_regs->register_status[regnum];
+
+      if (this_status != prev_status)
+	return true;
+      else if (this_status == REG_VALID)
+	return memcmp (register_buffer (prev_regs, regnum),
+		       register_buffer (this_regs, regnum),
+		       register_size (gdbarch, regnum)) != 0;
+      else
+	return false;
+    }
+  else
+    {
+      struct value *prev_value, *this_value;
+      bool ret;
+
+      prev_value = regcache_cooked_read_value (prev_regs, regnum);
+      this_value = regcache_cooked_read_value (this_regs, regnum);
+
+      if (value_optimized_out (prev_value)
+	  || value_optimized_out (this_value))
+	ret = value_optimized_out (prev_value)
+	      != value_optimized_out (this_value);
+      else if (!value_entirely_available (prev_value)
+	  || !value_entirely_available (this_value))
+	ret = value_entirely_available (prev_value)
+	      != value_entirely_available (this_value);
+      else
+	ret = memcmp (value_contents_raw (prev_value),
+		      value_contents_raw (this_value),
+		      register_size (gdbarch, regnum)) != 0;
+
+      release_value (prev_value);
+      value_free (prev_value);
+      release_value (this_value);
+      value_free (this_value);
+      return ret;
+    }
+}
+
 static void
 reg_flush_command (char *command, int from_tty)
 {




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-08 14:44                           ` Alan Hayward
@ 2017-02-18 23:19                             ` Yao Qi
  2017-02-20 11:19                               ` Alan Hayward
  0 siblings, 1 reply; 28+ messages in thread
From: Yao Qi @ 2017-02-18 23:19 UTC (permalink / raw)
  To: Alan Hayward; +Cc: Pedro Alves, Joel Brobecker, gdb-patches

On 17-02-08 14:44:38, Alan Hayward wrote:
> 
> Ok, changed as requested.
> 
> Alan.
> 
> 2017-02-08  Alan Hayward  <alan.hayward@arm.com>
> 
> 	* stack.c (frame_info): Use frame_unwind_register_value to avoid buf.

This line is too long.

Did you run regression test with board file unix and native-gdbserver?

Patch is good to me if it is regression-free.

-- 
Yao 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] Removal of uses of MAX_REGISTER_SIZE
  2017-02-18 23:19                             ` Yao Qi
@ 2017-02-20 11:19                               ` Alan Hayward
  0 siblings, 0 replies; 28+ messages in thread
From: Alan Hayward @ 2017-02-20 11:19 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, Joel Brobecker, gdb-patches, nd


> On 18 Feb 2017, at 23:18, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> On 17-02-08 14:44:38, Alan Hayward wrote:
>> 
>> Ok, changed as requested.
>> 
>> Alan.
>> 
>> 2017-02-08  Alan Hayward  <alan.hayward@arm.com>
>> 
>> 	* stack.c (frame_info): Use frame_unwind_register_value to avoid buf.
> 
> This line is too long.
> 
> Did you run regression test with board file unix and native-gdbserver?
> 
> Patch is good to me if it is regression-free.
> 
> -- 
> Yao 

Yes, I’ve run a unix and native-gdbserver run with the three patches:
*I386 + M68K changes
*stack.c changes
*mi-main changes


Alan.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2017-02-20 11:19 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-24 10:31 [PATCH] Removal of uses of MAX_REGISTER_SIZE Alan Hayward
2017-01-27 11:49 ` Pedro Alves
2017-01-27 12:11 ` Pedro Alves
2017-01-27 16:46   ` Alan Hayward
2017-02-01 15:49     ` Pedro Alves
2017-02-01 12:45   ` Yao Qi
2017-02-01 15:48     ` Pedro Alves
2017-02-02  9:40       ` Joel Brobecker
2017-02-03  9:59         ` Alan Hayward
2017-02-03 10:28           ` Yao Qi
2017-02-03 11:00             ` Pedro Alves
2017-02-03 11:25               ` Alan Hayward
2017-02-03 16:50                 ` Yao Qi
2017-02-06  9:33                   ` Alan Hayward
     [not found]                     ` <20170206152635.GE11916@E107787-LIN>
2017-02-07 16:33                       ` Alan Hayward
2017-02-08 10:47                         ` Yao Qi
2017-02-08 14:17                           ` Alan Hayward
2017-02-08 12:06                         ` Yao Qi
2017-02-08 12:24                         ` Yao Qi
2017-02-08 14:44                           ` Alan Hayward
2017-02-18 23:19                             ` Yao Qi
2017-02-20 11:19                               ` Alan Hayward
2017-02-08 15:32                         ` Yao Qi
2017-02-08 17:10                         ` Yao Qi
2017-02-09 13:26                           ` Alan Hayward
2017-02-14 11:24                           ` Alan Hayward
2017-02-08 17:36                         ` Yao Qi
2017-02-13 11:59                           ` Alan Hayward

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).