Day 1
This commit is contained in:
18
stdlib/include/arena.h
Normal file
18
stdlib/include/arena.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <common.h>
|
||||
|
||||
typedef struct arena {
|
||||
void* ptr;
|
||||
usize available;
|
||||
usize capacity;
|
||||
} arena;
|
||||
|
||||
// The capacity has to be page-aligned
|
||||
arena arena_init(usize capacity);
|
||||
|
||||
// The available size will be rounded up to a page boundary
|
||||
// Will not grow beyond its capacity
|
||||
void arena_ensure(arena* arena, usize available);
|
||||
|
||||
#define ARENA_ENSURE(T, arena, available) arena_ensure(arena, (available) * sizeof(T))
|
6
stdlib/include/buffer.h
Normal file
6
stdlib/include/buffer.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <common.h>
|
||||
|
||||
// The size has to be page-aligned
|
||||
void* buffer_init(usize size);
|
27
stdlib/include/common.h
Normal file
27
stdlib/include/common.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
typedef char c8;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long u64;
|
||||
|
||||
typedef signed char i8;
|
||||
typedef signed short i16;
|
||||
typedef signed int i32;
|
||||
typedef signed long i64;
|
||||
|
||||
typedef unsigned long int usize;
|
||||
typedef signed long isize;
|
||||
|
||||
#define asm __asm__
|
||||
|
||||
#define null ((void*)0)
|
||||
#define bool _Bool
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
#define COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
#define PAGE_SIZE 4096UL
|
24
stdlib/include/syscall.h
Normal file
24
stdlib/include/syscall.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#define stdin 0
|
||||
#define stdout 1
|
||||
#define stderr 2
|
||||
|
||||
#define PROT_NONE 0x0
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define PROT_EXEC 0x4
|
||||
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANONYMOUS 0x20
|
||||
|
||||
isize read(i32 fd, void* buf, usize size);
|
||||
isize write(i32 fd, const void* buf, usize size);
|
||||
void* mmap(void* addr, usize length, i32 prot, i32 flags, i32 fd, isize offset);
|
||||
i32 mprotect(void* addr, usize len, i32 prot);
|
||||
i32 ftruncate(i32 fd, isize length);
|
||||
i32 memfd_create(const char* name, u32 flags);
|
22
stdlib/src/arena.c
Normal file
22
stdlib/src/arena.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <common.h>
|
||||
#include <arena.h>
|
||||
#include <syscall.h>
|
||||
|
||||
arena arena_init(usize capacity)
|
||||
{
|
||||
void* ptr = mmap(null, capacity, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
return (arena){ .ptr = ptr, .available = 0, .capacity = capacity };
|
||||
}
|
||||
|
||||
void arena_ensure(arena* arena, usize available)
|
||||
{
|
||||
if (arena->available >= available) return;
|
||||
|
||||
available = (available + PAGE_SIZE - 1) & -PAGE_SIZE;
|
||||
if (available > arena->capacity) {
|
||||
available = arena->capacity;
|
||||
}
|
||||
|
||||
mprotect((c8*)arena->ptr + arena->available, available - arena->available, PROT_READ | PROT_WRITE);
|
||||
arena->available = available;
|
||||
}
|
14
stdlib/src/buffer.c
Normal file
14
stdlib/src/buffer.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <common.h>
|
||||
#include <syscall.h>
|
||||
|
||||
void* buffer_init(usize size)
|
||||
{
|
||||
i32 fd = memfd_create("buffer", 0);
|
||||
ftruncate(fd, size);
|
||||
|
||||
void* ptr = mmap(null, 2 * size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
mmap( ptr, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
|
||||
mmap((c8*)ptr + size, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
|
||||
|
||||
return ptr;
|
||||
}
|
12
stdlib/src/start.s
Normal file
12
stdlib/src/start.s
Normal file
@@ -0,0 +1,12 @@
|
||||
.intel_syntax noprefix
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
xor rbp, rbp
|
||||
pop rdi
|
||||
mov rsi, rsp
|
||||
and rsp, -16
|
||||
call main
|
||||
mov rdi, rax
|
||||
mov rax, 60
|
||||
syscall
|
77
stdlib/src/syscall.c
Normal file
77
stdlib/src/syscall.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include <syscall.h>
|
||||
|
||||
isize read(i32 fd, void* buf, usize size)
|
||||
{
|
||||
isize ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (0), "D" (fd), "S" (buf), "d" (size)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
isize write(i32 fd, const void* buf, usize size)
|
||||
{
|
||||
isize ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (1), "D" (fd), "S" (buf), "d" (size)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* mmap(void* addr, usize length, i32 prot, i32 flags, i32 fd, isize offset)
|
||||
{
|
||||
register i32 r10 asm ("r10") = flags;
|
||||
register i32 r8 asm ("r8") = fd;
|
||||
register isize r9 asm ("r9") = offset;
|
||||
|
||||
void* ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (9), "D" (addr), "S" (length), "d" (prot), "r" (r10), "r" (r8), "r" (r9)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i32 mprotect(void* addr, usize len, i32 prot)
|
||||
{
|
||||
i32 ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (10), "D" (addr), "S" (len), "d" (prot)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i32 ftruncate(i32 fd, isize length)
|
||||
{
|
||||
i32 ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (77), "D" (fd), "S" (length)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i32 memfd_create(const char* name, u32 flags)
|
||||
{
|
||||
i32 ret;
|
||||
asm volatile (
|
||||
"syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (319), "D" (name), "S" (flags)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
Reference in New Issue
Block a user