From 44a8f0c76e35c0278c8a43dd862cd0984ca14e2d Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Sat, 24 Sep 2011 14:01:28 -0700
Subject: [PATCH] Fix Trac ticket:46.

Make the size of all spaces configurable from the command line.

code/commandline.lisp:
o Define the switches so lisp doesn't complain.

general-info/lisp.1:
o Document new switches.

general-info/release-20c.txt:
o Update

lisp/Darwin-os.c
lisp/FreeBSD-os.c
lisp/Linux-os.c
lisp/NetBSD-os.c
lisp/backtrace.c
lisp/cgc.c
lisp/gencgc.c
lisp/os-common.c
lisp/ppc-validate.h
lisp/purify.c
lisp/solaris-os.c
lisp/sparc-arch.c
lisp/sparc-validate.h
lisp/x86-validate.h:
lisp/validate.c
o Basically rename CONTROL_STACK_SIZE, BINDING_STACK_SIZE,
  READ_ONLY_SPACE_SIZE, and STATIC_SPACE_SIZE to control_stack_size,
  binding_stack_size, read_only_space_size, and static_space_size,
  respectively.

lisp/coreparse.c
o Check the space size in the core file against the allocated size.
  If the allocated space is too small, print an error message and
  exit.

lisp/globals.c
o Define new variables for the allocated size of spaces.

lisp/globals.h
o Declare the new variables for the size of the spaces.

lisp/lisp.c
o Set the default values of the spaces.
o Parse the new command-line flags and set the space sizes.

lisp/sunos-os.c:
o Added os_init0 (that we forgot last time).

lisp/x86-assem.S:
o Change $CONTROL_STACK_END to GNAME(control_stack_end) to get the
  correct end of the stack.
---
 code/commandline.lisp        | 30 +++++++++++-
 general-info/lisp.1          | 24 +++++++++-
 general-info/release-20c.txt |  5 ++
 lisp/Darwin-os.c             |  8 ++--
 lisp/FreeBSD-os.c            |  8 ++--
 lisp/Linux-os.c              | 20 +++++---
 lisp/NetBSD-os.c             |  8 ++--
 lisp/backtrace.c             |  2 +-
 lisp/cgc.c                   |  2 +-
 lisp/coreparse.c             | 10 ++++
 lisp/gencgc.c                | 18 ++++----
 lisp/globals.c               |  7 +++
 lisp/globals.h               |  6 +++
 lisp/lisp.c                  | 89 ++++++++++++++++++++++++++++++++++++
 lisp/os-common.c             |  4 +-
 lisp/ppc-validate.h          |  2 +-
 lisp/purify.c                |  6 +--
 lisp/solaris-os.c            | 16 +++----
 lisp/sparc-arch.c            |  2 +-
 lisp/sparc-validate.h        |  2 +-
 lisp/sunos-os.c              |  4 ++
 lisp/validate.c              | 15 ++----
 lisp/x86-assem.S             |  4 +-
 lisp/x86-validate.h          |  3 +-
 24 files changed, 235 insertions(+), 60 deletions(-)

diff --git a/code/commandline.lisp b/code/commandline.lisp
index 9dded6a45..1ee614689 100644
--- a/code/commandline.lisp
+++ b/code/commandline.lisp
@@ -283,10 +283,38 @@
 
 (defswitch "dynamic-space-size" nil
   "Specifies the number of megabytes that should be allocated to the
-  heap.  If not specified, a platform- specific default is used.  The
+  heap.  If not specified, a platform-specific default is used.  The
   actual maximum allowed heap size is platform-specific."
   "megabytes")
 
+(defswitch "read-only-space-size" nil
+  "Specifies the number of megabytes that should be allocated for the
+  read-only space.  If not specified, a platform-specific default is
+  used.  The actual maximum allowed read-only size is
+  platform-specific."
+  "megabytes")
+
+(defswitch "static-space-size" nil
+  "Specifies the number of megabytes that should be allocated for the
+  static space.  If not specified, a platform-specific default is
+  used.  The actual maximum allowed static space size is
+  platform-specific."
+  "megabytes")
+
+(defswitch "control-stack-size" nil
+  "Specifies the number of megabytes that should be allocated for the
+  control stack.  If not specified, a platform-specific default is
+  used.  The actual maximum allowed control stack size is
+  platform-specific."
+  "megabytes")
+
+(defswitch "binding-stack-size" nil
+  "Specifies the number of megabytes that should be allocated for the
+  binding stack.  If not specified, a platform-specific default is
+  used.  The actual maximum allowed binding stack size is
+  platform-specific."
+  "megabytes")
+
 (defswitch "lib" nil
   "A colon-separated list of directories to be used for the library:
   search-list."
diff --git a/general-info/lisp.1 b/general-info/lisp.1
index b725c7e8d..5bb99158f 100644
--- a/general-info/lisp.1
+++ b/general-info/lisp.1
@@ -55,8 +55,30 @@ most unnecessary noise, like GC messages, load messages, etc. to be suppressed.
 Requires an argument that should be the number of megabytes (1048576 bytes)
 that should be allocated to the heap.  If not specified, a platform-specific
 default is used.  The actual maximum allowed heap size is platform-specific.
-Currently, this option is only available for the x86 and sparc platforms. 
 .TP
+.TP
+.BR \-read-only-space-size
+Requires an argument that should be the number of megabytes (1048576 bytes)
+that should be allocated to the read-only space.  If not specified, a platform-specific
+default is used.
+.TP
+.TP
+.BR \-static-space-size
+Requires an argument that should be the number of megabytes (1048576 bytes)
+that should be allocated to the static-space.  If not specified, a platform-specific
+default is used.  The actual maximum allowed heap size is platform-specific.
+.TP
+.TP
+.BR \-control-stack-size
+Requires an argument that should be the number of megabytes (1048576 bytes)
+that should be allocated for the control stack.  If not specified, a platform-specific
+default is used.  The actual maximum allowed heap size is platform-specific.
+.TP
+.TP
+.BR \-binding-stack-size
+Requires an argument that should be the number of megabytes (1048576 bytes)
+that should be allocated for the binding stack.  If not specified, a platform-specific
+default is used.  The actual maximum allowed heap size is platform-specific.
 .BR \-edit
 Causes Lisp to enter the 
 .I Hemlock
diff --git a/general-info/release-20c.txt b/general-info/release-20c.txt
index cb7399fcc..7328510a8 100644
--- a/general-info/release-20c.txt
+++ b/general-info/release-20c.txt
@@ -149,6 +149,11 @@ New in this release:
     - #43: unread-char doesn't change file-position
       Fixed.
 
+    - #47: Added command line flags -read-only-space-size,
+      -static-space-size, -control-stack-size, and -binding-stack-size
+      to control the size of the each region.  The default size for
+      each is unchanged.
+
   * Other changes:
 
   * Improvements to the PCL implementation of CLOS:
diff --git a/lisp/Darwin-os.c b/lisp/Darwin-os.c
index c52f9e0f9..1304d1042 100644
--- a/lisp/Darwin-os.c
+++ b/lisp/Darwin-os.c
@@ -444,14 +444,14 @@ valid_addr(os_vm_address_t addr)
 
     newaddr = os_trunc_to_page(addr);
 
-    if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
-	|| in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
+    if (in_range_p(addr, READ_ONLY_SPACE_START, read_only_space_size)
+	|| in_range_p(addr, STATIC_SPACE_START, static_space_size)
 	|| in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
 #ifndef GENCGC
 	|| in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
 #endif
-	|| in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
-	|| in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
+	|| in_range_p(addr, CONTROL_STACK_START, control_stack_size)
+	|| in_range_p(addr, BINDING_STACK_START, binding_stack_size))
 	return TRUE;
     return FALSE;
 }
diff --git a/lisp/FreeBSD-os.c b/lisp/FreeBSD-os.c
index 84e0b0854..7a06222cd 100644
--- a/lisp/FreeBSD-os.c
+++ b/lisp/FreeBSD-os.c
@@ -224,14 +224,14 @@ valid_addr(os_vm_address_t addr)
 
     newaddr = os_trunc_to_page(addr);
 
-    if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
-	|| in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
+    if (in_range_p(addr, READ_ONLY_SPACE_START, read_only_space_size)
+	|| in_range_p(addr, STATIC_SPACE_START, static_space_size)
 	|| in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
 #ifndef GENCGC
 	|| in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
 #endif
-	|| in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
-	|| in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
+	|| in_range_p(addr, CONTROL_STACK_START, control_stack_size)
+	|| in_range_p(addr, BINDING_STACK_START, binding_stack_size))
 	return TRUE;
     return FALSE;
 }
diff --git a/lisp/Linux-os.c b/lisp/Linux-os.c
index 26e122408..f4b96effe 100644
--- a/lisp/Linux-os.c
+++ b/lisp/Linux-os.c
@@ -131,12 +131,20 @@ check_personality(struct utsname *name, const char *argv[], const char *envp[])
 #endif
 }
 
+/*
+ * Check personality here, before we start processing command line
+ * args.  (Previously it was done in os_init.)  check_personality
+ * can re-exec us, so we end up parsing the command line args
+ * twice.  Not usually a problem unless the processing causes
+ * output, which can be confusing.
+ */
+
 void
 os_init0(const char *argv[], const char *envp[])
 {
     struct utsname name;
-
     uname(&name);
+        
     check_personality(&name, argv, envp);
 }
 
@@ -365,12 +373,12 @@ valid_addr(os_vm_address_t addr)
 
     newaddr = os_trunc_to_page(addr);
 
-    if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
-	|| in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
+    if (in_range_p(addr, READ_ONLY_SPACE_START, read_only_space_size)
+	|| in_range_p(addr, STATIC_SPACE_START, static_space_size)
 	|| in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
 	|| in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
-	|| in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
-	|| in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
+	|| in_range_p(addr, CONTROL_STACK_START, control_stack_size)
+	|| in_range_p(addr, BINDING_STACK_START, binding_stack_size))
 	return TRUE;
     return FALSE;
 }
@@ -437,7 +445,7 @@ sigsegv_handler(HANDLER_ARGS)
 #ifdef i386
     interrupt_handle_now(signal, contextstruct);
 #else
-#define CONTROL_STACK_TOP (((char*) CONTROL_STACK_START) + CONTROL_STACK_SIZE)
+#define CONTROL_STACK_TOP (((char*) CONTROL_STACK_START) + control_stack_size)
 
     addr = arch_get_bad_addr(signal, code, context);
 
diff --git a/lisp/NetBSD-os.c b/lisp/NetBSD-os.c
index 1399c402c..2cc359e96 100644
--- a/lisp/NetBSD-os.c
+++ b/lisp/NetBSD-os.c
@@ -276,14 +276,14 @@ valid_addr(os_vm_address_t addr)
 
     newaddr = os_trunc_to_page(addr);
 
-    if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
-	|| in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
+    if (in_range_p(addr, READ_ONLY_SPACE_START, read_only_space_size)
+	|| in_range_p(addr, STATIC_SPACE_START, static_space_size)
 	|| in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
 #ifndef GENCGC
 	|| in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
 #endif
-	|| in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
-	|| in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
+	|| in_range_p(addr, CONTROL_STACK_START, control_stack_size)
+	|| in_range_p(addr, BINDING_STACK_START, binding_stack_size))
 	return TRUE;
     return FALSE;
 }
diff --git a/lisp/backtrace.c b/lisp/backtrace.c
index 68b62f53a..cb9cd8cf7 100644
--- a/lisp/backtrace.c
+++ b/lisp/backtrace.c
@@ -253,7 +253,7 @@ backtrace(int nframes)
 static int
 stack_pointer_p(unsigned long p)
 {
-    return (p < CONTROL_STACK_START + CONTROL_STACK_SIZE
+    return (p < CONTROL_STACK_START + control_stack_size
 	    && p > (unsigned long) &p && (p & 3) == 0);
 }
 
diff --git a/lisp/cgc.c b/lisp/cgc.c
index 6a9b3f057..2bf564759 100644
--- a/lisp/cgc.c
+++ b/lisp/cgc.c
@@ -1531,7 +1531,7 @@ flip_spaces(void)
  * to just the assigned lisp stack area.
  */
 #if defined i386
-#define BOS (CONTROL_STACK_START+CONTROL_STACK_SIZE)	/* x86-validate.h */
+#define BOS (CONTROL_STACK_START+control_stack_size)	/* x86-validate.h */
 /* Traverse stack in same direction as it was loaded to try and
  * preserve original ordering of pages. Good for the VM system I hope.
  */
diff --git a/lisp/coreparse.c b/lisp/coreparse.c
index 76f87ccaa..cf1ee43ee 100644
--- a/lisp/coreparse.c
+++ b/lisp/coreparse.c
@@ -62,9 +62,19 @@ process_directory(int fd, long *ptr, int count)
 	      break;
 	  case STATIC_SPACE_ID:
 	      static_space = (lispobj *) addr;
+              if (len >= static_space_size) {
+                  fprintf(stderr, "Error:  Static space size (%d) exceeds allocated space (%d)!\n",
+                          len, static_space_size);
+                  exit(1);
+              }
 	      break;
 	  case READ_ONLY_SPACE_ID:
 	      /* Don't care about read only space */
+              if (len >= read_only_space_size) {
+                  fprintf(stderr, "Error:  Read only space size (%d) exceeds allocated space (%d)!\n",
+                          len, read_only_space_size);
+                  exit(1);
+              }
 	      break;
 	  default:
 	      printf("Strange space ID: %ld; ignored.\n", id);
diff --git a/lisp/gencgc.c b/lisp/gencgc.c
index 79901ed9f..423cc9ca9 100644
--- a/lisp/gencgc.c
+++ b/lisp/gencgc.c
@@ -169,20 +169,20 @@ check_escaped_stack_object(lispobj * where, lispobj obj)
     if (Pointerp(obj)
 	&& (p = (void *) PTR(obj),
 	    (p >= (void *) CONTROL_STACK_START
-	     && p < (void *) CONTROL_STACK_END))) {
+	     && p < (void *) control_stack_end))) {
 	char *space;
 
 	if (where >= (lispobj *) DYNAMIC_0_SPACE_START
-	    && where < (lispobj *) (DYNAMIC_0_SPACE_START + DYNAMIC_SPACE_SIZE))
+	    && where < (lispobj *) (DYNAMIC_0_SPACE_START + dynamic_space_size))
 	    space = "dynamic space";
 	else if (where >= (lispobj *) STATIC_SPACE_START
 		 && where <
-		 (lispobj *) (STATIC_SPACE_START + STATIC_SPACE_SIZE)) space =
+		 (lispobj *) (STATIC_SPACE_START + static_space_size)) space =
 		"static space";
 	else if (where >= (lispobj *) READ_ONLY_SPACE_START
 		 && where <
 		 (lispobj *) (READ_ONLY_SPACE_START +
-			      READ_ONLY_SPACE_SIZE)) space = "read-only space";
+			      read_only_space_size)) space = "read-only space";
 	else
 	    space = NULL;
 
@@ -198,7 +198,7 @@ check_escaped_stack_object(lispobj * where, lispobj obj)
 		 (unsigned long) obj, where, space);
 #ifndef i386
 	else if ((where >= (lispobj *) CONTROL_STACK_START
-		  && where < (lispobj *) (CONTROL_STACK_END))
+		  && where < (lispobj *) (control_stack_end))
 		 || (space == NULL)) {
 	    /* Do nothing if it the reference is from the control stack,
 	       because that will happen, and that's ok.  Or if it's from
@@ -2003,7 +2003,7 @@ read_only_space_p(lispobj obj)
 static inline boolean
 control_stack_space_p(lispobj obj)
 {
-    lispobj end = CONTROL_STACK_START + CONTROL_STACK_SIZE;
+    lispobj end = CONTROL_STACK_START + control_stack_size;
 
     return (obj >= CONTROL_STACK_START) && (obj < end);
 }
@@ -2011,7 +2011,7 @@ control_stack_space_p(lispobj obj)
 static inline boolean
 binding_stack_space_p(lispobj obj)
 {
-    lispobj end = BINDING_STACK_START + BINDING_STACK_SIZE;
+    lispobj end = BINDING_STACK_START + binding_stack_size;
 
     return (obj >= BINDING_STACK_START) && (obj < end);
 }
@@ -7321,7 +7321,7 @@ garbage_collect_generation(int generation, int raise)
     invalid_stack_end = (void *) &raise;
 #else /* not i386 */
     invalid_stack_start = (void *) &raise;
-    invalid_stack_end = (void *) CONTROL_STACK_END;
+    invalid_stack_end = (void *) control_stack_end;
 #endif /* not i386 */
 #endif /* GC_ASSERTIONS */
 
@@ -7381,7 +7381,7 @@ garbage_collect_generation(int generation, int raise)
     {
 	lispobj **ptr;
 
-	for (ptr = (lispobj **) CONTROL_STACK_END - 1;
+	for (ptr = (lispobj **) control_stack_end - 1;
 	     ptr > (lispobj **) (void *) &raise; ptr--)
 	    preserve_pointer(*ptr);
     }
diff --git a/lisp/globals.c b/lisp/globals.c
index a8f561d99..471da1fc7 100644
--- a/lisp/globals.c
+++ b/lisp/globals.c
@@ -24,6 +24,7 @@ lispobj *dynamic_1_space;
 unsigned dynamic_space_size;
 lispobj *control_stack;
 
+
 #if (defined(i386) || defined(__x86_64))
 lispobj *control_stack_end;
 #endif
@@ -38,6 +39,12 @@ lispobj *current_dynamic_space_free_pointer;
 lispobj *current_auto_gc_trigger;
 #endif
 
+unsigned long read_only_space_size;
+unsigned long binding_stack_size;
+unsigned long static_space_size;
+unsigned long control_stack_size;
+
+
 void
 globals_init(void)
 {
diff --git a/lisp/globals.h b/lisp/globals.h
index 76eb770ac..bfd8c6dce 100644
--- a/lisp/globals.h
+++ b/lisp/globals.h
@@ -23,9 +23,15 @@ extern lispobj *static_space;
 extern lispobj *dynamic_0_space;
 extern lispobj *dynamic_1_space;
 extern unsigned dynamic_space_size;
+extern unsigned static_size;
 extern lispobj *control_stack;
 extern lispobj *binding_stack;
 
+extern unsigned long read_only_space_size;
+extern unsigned long binding_stack_size;
+extern unsigned long static_space_size;
+extern unsigned long control_stack_size;
+
 #if (defined(i386) || defined(__x86_64))
 extern lispobj *control_stack_end;
 #endif
diff --git a/lisp/lisp.c b/lisp/lisp.c
index 396478d05..0bd6aff1c 100644
--- a/lisp/lisp.c
+++ b/lisp/lisp.c
@@ -37,6 +37,11 @@
 #include "elf.h"
 #endif
 #endif
+
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+
 
 
 /* SIGINT handler that invokes the monitor. */
@@ -484,6 +489,26 @@ main(int argc, const char *argv[], const char *envp[])
 #else
     dynamic_space_size = DYNAMIC_SPACE_SIZE;
 #endif
+#ifdef DEFAULT_READ_ONLY_SIZE
+    read_only_space_size = DEFAULT_READ_ONLY_SIZE;
+#else
+    read_only_space_size = READ_ONLY_SPACE_SIZE;
+#endif
+#ifdef DEFAULT_STATIC_SIZE
+    static_space_size = DEFAULT_STATIC_SIZE;
+#else
+    static_space_size = STATIC_SPACE_SIZE;
+#endif
+#ifdef DEFAULT_BINDING_SIZE
+    binding_stack_size = DEFAULT_BINDING_SIZE;
+#else
+    binding_stack_size = BINDING_STACK_SIZE;
+#endif    
+#ifdef DEFAULT_CONTROL_SIZE
+    control_stack_size = DEFAULT_CONTROL_SIZE;
+#else
+    control_stack_size = CONTROL_STACK_SIZE;
+#endif
 
     argptr = argv;
     while ((arg = *++argptr) != NULL) {
@@ -511,6 +536,70 @@ main(int argc, const char *argv[], const char *envp[])
 			"-lib must be followed by a string denoting the CMUCL library path.\n");
 		exit(1);
 	    }
+        } else if (strcmp(arg, "-read-only-space-size") == 0) {
+            const char *str = *++argptr;
+
+            if (str == NULL) {
+                fprintf(stderr,
+                        "-read-only-space-size must be followed by the size in MBytes.\n");
+                exit(1);
+            }
+            read_only_space_size = atoi(str) * 1024 * 1024;
+            if (read_only_space_size > READ_ONLY_SPACE_SIZE) {
+                fprintf(stderr,
+                        "-read-only-space-size must be no greater than %lu MBytes.\n",
+                        READ_ONLY_SPACE_SIZE / (1024 * 1024UL));
+                fprintf(stderr, "  Continuing with default size.\n");
+                read_only_space_size = READ_ONLY_SPACE_SIZE;
+            }
+        } else if (strcmp(arg, "-static-space-size") == 0) {
+            const char *str = *++argptr;
+
+            if (str == NULL) {
+                fprintf(stderr,
+                        "-static-space-size must be followed by the size in MBytes.\n");
+                exit(1);
+            }
+            static_space_size = atoi(str) * 1024 * 1024;
+            if (static_space_size > STATIC_SPACE_SIZE) {
+                fprintf(stderr,
+                        "-static-space-size must be no greater than %lu MBytes.\n",
+                        STATIC_SPACE_SIZE / (1024 * 1024UL));
+                fprintf(stderr, "  Continuing with default size.\n");
+                static_space_size = STATIC_SPACE_SIZE;
+            }
+        } else if (strcmp(arg, "-binding-stack-size") == 0) {
+            const char *str = *++argptr;
+
+            if (str == NULL) {
+                fprintf(stderr,
+                        "-binding-stack-size must be followed by the size in MBytes.\n");
+                exit(1);
+            }
+            binding_stack_size = atoi(str) * 1024 * 1024;
+            if (binding_stack_size > BINDING_STACK_SIZE) {
+                fprintf(stderr,
+                        "-binding-stack-size must be no greater than %lu MBytes.\n",
+                        BINDING_STACK_SIZE / (1024 * 1024UL));
+                fprintf(stderr, "  Continuing with default size.\n");
+                binding_stack_size = BINDING_STACK_SIZE;
+            }
+        } else if (strcmp(arg, "-control-stack-size") == 0) {
+            const char *str = *++argptr;
+
+            if (str == NULL) {
+                fprintf(stderr,
+                        "-control-stack-size must be followed by the size in MBytes.\n");
+                exit(1);
+            }
+            control_stack_size = atoi(str) * 1024 * 1024;
+            if (control_stack_size > CONTROL_STACK_SIZE) {
+                fprintf(stderr,
+                        "-control-stack-size must be no greater than %lu MBytes.\n",
+                        CONTROL_STACK_SIZE / (1024 * 1024UL));
+                fprintf(stderr, "  Continuing with default size.\n");
+                control_stack_size = CONTROL_STACK_SIZE;
+            }
 	} else if (strcmp(arg, "-dynamic-space-size") == 0) {
 	    const char *str;
 
diff --git a/lisp/os-common.c b/lisp/os-common.c
index 0ab255a29..e6684b2da 100644
--- a/lisp/os-common.c
+++ b/lisp/os-common.c
@@ -431,7 +431,7 @@ guard_zones(char **yellow_start, char **red_start)
 	*red_start = end;
 	*yellow_start = *red_start + RED_ZONE_SIZE;
     } else {
-	char *end = (char *) CONTROL_STACK_START + CONTROL_STACK_SIZE;
+	char *end = (char *) CONTROL_STACK_START + control_stack_size;
 
 	*red_start = end - RED_ZONE_SIZE;
 	*yellow_start = *red_start - YELLOW_ZONE_SIZE;
@@ -443,7 +443,7 @@ guard_zones(char **yellow_start, char **red_start)
      * control stack area.
      */
 
-    char *end = (char *) CONTROL_STACK_START + CONTROL_STACK_SIZE;
+    char *end = (char *) CONTROL_STACK_START + control_stack_size;
 
     *red_start = end - RED_ZONE_SIZE;
     *yellow_start = *red_start - YELLOW_ZONE_SIZE;
diff --git a/lisp/ppc-validate.h b/lisp/ppc-validate.h
index 12c232199..444e2aa27 100644
--- a/lisp/ppc-validate.h
+++ b/lisp/ppc-validate.h
@@ -45,7 +45,7 @@
 
 #define CONTROL_STACK_START 	(0x30000000)
 #define CONTROL_STACK_SIZE  	(0x07ff8000)	/* 128 MB, almost */
-#define CONTROL_STACK_END       (CONTROL_STACK_START + CONTROL_STACK_SIZE)
+#define CONTROL_STACK_END       (CONTROL_STACK_START + control_stack_size)
 
 #define BINDING_STACK_START 	(0x38000000)
 #define BINDING_STACK_SIZE  	(0x07ff8000)	/* 128 MB, almost */
diff --git a/lisp/purify.c b/lisp/purify.c
index fe5789202..a80e07cd6 100644
--- a/lisp/purify.c
+++ b/lisp/purify.c
@@ -50,13 +50,13 @@ static lispobj *current_dynamic_space_free_pointer;
 
 
 #define assert_static_space_bounds(ptr) do { \
-   if (!((lispobj*)STATIC_SPACE_START <= ptr && ptr < (lispobj*)(STATIC_SPACE_START + STATIC_SPACE_SIZE))) \
+   if (!((lispobj*)STATIC_SPACE_START <= ptr && ptr < (lispobj*)(STATIC_SPACE_START + static_space_size))) \
       lose ("static-space overflow!  File \"%s\", line %d\n", \
 			__FILE__, __LINE__); \
 } while (0)
 
 #define assert_readonly_space_bounds(ptr) do { \
-   if (!((lispobj*)READ_ONLY_SPACE_START <= ptr && ptr < (lispobj*)(READ_ONLY_SPACE_START + READ_ONLY_SPACE_SIZE))) \
+   if (!((lispobj*)READ_ONLY_SPACE_START <= ptr && ptr < (lispobj*)(READ_ONLY_SPACE_START + read_only_space_size))) \
       lose ("readonly-space overflow!  File \"%s\", line %d\n", \
 			__FILE__, __LINE__); \
 } while (0)
@@ -1751,7 +1751,7 @@ purify(lispobj static_roots, lispobj read_only_roots)
      */
 #if !(defined(i386) || defined(__x86_64))
     os_zero((os_vm_address_t) current_control_stack_pointer,
-	    (os_vm_size_t) (CONTROL_STACK_SIZE -
+	    (os_vm_size_t) (control_stack_size -
 			    ((current_control_stack_pointer - control_stack) *
 			     sizeof(lispobj))));
 #endif
diff --git a/lisp/solaris-os.c b/lisp/solaris-os.c
index 815a36dde..fa1a45e6c 100644
--- a/lisp/solaris-os.c
+++ b/lisp/solaris-os.c
@@ -194,14 +194,14 @@ boolean valid_addr(os_vm_address_t addr)
 
     /* Just assume address is valid if it lies within one of the known
        spaces.  (Unlike sunos-os which keeps track of every valid page.) */
-    return (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
-	    || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
+    return (in_range_p(addr, READ_ONLY_SPACE_START, read_only_space_size)
+	    || in_range_p(addr, STATIC_SPACE_START, static_space_size)
 	    || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
 #ifndef GENCGC
 	    || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
 #endif
-	    || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
-	    || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE));
+	    || in_range_p(addr, CONTROL_STACK_START, control_stack_size)
+	    || in_range_p(addr, BINDING_STACK_START, binding_stack_size));
 }
 
 /* ---------------------------------------------------------------- */
@@ -422,9 +422,9 @@ static os_vm_address_t spaces[] = {
  * SPARSE_BLOCK_SIZE boundaries.
  
  */
-static unsigned long space_size[] = {
-    READ_ONLY_SPACE_SIZE, STATIC_SPACE_SIZE,
-    BINDING_STACK_SIZE, CONTROL_STACK_SIZE
+static unsigned long *space_size[] = {
+    &read_only_space_size, &static_space_size,
+    &binding_stack_size, &control_stack_size
 };
 
 /*
@@ -444,7 +444,7 @@ make_holes(void)
 
     for (k = 0; k < sizeof(spaces) / sizeof(spaces[0]); ++k) {
 
-	hole = spaces[k] + space_size[k];
+	hole = spaces[k] + *space_size[k];
 
 	if (os_validate(hole, HOLE_SIZE) == NULL) {
 	    fprintf(stderr,
diff --git a/lisp/sparc-arch.c b/lisp/sparc-arch.c
index 364537dec..0d985997e 100644
--- a/lisp/sparc-arch.c
+++ b/lisp/sparc-arch.c
@@ -45,7 +45,7 @@ arch_get_bad_addr(HANDLER_ARGS)
     /* that caused the fault. */
     if ((SC_PC(context) & 3) != 0 ||
 	((SC_PC(context) < READ_ONLY_SPACE_START ||
-	  SC_PC(context) >= READ_ONLY_SPACE_START + READ_ONLY_SPACE_SIZE) &&
+	  SC_PC(context) >= READ_ONLY_SPACE_START + read_only_space_size) &&
 	 ((lispobj *) SC_PC(context) < current_dynamic_space &&
 	  (lispobj *) SC_PC(context) >=
 	  current_dynamic_space + dynamic_space_size))) return 0;
diff --git a/lisp/sparc-validate.h b/lisp/sparc-validate.h
index a326c2296..7ef7af474 100644
--- a/lisp/sparc-validate.h
+++ b/lisp/sparc-validate.h
@@ -102,7 +102,7 @@
 
 #define CONTROL_STACK_START 	(0x38000000)
 #define CONTROL_STACK_SIZE  	(MB_128 - SPARSE_BLOCK_SIZE)	/* 128 MB - 32 KB, 128 MB max */
-#define CONTROL_STACK_END       (CONTROL_STACK_START + CONTROL_STACK_SIZE)
+#define CONTROL_STACK_END       (CONTROL_STACK_START + control_stack_size)
 
 #define DYNAMIC_0_SPACE_START	(SpaceStart_TargetDynamic)
 
diff --git a/lisp/sunos-os.c b/lisp/sunos-os.c
index 775eb4060..ccbabd820 100644
--- a/lisp/sunos-os.c
+++ b/lisp/sunos-os.c
@@ -69,6 +69,10 @@ static int zero_fd = (-1), empty_fd = (-1);
 static os_vm_address_t last_fault = 0;
 static os_vm_size_t real_page_size_difference = 0;
 
+void
+os_init0(const char *argv[], const char *envp[])
+{}
+
 static void
 os_init_bailout(arg)
      char *arg;
diff --git a/lisp/validate.c b/lisp/validate.c
index 7d7cb8bae..efe727363 100644
--- a/lisp/validate.c
+++ b/lisp/validate.c
@@ -18,11 +18,6 @@
 #include "validate.h"
 #include "internals.h"
 
-unsigned long read_only_space_size = READ_ONLY_SPACE_SIZE;
-unsigned long binding_stack_size = BINDING_STACK_SIZE;
-unsigned long static_space_size = STATIC_SPACE_SIZE;
-unsigned long control_stack_size = CONTROL_STACK_SIZE;
-
 #ifdef sparc
 extern void make_holes(void);
 #endif
@@ -61,7 +56,7 @@ validate(void)
        FMG
     */
     ensure_space((lispobj *)((int)read_only_space + image_read_only_space_size),
-		 READ_ONLY_SPACE_SIZE - image_read_only_space_size);
+		 read_only_space_size - image_read_only_space_size);
 
     /* Static Space */
     static_space = (lispobj *) STATIC_SPACE_START;
@@ -71,7 +66,7 @@ validate(void)
        FMG
     */
     ensure_space((lispobj *)((int)static_space + image_static_space_size),
-		 STATIC_SPACE_SIZE - image_static_space_size);
+		 static_space_size - image_static_space_size);
 
     /* Dynamic-0 Space */
     dynamic_0_space = (lispobj *) DYNAMIC_0_SPACE_START;
@@ -102,9 +97,9 @@ validate(void)
     /* Control Stack */
     control_stack = (lispobj *) CONTROL_STACK_START;
 #if (defined(i386) || defined(__x86_64))
-    control_stack_end = (lispobj *) (CONTROL_STACK_START + CONTROL_STACK_SIZE);
+    control_stack_end = (lispobj *) (CONTROL_STACK_START + control_stack_size);
 #endif
-    ensure_space(control_stack, CONTROL_STACK_SIZE);
+    ensure_space(control_stack, control_stack_size);
 
 #ifdef SIGNAL_STACK_START
     ensure_space((lispobj *) SIGNAL_STACK_START, SIGNAL_STACK_SIZE);
@@ -112,7 +107,7 @@ validate(void)
 
     /* Binding Stack */
     binding_stack = (lispobj *) BINDING_STACK_START;
-    ensure_space(binding_stack, BINDING_STACK_SIZE);
+    ensure_space(binding_stack, binding_stack_size);
 #ifdef LINKAGE_TABLE
     ensure_space((lispobj *) FOREIGN_LINKAGE_SPACE_START,
 		 FOREIGN_LINKAGE_SPACE_SIZE);
diff --git a/lisp/x86-assem.S b/lisp/x86-assem.S
index 84759df1b..178e913b3 100644
--- a/lisp/x86-assem.S
+++ b/lisp/x86-assem.S
@@ -207,12 +207,12 @@ npx_save_done:
 	movl	%esp,%ebx	# remember current stack
 	cmpl	$CONTROL_STACK_START,%esp
 	jbe	ChangeToLispStack
-	cmpl	$CONTROL_STACK_END,%esp
+	cmpl	GNAME(control_stack_end), %esp
 	jbe	OnLispStack
 ChangeToLispStack:
 	/* Setup the *alien-stack* pointer */
 	movl	%esp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
-	movl	$CONTROL_STACK_END,%esp		# New stack
+	movl	GNAME(control_stack_end), %esp		# New stack
 OnLispStack:
 	pushl	%ebx		# save entry stack on (maybe) new stack
 
diff --git a/lisp/x86-validate.h b/lisp/x86-validate.h
index e5c6d4f59..c49ea50e9 100644
--- a/lisp/x86-validate.h
+++ b/lisp/x86-validate.h
@@ -182,6 +182,7 @@
 
 #define CONTROL_STACK_START	0x38000000
 #define CONTROL_STACK_SIZE	(0x07fff000 - 8192)
+
 #define SIGNAL_STACK_START	CONTROL_STACK_END
 #define SIGNAL_STACK_SIZE	SIGSTKSZ
 
@@ -245,7 +246,7 @@
 #endif
 #endif
 
-#define CONTROL_STACK_END	(CONTROL_STACK_START + CONTROL_STACK_SIZE)
+#define CONTROL_STACK_END	(CONTROL_STACK_START + control_stack_size)
 
 /* Note that GENCGC only uses dynamic_space 0. */
 #define DYNAMIC_1_SPACE_START	(DYNAMIC_0_SPACE_START + DYNAMIC_SPACE_SIZE)
-- 
GitLab