diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-09-29 16:17:11 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-09-29 17:45:00 -0700 |
commit | 2ec6d1e5250e5a36c919354649c3bc3f17261140 (patch) | |
tree | 862c561e9b727496a2a8c0aea379bf4f42c60f7a /subx | |
parent | 64338cc5d7c11cc25870c19f39c502921e471e65 (diff) | |
download | mu-2ec6d1e5250e5a36c919354649c3bc3f17261140.tar.gz |
4619 - new syscall: mmap()
Diffstat (limited to 'subx')
-rw-r--r-- | subx/020syscalls.cc | 17 | ||||
-rw-r--r-- | subx/035labels.cc | 2 | ||||
-rwxr-xr-x | subx/examples/ex12 | bin | 0 -> 167 bytes | |||
-rw-r--r-- | subx/examples/ex12.subx | 43 |
4 files changed, 61 insertions, 1 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; +} diff --git a/subx/035labels.cc b/subx/035labels.cc index ddaeabad..75000233 100644 --- a/subx/035labels.cc +++ b/subx/035labels.cc @@ -42,7 +42,7 @@ b9/copy aaa/imm32 # copy to ECX b9/copy xxx/imm32 # copy to ECX +transform: packing instruction 'b9/copy xxx/imm32' # no change (we're just not printing metadata to the trace) -+transform: instruction after packing: 'b9 xx' ++transform: instruction after packing: 'b9 xxx' //: a helper we'll find handy later :(code) diff --git a/subx/examples/ex12 b/subx/examples/ex12 new file mode 100755 index 00000000..236afe98 --- /dev/null +++ b/subx/examples/ex12 Binary files differdiff --git a/subx/examples/ex12.subx b/subx/examples/ex12.subx new file mode 100644 index 00000000..50c57928 --- /dev/null +++ b/subx/examples/ex12.subx @@ -0,0 +1,43 @@ +## example showing mmap syscall +# Create a new segment using mmap, save the address, write to it. +# +# To run: +# $ subx translate ex12.subx ex12 +# $ subx run ex12 +# You shouldn't get a segmentation fault. + +== code +# instruction effective address operand displacement immediate +# op subop mod rm32 base index scale r32 +# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes + + # mmap(0x1000) + bb/copy . . . . . . . mmap_new_segment/imm32 # copy to EBX + b8/copy . . . . . . . 0x5a/imm32/mmap # copy 8 to EAX + cd/syscall 0x80/imm8 + + # store to *EAX + c7/copy 0/mod/direct 0/rm32/EAX . . . . . 0x34/imm32 # copy 0x34 to *EAX + + # exit(EAX) + 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX + b8/copy . . . . . . . 1/imm32/exit # copy 1 to EAX + cd/syscall 0x80/imm8 + +== data +# various constants used here were found in the Linux sources (search for file mman-common.h) +mmap_new_segment: # type mmap_arg_struct + # addr + 00 00 00 00 # null + # len + 00 01 00 00 # 0x1000 + # protection flags + 03 00 00 00 # PROT_READ | PROT_WRITE + # sharing flags + 22 00 00 00 # MAP_PRIVATE | MAP_ANONYMOUS + # fd + ff ff ff ff # -1 since MAP_ANONYMOUS is specified + # offset + 00 00 00 00 # 0 since MAP_ANONYMOUS is specified + +# vim:ft=subx:nowrap:tw& |