diff options
Diffstat (limited to 'subx/020syscalls.cc')
-rw-r--r-- | subx/020syscalls.cc | 17 |
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; +} |