diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index 8fdad15d16..961d08533f 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -188,6 +188,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) switch (function) { case SC_mmap: return virt$mmap(arg1); + case SC_munmap: + return virt$munmap(arg1, arg2); case SC_gettid: return virt$gettid(); case SC_getpid: @@ -222,11 +224,17 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$lseek(arg1, arg2, arg3); case SC_get_process_name: return virt$get_process_name(arg1, arg2); + case SC_dbgputstr: + return virt$dbgputstr(arg1, arg2); + case SC_dbgputch: + return virt$dbgputch(arg1); + case SC_kill: + return virt$kill(arg1, arg2); case SC_exit: virt$exit((int)arg1); return 0; default: - warn() << "Unimplemented syscall!"; + warn() << "Unimplemented syscall: " << Syscall::to_string((Syscall::Function)function); dump_backtrace(); TODO(); } @@ -247,6 +255,24 @@ int Emulator::virt$close(int fd) return syscall(SC_close, fd); } +int Emulator::virt$dbgputstr(FlatPtr characters, int length) +{ + auto buffer = mmu().copy_buffer_from_vm(characters, length); + dbgputstr((const char*)buffer.data(), buffer.size()); + return 0; +} + +int Emulator::virt$dbgputch(char ch) +{ + dbgputch(ch); + return 0; +} + +int Emulator::virt$kill(pid_t pid, int signal) +{ + return syscall(SC_kill, pid, signal); +} + int Emulator::virt$get_process_name(FlatPtr buffer, int size) { if (size < 9) @@ -303,6 +329,16 @@ u32 Emulator::virt$open(u32 params_addr) return fd; } +u32 Emulator::virt$munmap(FlatPtr address, u32 size) +{ + auto* region = mmu().find_region({ 0x20, address }); + ASSERT(region); + if (region->size() != round_up_to_power_of_two(size, PAGE_SIZE)) + TODO(); + mmu().remove_region(*region); + return 0; +} + u32 Emulator::virt$mmap(u32 params_addr) { Syscall::SC_mmap_params params; diff --git a/DevTools/UserspaceEmulator/Emulator.h b/DevTools/UserspaceEmulator/Emulator.h index d0f395f74c..7f88f8697d 100644 --- a/DevTools/UserspaceEmulator/Emulator.h +++ b/DevTools/UserspaceEmulator/Emulator.h @@ -58,6 +58,7 @@ private: void setup_stack(const Vector& arguments); u32 virt$mmap(u32); + u32 virt$munmap(FlatPtr address, u32 size); u32 virt$gettid(); u32 virt$getpid(); u32 virt$unveil(u32); @@ -71,6 +72,9 @@ private: u32 virt$open(u32); int virt$close(int); int virt$get_process_name(FlatPtr buffer, int size); + int virt$dbgputstr(FlatPtr characters, int length); + int virt$dbgputch(char); + int virt$kill(pid_t, int); int virt$fstat(int, FlatPtr); u32 virt$fcntl(int fd, int, u32); int virt$getgroups(ssize_t count, FlatPtr); diff --git a/DevTools/UserspaceEmulator/SoftMMU.cpp b/DevTools/UserspaceEmulator/SoftMMU.cpp index a1c8485d2b..b2ef013a05 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.cpp +++ b/DevTools/UserspaceEmulator/SoftMMU.cpp @@ -48,6 +48,11 @@ void SoftMMU::add_region(NonnullOwnPtr region) m_regions.append(move(region)); } +void SoftMMU::remove_region(Region& region) +{ + m_regions.remove_first_matching([&](auto& entry) { return entry.ptr() == ®ion; }); +} + void SoftMMU::set_tls_region(NonnullOwnPtr region) { ASSERT(!m_tls_region); diff --git a/DevTools/UserspaceEmulator/SoftMMU.h b/DevTools/UserspaceEmulator/SoftMMU.h index 4fad77a391..53c75598d6 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.h +++ b/DevTools/UserspaceEmulator/SoftMMU.h @@ -76,6 +76,8 @@ public: Region* find_region(X86::LogicalAddress); void add_region(NonnullOwnPtr); + void remove_region(Region&); + void set_tls_region(NonnullOwnPtr); void copy_to_vm(FlatPtr destination, const void* source, size_t);