kernel+libc: Copy argv to userspace
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-03-18 22:25:19 +01:00
parent 0b00dc3fe4
commit a4ac3c85ed
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 53 additions and 24 deletions

View File

@ -1,24 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysmacros.h>
#include <unistd.h>
int main()
int main(int argc, char** argv)
{
printf("Hello world!\n");
mkdir("/dev", 0755);
if (mknod("/dev/console", 0666, makedev(1, 0)) < 0)
{
perror("mknod");
return 1;
}
const char* str = "Hello from /dev!";
FILE* f = fopen("/dev/console", "r+");
if (f) fwrite(str, 1, strlen(str), f);
if (f) fclose(f);
printf("Hello world! argc=%d, argv[0]=%s, argv[1]=%s, argv[2]=%s\n", argc, argv[0], argv[1], argv[2]);
}

View File

@ -30,14 +30,26 @@ static Result<Vector<OwnedStringView>> copy_string_vector_from_userspace(u64 add
return result;
}
static Result<u64> copy_string_vector_to_userspace(const Vector<OwnedStringView>& vec, ThreadImage& image)
{
Vector<u64> user_vec;
for (const auto& item : vec)
{
// Copy each individual string and retrieve a userspace pointer to said copy
u64 addr = TRY(image.push_mem_on_stack((const u8*)item.chars(), item.length() + 1));
TRY(user_vec.try_append(addr));
}
TRY(user_vec.try_append((u64) nullptr));
// Copy the actual vector of userspace pointers to the stack
return TRY(image.push_mem_on_stack((u8*)user_vec.data(), user_vec.size() * sizeof(u64)));
}
Result<u64> sys_exec(Registers* regs, SyscallArgs args)
{
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
auto argv = TRY(copy_string_vector_from_userspace(args[1]));
kdbgln("exec: printing out argv (argc = %zu)", argv.size());
for (const auto& arg : argv) { kdbgln("* %s", arg.chars()); }
// FIXME: Make sure argv is not too big.
auto inode = TRY(VFS::resolve_path(path.chars()));
@ -49,12 +61,21 @@ Result<u64> sys_exec(Registers* regs, SyscallArgs args)
auto current = Scheduler::current();
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->directory); });
auto image = TRY(ThreadImage::try_load_from_elf(inode));
kdbgln("exec: copying argv to image memory (argc = %zu)", argv.size());
u64 user_argv = TRY(copy_string_vector_to_userspace(argv, *image));
usize user_argc = argv.size();
// From now on, nothing should fail.
kinfoln("exec: image load ok, will now replace existing process image");
guard.deactivate();
// FIXME: Close O_CLOEXEC file descriptors.
// for (int i = 0; i < FD_MAX; i++) { current->fd_table[i] = {}; }
@ -64,6 +85,8 @@ Result<u64> sys_exec(Registers* regs, SyscallArgs args)
MMU::switch_page_directory(current->directory);
current->set_arguments(user_argc, user_argv, 0, 0);
memcpy(regs, &current->regs, sizeof(*regs));
kinfoln("exec: done");

View File

@ -1,6 +1,7 @@
#include "thread/ThreadImage.h"
#include "memory/MemoryManager.h"
#include "thread/Thread.h"
#include <luna/CString.h>
static Result<void> create_stacks(Stack& user_stack, Stack& kernel_stack)
{
@ -50,10 +51,24 @@ Result<OwnedPtr<ThreadImage>> ThreadImage::try_load_from_elf(SharedPtr<VFS::Inod
image->m_user_stack = user_stack;
image->m_loaded_image_data = data;
image->m_vm_allocator = move(vm_allocator);
image->m_sp = user_stack.top();
return image;
}
Result<u64> ThreadImage::push_mem_on_stack(const u8* mem, usize size)
{
if ((m_sp - size) < m_user_stack.bottom()) return err(E2BIG);
if (!MemoryManager::validate_user_write((void*)(m_sp - size), size)) return err(EFAULT);
m_sp -= size;
memcpy((void*)m_sp, mem, size);
return m_sp;
}
void ThreadImage::apply(Thread* thread)
{
thread->init_regs_user();
@ -62,7 +77,7 @@ void ThreadImage::apply(Thread* thread)
thread->kernel_stack = m_kernel_stack;
thread->stack = m_user_stack;
thread->set_sp(m_user_stack.top());
thread->set_sp(m_sp);
thread->directory = m_directory;

View File

@ -17,6 +17,8 @@ class ThreadImage
public:
static Result<OwnedPtr<ThreadImage>> try_load_from_elf(SharedPtr<VFS::Inode> inode);
Result<u64> push_mem_on_stack(const u8* mem, usize size);
void apply(Thread* thread);
private:
@ -25,4 +27,5 @@ class ThreadImage
Stack m_user_stack;
Stack m_kernel_stack;
ELFData m_loaded_image_data;
u64 m_sp;
};

View File

@ -10,11 +10,17 @@ _start:
pushq %rbp # rbp=0
movq %rsp, %rbp
pushq %rsi
pushq %rdi
call libc_init
# Run the global constructors.
call _init
popq %rdi
popq %rsi
# Run main
call main