Browse Source

UserspaceEmulator: Add some more syscalls

We can now unmap mapped memory, among other things. This is all very
ad-hoc as I'm trying to run UserspaceEmulator inside itself. :^)
Andreas Kling 5 năm trước cách đây
mục cha
commit
e0580e2975

+ 37 - 1
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;

+ 4 - 0
DevTools/UserspaceEmulator/Emulator.h

@@ -58,6 +58,7 @@ private:
     void setup_stack(const Vector<String>& 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);

+ 5 - 0
DevTools/UserspaceEmulator/SoftMMU.cpp

@@ -48,6 +48,11 @@ void SoftMMU::add_region(NonnullOwnPtr<Region> region)
     m_regions.append(move(region));
 }
 
+void SoftMMU::remove_region(Region& region)
+{
+    m_regions.remove_first_matching([&](auto& entry) { return entry.ptr() == &region; });
+}
+
 void SoftMMU::set_tls_region(NonnullOwnPtr<Region> region)
 {
     ASSERT(!m_tls_region);

+ 2 - 0
DevTools/UserspaceEmulator/SoftMMU.h

@@ -76,6 +76,8 @@ public:
     Region* find_region(X86::LogicalAddress);
 
     void add_region(NonnullOwnPtr<Region>);
+    void remove_region(Region&);
+
     void set_tls_region(NonnullOwnPtr<Region>);
 
     void copy_to_vm(FlatPtr destination, const void* source, size_t);