about summary refs log tree commit diff stats
path: root/subx/020syscalls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/020syscalls.cc')
-rw-r--r--subx/020syscalls.cc19
1 files changed, 11 insertions, 8 deletions
diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc
index 6b9faa2c..eb8ebcce 100644
--- a/subx/020syscalls.cc
+++ b/subx/020syscalls.cc
@@ -111,16 +111,19 @@ void check_mode(int reg) {
 
 :(before "End Globals")
 // Very primitive/fixed/insecure mmap segments for now.
-// For now we avoid addresses with the most significant bit set; SubX doesn't
-// support unsigned comparison yet (https://github.com/akkartik/mu/issues/30)
-// Once we do, we can go up to 0xc0000000; higher addresses are reserved for
-// the Linux kernel.
-uint32_t Next_segment = 0x7c000000;
+uint32_t Segments_allocated_above = END_HEAP;
 const uint32_t SPACE_FOR_SEGMENT = 0x01000000;
 :(code)
+// always allocate multiples of the segment size
 uint32_t new_segment(uint32_t length) {
-  uint32_t result = Next_segment;
-  Mem.push_back(vma(Next_segment, Next_segment+length));
-  Next_segment -= SPACE_FOR_SEGMENT;
+  assert(length > 0);
+  uint32_t result = (Segments_allocated_above - length) & 0xff000000;
+  if (result <= START_HEAP) {
+    raise << "Allocated too many segments; the VM ran out of memory. "
+          << "Maybe SPACE_FOR_SEGMENT can be smaller?\n" << end();
+    exit(1);
+  }
+  Mem.push_back(vma(result, result+length));
+  Segments_allocated_above = result;
   return result;
 }