From c40b7a6bd91ee60ec4e1fbbffbfe8b4ad090ec52 Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Tue, 29 Aug 2017 10:38:13 -0700
Subject: [PATCH] Fix #40: Move start of heap space higher

This is a workaround for issue #40.  By moving the start of the heap
to a higher address, we can still run on older systems (albeit with
reduced max heap size), and run on newer systesm where the C code is
now mapped at or overlapping the (old) heap start.  Arbitrarily choose
0x60000000 as a compromise.

This also requires moving the foreign linkage start to a different
address because the old address overlaps the new C area.

Ideally, we could fix this if we could map the heap wherever the OS
wants to put it, but we're not there yet.

Use boot-2017-04.lisp to bootstrap this change from the 2017-04
snapshot.
---
 src/bootfiles/21b/boot-2017-04.lisp | 25 +++++++++++++++++++++++++
 src/compiler/x86/parms.lisp         |  4 ++--
 src/lisp/x86-validate-linux.h       | 18 ++++++++++++++++++
 3 files changed, 45 insertions(+), 2 deletions(-)
 create mode 100644 src/bootfiles/21b/boot-2017-04.lisp

diff --git a/src/bootfiles/21b/boot-2017-04.lisp b/src/bootfiles/21b/boot-2017-04.lisp
new file mode 100644
index 000000000..6a8364a5d
--- /dev/null
+++ b/src/bootfiles/21b/boot-2017-04.lisp
@@ -0,0 +1,25 @@
+;; Bootstrap file for linuu to move the heap to a higher address so
+;; that executables will work on newer OSes, as mentioned in issue
+;; #40.
+;;
+;; Use "bin/build.sh -B boot-2017-04" to build this.
+;;
+;; Also need to move the foreign linkage start to a different address
+;; because this also overlaps where the C code is placed in an
+;; executable image.
+;;
+;; This reduces the max total heap space on older systems, but it
+;; looks like newer systems have the C libraries and stack mapped at a
+;; much higher address.
+
+#+linux
+(setf (c::backend-foreign-linkage-space-start c::*target-backend*)
+      #x5f000000)
+
+#+linux
+(defconstant vm::target-foreign-linkage-space-start
+  (c:backend-foreign-linkage-space-start c::*target-backend*))
+
+#+linux
+(defconstant vm::target-dynamic-space-start
+  #x60000000)
diff --git a/src/compiler/x86/parms.lisp b/src/compiler/x86/parms.lisp
index 228df997d..f3ff12d0c 100644
--- a/src/compiler/x86/parms.lisp
+++ b/src/compiler/x86/parms.lisp
@@ -64,7 +64,7 @@
 (setf (backend-page-size *target-backend*) 4096)
 
 (setf (c::backend-foreign-linkage-space-start *target-backend*)
-      #+linux #x58000000
+      #+linux #x5f000000
       #+solaris #x30000000
       #-(or linux solaris) #xB0000000
       (c::backend-foreign-linkage-entry-size *target-backend*)
@@ -235,7 +235,7 @@
   #+FreeBSD #x28F00000
   #-FreeBSD #x28000000)
 (defconstant target-dynamic-space-start
-  #+linux #x58100000
+  #+linux #x60000000
   #+solaris #x40000000
   #-(or linux solaris) #x48000000)
 (defconstant target-foreign-linkage-space-start
diff --git a/src/lisp/x86-validate-linux.h b/src/lisp/x86-validate-linux.h
index 36688340c..af5422548 100644
--- a/src/lisp/x86-validate-linux.h
+++ b/src/lisp/x86-validate-linux.h
@@ -37,6 +37,24 @@
  * However, Fedora 22 ther appears to be nothing mapped there.  In
  * fact it appears to be free all the way to 0xf7c1b000.  That would
  * allow a heap of size 2555 MB.
+ *
+ * On even newer OSes like Ubuntu 17.04, the map looks something like
+ *
+ *	0x00000000->0x10000000  128M ?
+ *	0x10000000->0x20000000  256M Read-Only Space.
+ *	0x20000000->0x28000000  128M Binding stack growing up.
+ *	0x28000000->0x38000000  256M Static Space.
+ *      0x38000000->                 ?
+ *      0x56555000->                 C space
+ *      0xf7dfe000->                 [anon]
+ *      0xf7e00000->0xf7fb4000       libc.so
+ *      0xf7fb5000->0xf7fd9000       [anon]
+ *      0xf7fd9000->0xf7ffd000       ld.so
+ *      0xfffdd000->                 [stack]
+ *
+ * There's a potential clash if the lisp heap is mapped near
+ * 0x58100000 as shown above.  This happens if a lisp exectuable image
+ * is created.
  */
 
 #define READ_ONLY_SPACE_START   (SpaceStart_TargetReadOnly)
-- 
GitLab