From 1a4de9dd58201bb57a07ea931d1764064fc52e64 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 22 Sep 2018 00:32:03 -0700 Subject: 4588 --- html/subx/020syscalls.cc.html | 171 ++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 82 deletions(-) (limited to 'html/subx/020syscalls.cc.html') diff --git a/html/subx/020syscalls.cc.html b/html/subx/020syscalls.cc.html index 9b18f151..532275c0 100644 --- a/html/subx/020syscalls.cc.html +++ b/html/subx/020syscalls.cc.html @@ -81,93 +81,100 @@ if ('onhashchange' in window) { 21 exit(/*exit code*/Reg[EBX].u); 22 break; 23 case 3: - 24 trace(91, "run") << "read: " << Reg[EBX].u << ' ' << Reg[ECX].u << '/' << mem_addr_string(Reg[ECX].u) << ' ' << Reg[EDX].u << end(); - 25 Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); - 26 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 27 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 28 break; - 29 case 4: - 30 trace(91, "run") << "write: " << Reg[EBX].u << ' ' << Reg[ECX].u << '/' << mem_addr_string(Reg[ECX].u) << ' ' << Reg[EDX].u << end(); - 31 Reg[EAX].i = write(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); - 32 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 33 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 34 break; - 35 case 5: { - 36 check_flags(ECX); - 37 check_mode(EDX); - 38 trace(91, "run") << "open: " << Reg[EBX].u << '/' << mem_addr_string(Reg[EBX].u) << ' ' << Reg[ECX].u << end(); - 39 Reg[EAX].i = open(/*filename*/mem_addr_string(Reg[EBX].u), /*flags*/Reg[ECX].u, /*mode*/0640); - 40 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 41 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 42 break; - 43 } - 44 case 6: - 45 trace(91, "run") << "close: " << Reg[EBX].u << end(); - 46 Reg[EAX].i = close(/*file descriptor*/Reg[EBX].u); - 47 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 48 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 49 break; - 50 case 8: - 51 check_mode(ECX); - 52 trace(91, "run") << "creat: " << Reg[EBX].u << '/' << mem_addr_string(Reg[EBX].u) << end(); - 53 Reg[EAX].i = creat(/*filename*/mem_addr_string(Reg[EBX].u), /*mode*/0640); - 54 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 55 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 56 break; - 57 case 10: - 58 trace(91, "run") << "unlink: " << Reg[EBX].u << '/' << mem_addr_string(Reg[EBX].u) << end(); - 59 Reg[EAX].i = unlink(/*filename*/mem_addr_string(Reg[EBX].u)); - 60 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 61 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 62 break; - 63 case 38: - 64 trace(91, "run") << "rename: " << Reg[EBX].u << '/' << mem_addr_string(Reg[EBX].u) << " -> " << Reg[ECX].u << '/' << mem_addr_string(Reg[ECX].u) << end(); - 65 Reg[EAX].i = rename(/*old filename*/mem_addr_string(Reg[EBX].u), /*new filename*/mem_addr_string(Reg[ECX].u)); - 66 trace(91, "run") << "result: " << Reg[EAX].i << end(); - 67 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); - 68 break; - 69 case 45: // brk: modify size of data segment - 70 trace(91, "run") << "grow data segment to " << Reg[EBX].u << end(); - 71 resize_mem(/*new end address*/Reg[EBX].u); - 72 break; - 73 default: - 74 raise << HEXWORD << EIP << ": unimplemented syscall " << Reg[EAX].u << '\n' << end(); - 75 } - 76 } - 77 - 78 // SubX is oblivious to file permissions, directories, symbolic links, terminals, and much else besides. - 79 // Also ignoring any concurrency considerations for now. - 80 void check_flags(int reg) { - 81 uint32_t flags = Reg[reg].u; - 82 if (flags != ((flags & O_RDONLY) | (flags & O_WRONLY))) { - 83 cerr << HEXWORD << EIP << ": most POSIX flags to the open() syscall are not supported. Just O_RDONLY and O_WRONLY for now. Zero concurrent access support.\n"; - 84 exit(1); - 85 } - 86 if ((flags & O_RDONLY) && (flags & O_WRONLY)) { - 87 cerr << HEXWORD << EIP << ": can't open a file for both reading and writing at once. See http://man7.org/linux/man-pages/man2/open.2.html.\n"; - 88 exit(1); - 89 } - 90 } - 91 - 92 void check_mode(int reg) { - 93 if (Reg[reg].u != 0600) { - 94 cerr << HEXWORD << EIP << ": SubX is oblivious to file permissions; register " << reg << " must be 0.\n"; + 24 trace(91, "run") << "read: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end(); + 25 trace(91, "run") << Reg[ECX].u << " => " << mem_addr_string(Reg[ECX].u) << end(); + 26 Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); + 27 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 28 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 29 break; + 30 case 4: + 31 trace(91, "run") << "write: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end(); + 32 trace(91, "run") << Reg[ECX].u << " => " << mem_addr_string(Reg[ECX].u) << end(); + 33 Reg[EAX].i = write(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); + 34 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 35 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 36 break; + 37 case 5: { + 38 check_flags(ECX); + 39 check_mode(EDX); + 40 trace(91, "run") << "open: " << Reg[EBX].u << ' ' << Reg[ECX].u << end(); + 41 trace(91, "run") << Reg[EBX].u << " => " << mem_addr_string(Reg[EBX].u) << end(); + 42 Reg[EAX].i = open(/*filename*/mem_addr_string(Reg[EBX].u), /*flags*/Reg[ECX].u, /*mode*/0640); + 43 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 44 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 45 break; + 46 } + 47 case 6: + 48 trace(91, "run") << "close: " << Reg[EBX].u << end(); + 49 Reg[EAX].i = close(/*file descriptor*/Reg[EBX].u); + 50 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 51 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 52 break; + 53 case 8: + 54 check_mode(ECX); + 55 trace(91, "run") << "creat: " << Reg[EBX].u << end(); + 56 trace(91, "run") << Reg[EBX].u << " => " << mem_addr_string(Reg[EBX].u) << end(); + 57 Reg[EAX].i = creat(/*filename*/mem_addr_string(Reg[EBX].u), /*mode*/0640); + 58 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 59 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 60 break; + 61 case 10: + 62 trace(91, "run") << "unlink: " << Reg[EBX].u << end(); + 63 trace(91, "run") << Reg[EBX].u << " => " << mem_addr_string(Reg[EBX].u) << end(); + 64 Reg[EAX].i = unlink(/*filename*/mem_addr_string(Reg[EBX].u)); + 65 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 66 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 67 break; + 68 case 38: + 69 trace(91, "run") << "rename: " << Reg[EBX].u << " -> " << Reg[ECX].u << end(); + 70 trace(91, "run") << Reg[EBX].u << " => " << mem_addr_string(Reg[EBX].u) << end(); + 71 trace(91, "run") << Reg[ECX].u << " => " << mem_addr_string(Reg[ECX].u) << end(); + 72 Reg[EAX].i = rename(/*old filename*/mem_addr_string(Reg[EBX].u), /*new filename*/mem_addr_string(Reg[ECX].u)); + 73 trace(91, "run") << "result: " << Reg[EAX].i << end(); + 74 if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + 75 break; + 76 case 45: // brk: modify size of data segment + 77 trace(91, "run") << "grow data segment to " << Reg[EBX].u << end(); + 78 resize_mem(/*new end address*/Reg[EBX].u); + 79 break; + 80 default: + 81 raise << HEXWORD << EIP << ": unimplemented syscall " << Reg[EAX].u << '\n' << end(); + 82 } + 83 } + 84 + 85 // SubX is oblivious to file permissions, directories, symbolic links, terminals, and much else besides. + 86 // Also ignoring any concurrency considerations for now. + 87 void check_flags(int reg) { + 88 uint32_t flags = Reg[reg].u; + 89 if (flags != ((flags & O_RDONLY) | (flags & O_WRONLY))) { + 90 cerr << HEXWORD << EIP << ": most POSIX flags to the open() syscall are not supported. Just O_RDONLY and O_WRONLY for now. Zero concurrent access support.\n"; + 91 exit(1); + 92 } + 93 if ((flags & O_RDONLY) && (flags & O_WRONLY)) { + 94 cerr << HEXWORD << EIP << ": can't open a file for both reading and writing at once. See http://man7.org/linux/man-pages/man2/open.2.html.\n"; 95 exit(1); 96 } 97 } 98 - 99 void resize_mem(uint32_t new_end_address) { -100 if (new_end_address < Mem_offset) { -101 raise << HEXWORD << EIP << ": can't shrink data segment to before code segment\n"; -102 return; + 99 void check_mode(int reg) { +100 if (Reg[reg].u != 0600) { +101 cerr << HEXWORD << EIP << ": SubX is oblivious to file permissions; register " << reg << " must be 0.\n"; +102 exit(1); 103 } -104 int32_t new_size = new_end_address - Mem_offset; -105 if (new_size < SIZE(Mem)) { -106 raise << HEXWORD << EIP << ": shrinking data segment is not supported.\n" << end(); -107 return; -108 } -109 Mem.resize(new_size); // will throw exception on failure -110 } +104 } +105 +106 void resize_mem(uint32_t new_end_address) { +107 if (new_end_address < Mem_offset) { +108 raise << HEXWORD << EIP << ": can't shrink data segment to before code segment\n"; +109 return; +110 } +111 int32_t new_size = new_end_address - Mem_offset; +112 if (new_size < SIZE(Mem)) { +113 raise << HEXWORD << EIP << ": shrinking data segment is not supported.\n" << end(); +114 return; +115 } +116 Mem.resize(new_size); // will throw exception on failure +117 } -- cgit 1.4.1-2-gfad0