From 94cd915f48523bbcbe20f74835d7f5a9d0b3a916 Mon Sep 17 00:00:00 2001
From: Michael Snyder <msnyder@vmware.com>
Date: Tue, 8 Jan 2002 00:59:31 +0000
Subject: [PATCH] 2002-01-07  Michael Snyder  <msnyder@redhat.com>

	* infptrace.c (GDB_MAX_ALLOCA): New define.
	(child_xfer_memory): Use xmalloc/xfree instead of alloca if the
	size of the buffer exceeds GDB_MAX_ALLOCA (default 1 megabyte,
	can be overridden with whatever value is appropriate to the host).
	* infttrace.c (child_xfer_memory): Add FIXME warning about use of
	alloca to allocate potentially large buffer.
	* rs6000-nat.c (child_xfer_memory): Ditto.
	* symm-nat.c (child_xfer_memory): Ditto.
	* x86-64-linux-nat.c (child_xfer_memory): Ditto.
---
 gdb/ChangeLog          | 12 ++++++++++++
 gdb/infptrace.c        | 22 ++++++++++++++++++++--
 gdb/infttrace.c        |  5 ++++-
 gdb/symm-nat.c         |  5 ++++-
 gdb/x86-64-linux-nat.c |  6 ++++--
 5 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4b5b530fab..f6b07d1f4b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,15 @@
+2002-01-07  Michael Snyder  <msnyder@redhat.com>
+
+	* infptrace.c (GDB_MAX_ALLOCA): New define.
+	(child_xfer_memory): Use xmalloc/xfree instead of alloca if the
+	size of the buffer exceeds GDB_MAX_ALLOCA (default 1 megabyte, 
+	can be overridden with whatever value is appropriate to the host).
+	* infttrace.c (child_xfer_memory): Add FIXME warning about use of
+	alloca to allocate potentially large buffer.
+	* rs6000-nat.c (child_xfer_memory): Ditto.
+	* symm-nat.c (child_xfer_memory): Ditto.
+	* x86-64-linux-nat.c (child_xfer_memory): Ditto.
+
 2002-01-07  Jackie Smith Cashion  <jsmith@redhat.com>
 
 	From Nick Clifton  <nickc@redhat.com>
diff --git a/gdb/infptrace.c b/gdb/infptrace.c
index 9815e05ef0..c39ca030e7 100644
--- a/gdb/infptrace.c
+++ b/gdb/infptrace.c
@@ -480,6 +480,11 @@ store_inferior_registers (int regno)
 #endif /* !defined (FETCH_INFERIOR_REGISTERS).  */
 
 
+/* Set an upper limit on alloca.  */
+#ifndef GDB_MAX_ALLOCA
+#define GDB_MAX_ALLOCA 0x1000
+#endif
+
 #if !defined (CHILD_XFER_MEMORY)
 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
    in the NEW_SUN_PTRACE case.  It ought to be straightforward.  But
@@ -506,9 +511,20 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
   /* Round ending address up; get number of longwords that makes.  */
   int count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
 	       / sizeof (PTRACE_XFER_TYPE));
+  int alloc = count * sizeof (PTRACE_XFER_TYPE);
+  PTRACE_XFER_TYPE *buffer;
+  struct cleanup *old_chain = NULL;
+
   /* Allocate buffer of that many longwords.  */
-  PTRACE_XFER_TYPE *buffer =
-    (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+  if (len < GDB_MAX_ALLOCA)
+    {
+      buffer = (PTRACE_XFER_TYPE *) alloca (alloc);
+    }
+  else
+    {
+      buffer = (PTRACE_XFER_TYPE *) xmalloc (alloc);
+      old_chain = make_cleanup (xfree, buffer);
+    }
 
   if (write)
     {
@@ -573,6 +589,8 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
 	      len);
     }
 
+  if (old_chain != NULL)
+    do_cleanups (old_chain);
   return len;
 }
 
diff --git a/gdb/infttrace.c b/gdb/infttrace.c
index c3216a5f0e..df0a5e579d 100644
--- a/gdb/infttrace.c
+++ b/gdb/infttrace.c
@@ -4922,8 +4922,11 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
   = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
   / sizeof (TTRACE_XFER_TYPE);
   /* Allocate buffer of that many longwords.  */
+  /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+     because it uses alloca to allocate a buffer of arbitrary size.
+     For very large xfers, this could crash GDB's stack.  */
   register TTRACE_XFER_TYPE *buffer
-  = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
+    = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
 
   if (write)
     {
diff --git a/gdb/symm-nat.c b/gdb/symm-nat.c
index 183fa9198d..d686777431 100644
--- a/gdb/symm-nat.c
+++ b/gdb/symm-nat.c
@@ -764,8 +764,11 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
   = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
   / sizeof (PTRACE_XFER_TYPE);
   /* Allocate buffer of that many longwords.  */
+  /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+     because it uses alloca to allocate a buffer of arbitrary size.
+     For very large xfers, this could crash GDB's stack.  */
   register PTRACE_XFER_TYPE *buffer
-  = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+    = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
 
   if (write)
     {
diff --git a/gdb/x86-64-linux-nat.c b/gdb/x86-64-linux-nat.c
index 268aad583b..85912e8138 100644
--- a/gdb/x86-64-linux-nat.c
+++ b/gdb/x86-64-linux-nat.c
@@ -147,8 +147,7 @@ fill_gregset (elf_gregset_t * gregsetp, int regno)
 
   for (i = 0; i < X86_64_NUM_GREGS; i++)
     if ((regno == -1 || regno == i))
-      *(regp + x86_64_regmap[i]) =
-	*(elf_greg_t *) & registers[REGISTER_BYTE (i)];
+      read_register_gen (i, regp + x86_64_regmap[i]);
 }
 
 /* Fetch all general-purpose registers from process/thread TID and
@@ -417,6 +416,9 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
     = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
     / sizeof (PTRACE_XFER_TYPE);
   /* Allocate buffer of that many longwords.  */
+  /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+     because it uses alloca to allocate a buffer of arbitrary size.
+     For very large xfers, this could crash GDB's stack.  */
   register PTRACE_XFER_TYPE *buffer
     = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
 
-- 
2.42.0