UserspaceEmulator: Implement/stub out various syscalls

Moving forward on getting /bin/id to run inside the emulator. :^)
This commit is contained in:
Andreas Kling 2020-07-12 20:25:41 +02:00
parent 56d3a949e6
commit 1b196df4c4
2 changed files with 83 additions and 1 deletions

View file

@ -31,6 +31,7 @@
#include <Kernel/API/Syscall.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
namespace UserspaceEmulator {
@ -216,8 +217,10 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
(void)arg2;
(void)arg3;
printf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function);
dbgprintf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function);
switch (function) {
case SC_mmap:
return virt$mmap(arg1);
case SC_gettid:
return virt$gettid();
case SC_pledge:
@ -226,6 +229,16 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
return virt$unveil(arg1);
case SC_getuid:
return virt$getuid();
case SC_getgid:
return virt$getgid();
case SC_write:
return virt$write(arg1, arg2, arg3);
case SC_read:
return virt$read(arg1, arg2, arg3);
case SC_mprotect:
return virt$mprotect(arg1, arg2, arg3);
case SC_madvise:
return virt$madvise(arg1, arg2, arg3);
case SC_exit:
virt$exit((int)arg1);
return 0;
@ -236,6 +249,34 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
}
}
u32 Emulator::virt$mmap(u32 params_addr)
{
Syscall::SC_mmap_params params;
mmu().copy_from_vm(&params, params_addr, sizeof(params));
ASSERT(params.addr == 0);
ASSERT(params.flags & MAP_ANONYMOUS);
// FIXME: Write a proper VM allocator
static u32 next_address = 0x30000000;
u32 final_address = 0;
u32 final_size = round_up_to_power_of_two(params.size, PAGE_SIZE);
if (params.alignment) {
// FIXME: What if alignment is not a power of 2?
final_address = round_up_to_power_of_two(next_address, params.alignment);
} else {
final_address = next_address;
}
next_address = final_address + final_size;
mmu().add_region(make<SimpleRegion>(final_address, final_size));
return final_address;
}
u32 Emulator::virt$gettid()
{
return gettid();
@ -251,11 +292,46 @@ u32 Emulator::virt$unveil(u32)
return 0;
}
u32 Emulator::virt$mprotect(FlatPtr, size_t, int)
{
return 0;
}
u32 Emulator::virt$madvise(FlatPtr, size_t, int)
{
return 0;
}
uid_t Emulator::virt$getuid()
{
return getuid();
}
uid_t Emulator::virt$getgid()
{
return getgid();
}
u32 Emulator::virt$write(int fd, FlatPtr data, ssize_t size)
{
if (size < 0)
return -EINVAL;
auto buffer = mmu().copy_buffer_from_vm(data, size);
return syscall(SC_write, fd, buffer.data(), buffer.size());
}
u32 Emulator::virt$read(int fd, FlatPtr buffer, ssize_t size)
{
if (size < 0)
return -EINVAL;
auto local_buffer = ByteBuffer::create_uninitialized(size);
int nread = syscall(SC_read, fd, local_buffer.data(), local_buffer.size());
if (nread < 0)
return nread;
mmu().copy_to_vm(buffer, local_buffer.data(), local_buffer.size());
return nread;
}
void Emulator::virt$exit(int status)
{
out() << "exit(" << status << "), shutting down!";

View file

@ -55,10 +55,16 @@ private:
void setup_stack();
u32 virt$mmap(u32);
u32 virt$gettid();
u32 virt$unveil(u32);
u32 virt$pledge(u32);
uid_t virt$getuid();
gid_t virt$getgid();
u32 virt$read(int, FlatPtr, ssize_t);
u32 virt$write(int, FlatPtr, ssize_t);
u32 virt$mprotect(FlatPtr, size_t, int);
u32 virt$madvise(FlatPtr, size_t, int);
void virt$exit(int);
bool m_shutdown { false };