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.cc17
1 files changed, 17 insertions, 0 deletions
diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc
index 2940b06c..5fdc40f6 100644
--- a/subx/020syscalls.cc
+++ b/subx/020syscalls.cc
@@ -77,6 +77,12 @@ void process_int80() {
     trace(91, "run") << "grow data segment to " << Reg[EBX].u << end();
     grow_data_segment(/*new end address*/Reg[EBX].u);
     break;
+  case 90:  // mmap: allocate memory outside existing segment allocations
+    trace(91, "run") << "mmap: allocate new segment" << end();
+    // Ignore most arguments for now: address hint, protection flags, sharing flags, fd, offset.
+    // We only support anonymous maps.
+    Reg[EAX].u = new_segment(/*length*/read_mem_u32(Reg[EBX].u+0x4));
+    break;
   default:
     raise << HEXWORD << EIP << ": unimplemented syscall " << Reg[EAX].u << '\n' << end();
   }
@@ -102,3 +108,14 @@ void check_mode(int reg) {
     exit(1);
   }
 }
+
+:(before "End Globals")
+uint32_t Next_segment = 0xb0000000;  // 0xc0000000 and up is reserved for Linux kernel
+const uint32_t SPACE_FOR_SEGMENT = 0x01000000;
+:(code)
+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;
+  return result;
+}