Compare commits

..

17 Commits

68 changed files with 1133 additions and 650 deletions

View File

@ -1,3 +1,3 @@
%print "this is an init script!"
%print 'this is an init script!'
base:/bin/pctl ls
base:/bin/tb -m interactive -preload base:/scripts/rc.tb

View File

@ -54,8 +54,6 @@ SRCFILES += $(call GRABSRC, \
baseimg \
proc \
proc/kproc \
proc/ps2kbproc \
proc/termproc \
proc/serialproc \
hal \
hal/$(ARCH) \
@ -67,6 +65,7 @@ SRCFILES += $(call GRABSRC, \
rbuf \
ipc/pipe \
drivers/ps2kb \
dev \
)
ifeq ($(ARCH),x86_64)

View File

@ -11,7 +11,7 @@ CFLAGS += -m64 \
-mno-red-zone \
-fno-stack-protector \
-fno-stack-check \
-O0 \
-Os \
LDFLAGS += -m elf_x86_64 \
-pie \

View File

@ -3,6 +3,7 @@
#include <stdbool.h>
#include "bitmap.h"
#include "util/util.h"
#include "kprintf.h"
void *bitmap_toptr(BitMap *bm, size_t block) {
uint8_t *ptr = (uint8_t *)(bm->mem_start + (block * BITMAP_BLOCK_SIZE));
@ -104,13 +105,3 @@ void *bitmap_alloc(BitMap *bm, size_t blocks) {
void bitmap_free(BitMap *bm, void *base, size_t blocks) {
bitmap_markregion(bm, base, BITMAP_BLOCK_SIZE * blocks, 0);
}
size_t bitmap_allocpageframe(BitMap *bm) {
size_t pickedreg = bitmap_freeregion(bm, 1);
bitmap_markblocks(bm, pickedreg, 1, 1);
return (bm->mem_start + (pickedreg * BITMAP_BLOCK_SIZE));
}
void bitmap_freepageframe(BitMap *bm, void *addr) {
bitmap_markregion(bm, addr, BITMAP_BLOCK_SIZE * 1, 0);
}

View File

@ -31,7 +31,5 @@ void bitmap_markregion(BitMap *bm, void *baseptr, size_t size, bool is_used);
size_t bitmap_freeregion(BitMap *bm, size_t blocks);
void *bitmap_alloc(BitMap *bm, size_t blocks);
void bitmap_free(BitMap *bm, void *base, size_t blocks);
size_t bitmap_allocpageframe(BitMap *bm);
void bitmap_freepageframe(BitMap *bm, void *addr);
#endif // BITMAP_BITMAP_H_

14
kernel/dev/dev.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef DEV_DEV_H_
#define DEV_DEV_H_
#include <stdint.h>
#define DEV_FNS_MAX 32
typedef int32_t (*DevFn)(uint8_t *buffer, size_t len, void *extra);
typedef struct {
DevFn fns[DEV_FNS_MAX];
} Dev;
#endif // DEV_DEV_H_

35
kernel/dev/ps2kbdev.c Normal file
View File

@ -0,0 +1,35 @@
#include <stdint.h>
#include <stddef.h>
#include "kprintf.h"
#include "hal/hal.h"
#include "ps2kbdev.h"
#include "dev.h"
#include "errors.h"
#include "dlmalloc/malloc.h"
Dev PS2KBDEV;
Ps2KbFastBuf PS2KB_BUF;
int32_t ps2kbdev_readch(uint8_t *buffer, size_t len, void *extra) {
(void)buffer; (void)len; (void)extra;
uint8_t b = 0;
spinlock_acquire(&PS2KB_BUF.spinlock);
int32_t r = rbuf_pop(&PS2KB_BUF.rbuf, &b);
spinlock_release(&PS2KB_BUF.spinlock);
if (r == 0) {
return b;
} else {
return E_NOTYET;
}
}
void ps2kbdev_init(void) {
hal_memset(&PS2KBDEV, 0, sizeof(PS2KBDEV));
PS2KBDEV.fns[0] = &ps2kbdev_readch;
const int bufsz = 0x1000;
uint8_t *buf = dlmalloc(bufsz);
rbuf_init(&PS2KB_BUF.rbuf, buf, bufsz);
PS2KB_BUF.init = true;
}

22
kernel/dev/ps2kbdev.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef DEV_PS2KBDEV_H_
#define DEV_PS2KBDEV_H_
#include <stdint.h>
#include <stddef.h>
#include "dev.h"
#include "rbuf/rbuf.h"
#include "spinlock/spinlock.h"
typedef struct {
RBuf rbuf;
SpinLock spinlock;
bool init;
} Ps2KbFastBuf;
void ps2kbdev_init(void);
extern Dev PS2KBDEV;
extern Ps2KbFastBuf PS2KB_BUF;
#endif // DEV_PS2KBDEV_H_

19
kernel/dev/termdev.c Normal file
View File

@ -0,0 +1,19 @@
#include <stdint.h>
#include <stddef.h>
#include "kprintf.h"
#include "hal/hal.h"
#include "termdev.h"
#include "dev.h"
#include "errors.h"
Dev TERMDEV;
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra) {
kprintf("%.*s", (int)len, (char *)buffer);
return E_OK;
}
void termdev_init(void) {
hal_memset(&TERMDEV, 0, sizeof(TERMDEV));
TERMDEV.fns[0] = &termdev_putch;
}

13
kernel/dev/termdev.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef DEV_TERMDEV_H_
#define DEV_TERMDEV_H_
#include <stdint.h>
#include <stddef.h>
#include "dev.h"
int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra);
void termdev_init(void);
extern Dev TERMDEV;
#endif // DEV_TERMDEV_H_

View File

@ -49,7 +49,7 @@ int RELEASE_LOCK(SpinLock *sl) {
}
int INITIAL_LOCK(SpinLock *sl) {
spinlock_release(sl);
spinlock_init(sl);
return 0;
}

View File

@ -7,7 +7,7 @@
#define GDT_PRESENT 0x80
#define GDT_TSS 0x89
#define KSTACK 8192
#define KSTACK (1024*2*4096)
ALIGNED(16) static uint8_t kernelstack[KSTACK];
typedef struct {

View File

@ -14,8 +14,8 @@
#include "errors.h"
#include "drivers/ps2kb/ps2kb.h"
#include "ipc/pipe/pipe.h"
#include "proc/ps2kbproc/ps2kbproc.h"
#include "rbuf/rbuf.h"
#include "dev/ps2kbdev.h"
typedef struct BackTraceFrame {
struct BackTraceFrame *rbp;
@ -178,8 +178,6 @@ void hal_syscalldispatch(IntrStackFrame *frame) {
frame->regs.rax = E_BADSYSCALL;
return;
}
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));
int32_t ret = fn(frame, frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
frame->regs.r10, frame->regs.r8, frame->regs.r9);
@ -200,7 +198,7 @@ void intr_handleintr(IntrStackFrame *frame) {
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
intr_dumpframe(frame);
backtrace((BackTraceFrame *)frame->regs.rbp);
if (frame->errnum & 0x4) {
if (hal_vmm_current_cr3() != KERNEL_CR3) {
kprintf("killed pid %ld %s\n", PROCS.current->pid, PROCS.current->name);
proc_killself();
proc_sched((void *)frame);
@ -215,7 +213,7 @@ void intr_handleintr(IntrStackFrame *frame) {
break;
case INTR_IRQBASE+1:
int32_t c = ps2kb_intr();
if (c >= 0) {
if (c >= 0 && PS2KB_BUF.init) {
uint8_t b = c;
spinlock_acquire(&PS2KB_BUF.spinlock);
rbuf_push(&PS2KB_BUF.rbuf, b);

View File

@ -62,13 +62,13 @@
.endm
.macro _vecintr_bodygen
cli
_push_regs
cld
mov %rsp, %rdi
movq %rsp, %rdi
call intr_handleintr
_pop_regs
add $0x10, %rsp
iretq
.endm

View File

@ -2,15 +2,11 @@
.global hal_switchproc
hal_switchproc:
mov %cr3, %rcx
cmp %rsi, %rcx
je .done
mov %rsi, %cr3
.done:
testq %rsi, %rsi
je 1f
movq %rsi, %cr3
1:
mov %rdi, %rsp
_pop_regs
add $0x10, %rsp
iretq

View File

@ -29,12 +29,16 @@ PgIndex hal_vmm_pageindex(uint64_t vaddr) {
return ret;
}
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) {
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent, bool alloc) {
uint64_t entry = table[ent];
uint64_t phys;
if (entry & HAL_PG_PRESENT) {
phys = entry & ~0xFFFULL;
} else {
if (!alloc) {
return NULL;
}
uint8_t *newphys = pmm_alloc(1);
phys = (uint64_t)newphys;
hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
@ -47,9 +51,9 @@ void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, ui
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
PgIndex pi = hal_vmm_pageindex(virtaddr);
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4, true);
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3, true);
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2, true);
uint64_t *pte = &pml1[pi.pml1];
*pte = (physaddr & ~0xFFFULL) | ((uint64_t)flags & 0x7ULL);
@ -59,9 +63,9 @@ void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr)
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
PgIndex pi = hal_vmm_pageindex(virtaddr);
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4, false);
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3, false);
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2, false);
uint64_t *pte = &pml1[pi.pml1];
*pte &= ~HAL_PG_PRESENT;

View File

@ -30,10 +30,6 @@ typedef struct {
uint16_t pml3;
uint16_t pml2;
uint16_t pml1;
/* uint64_t pml4; */
/* uint64_t pml3; */
/* uint64_t pml2; */
/* uint64_t pml1; */
} PACKED PgIndex;
typedef struct {
@ -50,11 +46,6 @@ typedef struct {
uint64_t addr: 40;
uint16_t osdef: 11;
bool nx: 1;
/* bool zero0: 1; */
/* bool size: 1; */
/* bool zero1: 1; */
/* uint8_t avail: 3; */
/* uint64_t addr: 52; */
} PACKED Pte;
typedef struct {

View File

@ -11,6 +11,8 @@
#include "storedev/storedev.h"
#include "util/util.h"
#include "proc/proc.h"
#include "dev/termdev.h"
#include "dev/ps2kbdev.h"
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
@ -64,6 +66,8 @@ void kmain(void) {
storedev_init();
baseimg_init();
vfs_init();
termdev_init();
ps2kbdev_init();
proc_init();
for(;;);

View File

@ -40,6 +40,9 @@ void pmm_init(void) {
hal_memset(bm->map, 0xff, bm->nbytes);
for (size_t i = 0; i < BOOT_INFO.memmap_entrycount; i++) {
struct limine_memmap_entry *entry = BOOT_INFO.memmap_entries[i];
if (entry == memmap_ent) {
continue;
}
// mark usable as 0 and unusable as 1
bitmap_markregion(bm, (void *)entry->base, entry->length, entry->type != LIMINE_MEMMAP_USABLE);
}

View File

@ -14,8 +14,6 @@
#include "bootinfo/bootinfo.h"
#include "ipc/pipe/pipe.h"
#include "kproc/kproc.h"
#include "ps2kbproc/ps2kbproc.h"
#include "termproc/termproc.h"
#include "serialproc/serialproc.h"
#include "sysdefs/processctl.h"
@ -181,6 +179,7 @@ Proc *proc_spawnuser(char *mountpoint, char *path) {
proc->mman_map_base = PROC_MMAN_MAP_BASE;
spinlock_init(&proc->bcast_pipes.spinlock);
spinlock_init(&proc->pipes_spinlock);
spinlock_init(&proc->devs_spinlock);
proc->pipes[0] = dlmalloc(sizeof(IpcPipe));
ipc_pipeinit(proc->pipes[0], proc->pid);
@ -211,58 +210,50 @@ Proc *proc_nextready(void) {
void proc_reaper(void) {
spinlock_acquire(&PROCS.spinlock);
Proc *head = PROCS.procs;
while (head) {
if (head->state == PROC_ZOMBIE) {
Proc *zombie = head;
head = head->next;
LL_REMOVE(PROCS.procs, zombie);
for (size_t i = 0; i < zombie->vobjcnt; i++) {
if (zombie->vobjs[i] != NULL) {
vfs_close(zombie->vobjs[i]);
zombie->vobjs[i] = NULL;
}
}
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) {
dlfree(zombie->pipes[i]);
ipc_pipefree(zombie->pipes[i]);
zombie->pipes[i] = NULL;
}
}
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
pmm_free((uintptr_t)(zombie->platformdata.pstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
if (!zombie->kern) {
VasRange *vashead = zombie->vas;
size_t i = 0;
while (vashead) {
VasRange *tmp = vashead;
vashead = vashead->next;
hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size);
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
dlfree(tmp);
i++;
}
pmm_free((uintptr_t)zombie->platformdata.cr3, 1);
ProcArg *arg = zombie->procargs.list;
while (arg) {
dlfree(arg->string);
ProcArg *tmp = arg;
arg = arg->next;
dlfree(tmp);
}
}
dlfree(zombie);
} else {
head = head->next;
Proc *head, *tmp;
LL_FOREACH_SAFE(PROCS.procs, head, tmp) {
if (head->state != PROC_ZOMBIE) {
continue;
}
Proc *zombie = head;
LL_REMOVE(PROCS.procs, zombie);
for (size_t i = 0; i < zombie->vobjcnt; i++) {
if (zombie->vobjs[i] != NULL) {
vfs_close(zombie->vobjs[i]);
zombie->vobjs[i] = NULL;
}
}
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) {
dlfree(zombie->pipes[i]);
ipc_pipefree(zombie->pipes[i]);
zombie->pipes[i] = NULL;
}
}
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
pmm_free((uintptr_t)(zombie->platformdata.pstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
if (!zombie->kern) {
VasRange *vas, *vastmp;
LL_FOREACH_SAFE(zombie->vas, vas, vastmp) {
hal_vmm_unmap_range(zombie->platformdata.cr3, vas->virtstart, vas->physstart, vas->size);
pmm_free((uintptr_t)vas->physstart, vas->size / HAL_PAGE_SIZE);
dlfree(vas);
}
pmm_free((uintptr_t)zombie->platformdata.cr3, 1);
ProcArg *arg, *argtmp;
LL_FOREACH_SAFE(zombie->procargs.list, arg, argtmp) {
dlfree(arg->string);
dlfree(arg);
}
}
dlfree(zombie);
}
spinlock_release(&PROCS.spinlock);
}
@ -316,26 +307,8 @@ void proc_init(void) {
spinlock_init(&PROCS.spinlock);
PROCS.procs = NULL;
kproc_init(proc_spawnkern(&kproc_fn, "kproc"));
proc_register(KPROC);
PROCS.current = KPROC;
KPROC->state = PROC_READY;
ps2kbproc_init(proc_spawnkern(&ps2kbproc_fn, "ps2kbproc"));
proc_register(PS2KBPROC);
PS2KBPROC->state = PROC_READY;
termproc_init(proc_spawnkern(&termproc_fn, "termproc"));
proc_register(TERMPROC);
TERMPROC->state = PROC_READY;
/* serialproc_init(proc_spawnkern(&serialproc_fn, "serialproc")); */
/* proc_register(SERIALPROC); */
Proc *init = proc_spawnuser("base", "/bin/init");
ipc_pipefree(init->pipes[0]);
dlfree(init->pipes[0]);
init->pipes[0] = TERMPROC->pipes[1];
PROCS.current = init;
proc_register(init);
init->state = PROC_READY;

View File

@ -8,19 +8,21 @@
#include "vfs/vfs.h"
#include "ipc/pipe/pipe.h"
#include "sysdefs/processctl.h"
#include "dev/dev.h"
#define PROC_NAME_MAX 0x100
#define PROC_STACKBLOCKS (1024*4)
#define PROC_STACKBLOCKS (1024*2)
#define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE)
#define PROC_MAX 0x100 // max amount of processes
#define PROC_VFSHANDLES_MAX 0x80
#define PROC_PIPEHANDLES_MAX 0x20
#define PROC_DEVHANDLES_MAX 0x20
#define PROC_MMAN_MAP_BASE 0x700000000000
#define PROC_USER_STACK_TOP 0x800000000000
#define PROC_MMAN_MAP_BASE 0x0000100000000000ULL
#define PROC_USER_STACK_TOP 0x00007FFFFFFFF000ULL
typedef struct {
IntrStackFrame trapframe;
@ -56,12 +58,18 @@ typedef struct Proc {
VfsObj *vobjs[PROC_VFSHANDLES_MAX];
uint64_t vobjcnt;
IpcPipe *pipes[PROC_PIPEHANDLES_MAX];
SpinLock pipes_spinlock;
struct {
IpcPipe *list;
SpinLock spinlock;
} bcast_pipes;
Dev *devs[PROC_DEVHANDLES_MAX];
SpinLock devs_spinlock;
struct {
ProcArg *list;
size_t len;

View File

@ -1,38 +0,0 @@
#include <stdint.h>
#include "proc/proc.h"
#include "dlmalloc/malloc.h"
#include "ipc/pipe/pipe.h"
#include "kprintf.h"
#include "rbuf/rbuf.h"
#include "ps2kbproc.h"
Proc *PS2KBPROC = NULL;
Ps2KbFastBuf PS2KB_BUF;
void ps2kbproc_init(Proc *proc) {
PS2KBPROC = proc;
PS2KBPROC->bcast_pipes.list = NULL;
uint8_t *buf = dlmalloc(IPC_PIPE_MAX);
rbuf_init(&PS2KB_BUF.rbuf, buf, IPC_PIPE_MAX);
spinlock_init(&PS2KB_BUF.spinlock);
}
void ps2kbproc_fn(void) {
for (;;) {
uint8_t b = 0;
spinlock_acquire(&PS2KB_BUF.spinlock);
if (rbuf_pop(&PS2KB_BUF.rbuf, &b) == 0) {
spinlock_acquire(&PS2KBPROC->bcast_pipes.spinlock);
IpcPipe *head = PS2KBPROC->bcast_pipes.list;
while (head != NULL) {
ipc_pipewrite(head, &b, 1);
head = head->next;
}
spinlock_release(&PS2KBPROC->bcast_pipes.spinlock);
}
spinlock_release(&PS2KB_BUF.spinlock);
}
}

View File

@ -1,20 +0,0 @@
#ifndef PROC_PS2KB_PS2KBPROC_H_
#define PROC_PS2KB_PS2KBPROC_H_
#include <stdbool.h>
#include "proc/proc.h"
#include "rbuf/rbuf.h"
#include "spinlock/spinlock.h"
typedef struct {
RBuf rbuf;
SpinLock spinlock;
} Ps2KbFastBuf;
extern Proc *PS2KBPROC;
extern Ps2KbFastBuf PS2KB_BUF;
void ps2kbproc_fn(void);
void ps2kbproc_init(Proc *proc);
#endif // PROC_PS2KB_PS2KBPROC_H_

View File

@ -1,25 +0,0 @@
#include <stdint.h>
#include "proc/proc.h"
#include "ipc/pipe/pipe.h"
#include "kprintf.h"
#include "hal/hal.h"
#include "dlmalloc/malloc.h"
#include "spinlock/spinlock.h"
Proc *TERMPROC;
void termproc_init(Proc *proc) {
TERMPROC = proc;
TERMPROC->pipes[1] = dlmalloc(sizeof(IpcPipe));
ipc_pipeinit(TERMPROC->pipes[1], TERMPROC->pid);
}
void termproc_fn(void) {
for (;;) {
char c = 0;
int32_t read = ipc_piperead(TERMPROC->pipes[1], (uint8_t *)&c, 1);
if (read > 0) {
kprintf("%c", c);
}
}
}

View File

@ -1,11 +0,0 @@
#ifndef PROC_TERMPROC_TERMPROC_H_
#define PROC_TERMPROC_TERMPROC_H_
#include "proc/proc.h"
extern Proc *TERMPROC;
void termproc_init(Proc *proc);
void termproc_fn(void);
#endif // PROC_TERMPROC_TERMPROC_H_

View File

@ -5,25 +5,62 @@
#include "hal/hal.h"
#include "kprintf.h"
#define SPINLOCK_IRQ_DBG 1
#define SPINLOCK_HINT() asm volatile("pause")
struct {
atomic_uint64_t irq_flags;
atomic_int irq_nest;
} IRQ_CTX;
void spinlock_init(SpinLock *sl) {
atomic_store(&sl->lock, false);
sl->flags = 0;
}
uint64_t spinlock_irqsave(void) {
uint64_t irqsave(void) {
uint64_t flags;
asm volatile("pushfq; cli; popq %0" : "=r"(flags) :: "memory");
asm volatile("pushfq; cli; popq %0" : "=r"(flags) :: "memory", "cc");
return flags;
}
void spinlock_irqrestore(uint64_t flags) {
void irqrestore(uint64_t flags) {
if (flags & (1<<9)) {
asm volatile("sti" ::: "memory");
asm volatile("sti" ::: "memory", "cc");
}
}
void irqsave_nested(void) {
if (atomic_load(&IRQ_CTX.irq_nest) == 0) {
atomic_store(&IRQ_CTX.irq_flags, irqsave());
}
atomic_inc(&IRQ_CTX.irq_nest);
#if SPINLOCK_IRQ_DBG
if (atomic_load(&IRQ_CTX.irq_nest) < 0) {
kprintf("IRQ_CTX.irq_nest underflow\n");
hal_hang();
}
#endif
}
void irqrestore_nested(void) {
#if SPINLOCK_IRQ_DBG
int irq_nest = atomic_load(&IRQ_CTX.irq_nest);
if (irq_nest <= 0) {
kprintf("spinlock: irqs restored too many times: %d\n", irq_nest);
hal_hang();
}
#endif
atomic_dec(&IRQ_CTX.irq_nest);
if (atomic_load(&IRQ_CTX.irq_nest) == 0) {
irqrestore(atomic_load(&IRQ_CTX.irq_flags));
}
}
void spinlock_acquire(SpinLock *sl) {
sl->flags = spinlock_irqsave();
irqsave_nested();
while (atomic_test_and_set_explicit(&sl->lock, memory_order_acquire)) {
SPINLOCK_HINT();
@ -33,6 +70,6 @@ void spinlock_acquire(SpinLock *sl) {
void spinlock_release(SpinLock *sl) {
atomic_clear_flag_explicit(&sl->lock, memory_order_release);
spinlock_irqrestore(sl->flags);
irqrestore_nested();
}

View File

@ -6,11 +6,8 @@
typedef struct {
atomic_bool lock;
uint64_t flags;
} SpinLock;
#define SPINLOCK_HINT() asm volatile("pause")
void spinlock_init(SpinLock *sl);
void spinlock_acquire(SpinLock *sl);
void spinlock_release(SpinLock *sl);

68
kernel/syscall/devctl.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdint.h>
#include <stddef.h>
#include "kprintf.h"
#include "syscall.h"
#include "errors.h"
#include "spinlock/spinlock.h"
#include "proc/proc.h"
#include "sysdefs/devctl.h"
#include "dev/termdev.h"
#include "dev/ps2kbdev.h"
#include "util/util.h"
Dev *DEVS[] = {
[0x10] = &TERMDEV,
[0x11] = &PS2KBDEV,
};
int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1) {
uint64_t *devh = (uint64_t *)devh1;
uint64_t cmd = cmd1;
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
switch (cmd) {
case DEVCTL_GET_HANDLE: {
uint64_t devid = buffer1;
if (devid >= LEN(DEVS)) {
ret = E_INVALIDARGUMENT;
goto done;
}
bool found = false;
for (size_t i = 0; i < PROC_DEVHANDLES_MAX; i++) {
if (proc->devs[i] == NULL) {
found = true;
proc->devs[i] = DEVS[devid];
*devh = i;
break;
}
}
if (!found) {
ret = E_NOENTRY;
goto done;
}
} break;
default: {
if (devh == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (cmd >= DEV_FNS_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
Dev *dev = proc->devs[*devh];
ret = dev->fns[cmd]((uint8_t *)buffer1, (size_t)len1, (void *)extra1);
} break;
}
done:
return ret;
}

9
kernel/syscall/devctl.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef SYSCALL_DEVCTL_H_
#define SYSCALL_DEVCTL_H_
#include <stdint.h>
#include "syscall.h"
int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1);
#endif // SYSCALL_DEVCTL_H_

View File

@ -10,6 +10,7 @@
#include "sysdefs/mman.h"
#include "bootinfo/bootinfo.h"
#include "dlmalloc/malloc.h"
#include "kprintf.h"
int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
uint8_t *addr = (uint8_t *)addr1;
@ -27,9 +28,6 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
size_t pages = _DIV_ROUNDUP(size, HAL_PAGE_SIZE);
uint8_t *phys = (uint8_t *)pmm_alloc(pages);
if (phys == NULL) {
return E_NOMEMORY;
}
hal_memset(VIRT(phys), 0, pages * HAL_PAGE_SIZE);
spinlock_acquire(&PROCS.spinlock);
@ -86,13 +84,12 @@ int32_t SYSCALL1(sys_mman_unmap, addr1) {
uint8_t *virt = NULL;
VasRange *tofree = NULL;
VasRange *range = proc->vas;
while (range) {
if (range->virtstart == addr) {
tofree = range;
VasRange *vas, *vastmp;
LL_FOREACH_SAFE(proc->vas, vas, vastmp) {
if (vas->virtstart == addr) {
tofree = vas;
break;
}
range = range->next;
}
if (tofree == NULL) {

View File

@ -63,8 +63,10 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
size_t argslen = arg3;
char *(*args)[] = (char *(*)[])arg2;
for (size_t i = 0; i < argslen; i++) {
PROC_ARG(newproc, (*args)[i]);
if (args != NULL && argslen > 0) {
for (size_t i = 0; i < argslen; i++) {
PROC_ARG(newproc, (*args)[i]);
}
}
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
@ -91,36 +93,32 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
ret = proc->procargs.len;
} break;
case PCTL_ARGV: {
char **argbuf = (char **)arg1;
size_t *argslen = (size_t *)arg1;
char **argbuf = (char **)arg2;
if (argbuf == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t len = arg2;
ProcArg *arg = proc->procargs.list;
size_t i = 0;
while (arg) {
if (i == len) {
break;
}
size_t maxargs = (size_t)arg3;
ProcArg *arg, *argtmp;
size_t i;
LL_FOREACH_SAFE_IDX_LIMIT(proc->procargs.list, arg, argtmp, i, maxargs) {
if (argbuf[i] == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
hal_strcpy(argbuf[i], arg->string);
arg = arg->next;
i++;
}
*argslen = i;
ret = E_OK;
} break;
case PCTL_PLS_SZ: {
size_t i = 0;
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
Proc *p = PROCS.procs;
while (p) {
i++;
p = p->next;
}
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i);
spinlock_release(&PROCS.spinlock);
ret = i;
} break;
@ -133,26 +131,22 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
goto done;
}
size_t i = 0;
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
Proc *p = PROCS.procs;
while (p) {
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i) {
if (i == pidx) {
stat->pid = p->pid;
hal_strcpy(stat->name, p->name);
stat->state = p->state;
stat->kern = p->kern;
VasRange *range = p->vas;
while (range) {
stat->usemem += range->size;
range = range->next;
VasRange *vas, *vastmp;
LL_FOREACH_SAFE(p->vas, vas, vastmp) {
stat->usemem += vas->size;
}
break;
}
i++;
p = p->next;
}
spinlock_release(&PROCS.spinlock);
ret = E_OK;

View File

@ -11,7 +11,7 @@ int32_t SYSCALL0(sys_schedrelease) {
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
proc_sched((void *)frame);
/* proc_sched((void *)frame); */
return E_OK;
}

View File

@ -8,6 +8,7 @@
#include "ipcpipe.h"
#include "mman.h"
#include "sched.h"
#include "devctl.h"
int32_t SYSCALL1(sys_debugprint, string) {
char *p = (char *)string;
@ -23,4 +24,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
[SYS_MMAN_MAP] = &sys_mman_map,
[SYS_MMAN_UNMAP] = &sys_mman_unmap,
[SYS_SCHEDRELEASE] = &sys_schedrelease,
[SYS_DEVCTL] = &sys_devctl,
};

View File

@ -8,35 +8,45 @@
#define LL_APPEND(head, new) \
do { \
if ((head) != NULL) { \
typeof((head)) __tmp; \
(new)->next = NULL; \
__tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
if ((new) != NULL) { \
if ((head) != NULL) { \
typeof((head)) __tmp; \
(new)->next = NULL; \
__tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
__tmp->next = (new); \
} else { \
(new)->next = NULL; \
(head) = (new); \
} \
__tmp->next = (new); \
} else { \
(new)->next = NULL; \
(head) = (new); \
} \
} while(0)
#define LL_REMOVE(head, ele) \
do { \
typeof((head)) __cur = (head); \
typeof((head)) __prev = NULL; \
while (__cur != (ele)) { \
__prev = __cur; \
__cur = __cur->next; \
} \
if (__prev != NULL) { \
__prev->next = __cur->next; \
if ((head) != NULL && (ele) != NULL) { \
typeof((head)) __cur = (head); \
typeof((head)) __prev = NULL; \
while (__cur != NULL && __cur != (ele)) { \
__prev = __cur; \
__cur = __cur->next; \
} \
if (__cur == (ele)) { \
if (__prev != NULL) { \
__prev->next = __cur->next; \
} else { \
(head) = __cur->next; \
} \
(ele)->next = NULL; \
} \
} \
} while(0)
#define LL_FINDPROP(head, out, propname, propvalue) \
do { \
(out) = NULL; \
typeof((head)) __tmp = (head); \
while (__tmp) { \
if (__tmp->propname == (propvalue)) { \
@ -47,6 +57,22 @@
} \
} while(0)
#define LL_FOREACH_SAFE(head, var, tmp) \
for (var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL) \
)
#define LL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define LL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL && (idx) < (max); \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
char *util_get_filename(char *path);
#endif // UTIL_UTIL_H_

View File

@ -10,4 +10,7 @@ CFLAGS += -m64 \
-fno-stack-check \
-fno-builtin \
-fno-omit-frame-pointer \
-fno-strict-aliasing \
-O0 \
-mno-tls-direct-seg-refs \
# -fsanitize=undefined

View File

@ -16,6 +16,7 @@ enum {
E_INVALIDOPER = -11,
E_RESOURCEAVAIL = -12,
E_SPAWNERROR = -13,
E_NOTYET = -14,
};
static const char *_ERROR_STRINGS[] = {

10
share/sysdefs/devctl.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef SHARE_SYSDEFS_DEVCTL_H_
#define SHARE_SYSDEFS_DEVCTL_H_
enum {
DEVCTL_GET_HANDLE = 100,
};
typedef uint64_t Dev_t;
#endif // SHARE_SYSDEFS_DEVCTL_H_

View File

@ -1,7 +1,7 @@
#ifndef SHARE_HDRS_PROCESSCTL_H_
#define SHARE_HDRS_PROCESSCTL_H_
#define PROC_ARG_MAX 0x400
#define PROC_ARG_MAX 128
enum {
PCTL_KILL = 0,

View File

@ -9,6 +9,7 @@ enum {
SYS_MMAN_MAP = 5,
SYS_MMAN_UNMAP = 6,
SYS_SCHEDRELEASE = 7,
SYS_DEVCTL = 8,
};
#endif // SHARE_HDRS_SYSCALL_H_

View File

@ -11,14 +11,14 @@
#define atomic_load_explicit __atomic_load_n
#define atomic_store_explicit __atomic_store_n
#define atomic_store(p, v) atomic_store_explicit(p, v, memory_order_relaxed)
#define atomic_load(p) atomic_load_explicit(p, memory_order_relaxed)
#define atomic_store(p, v) atomic_store_explicit(p, v, memory_order_seq_cst)
#define atomic_load(p) atomic_load_explicit(p, memory_order_seq_cst)
#define atomic_compare_exchange_weak(p, old, new) \
__atomic_compare_exchange_n(p, old, new, true, memory_order_relaxed, memory_order_relaxed)
__atomic_compare_exchange_n(p, old, new, true, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_compare_exchange_strong(p, old, new) \
__atomic_compare_exchange_n(p, old, new, false, memory_order_relaxed, memory_order_relaxed)
__atomic_compare_exchange_n(p, old, new, false, memory_order_seq_cst, memory_order_seq_cst)
#define atomic_test_and_set_explicit(p, memory_order) \
__atomic_test_and_set(p, memory_order)
@ -26,6 +26,28 @@
#define atomic_clear_flag_explicit(p, memory_order) \
__atomic_clear(p, memory_order)
#define atomic_inc_explicit(p, memory_order) \
__atomic_fetch_add(p, 1, memory_order)
#define atomic_inc(p) \
atomic_inc_explicit(p, memory_order_seq_cst)
#define atomic_dec_explicit(p, memory_order) \
__atomic_fetch_sub(p, 1, memory_order)
#define atomic_dec(p) \
atomic_dec_explicit(p, memory_order_seq_cst)
#define atomic_bool _Atomic(bool)
#define atomic_int _Atomic(int)
#define atomic_uint _Atomic(unsigned int)
#define atomic_int8_t _Atomic(int8_t)
#define atomic_uint8_t _Atomic(uint8_t)
#define atomic_int16_t _Atomic(int16_t)
#define atomic_uint16_t _Atomic(uint16_t)
#define atomic_int32_t _Atomic(int32_t)
#define atomic_uint32_t _Atomic(uint32_t)
#define atomic_int64_t _Atomic(int64_t)
#define atomic_uint64_t _Atomic(uint64_t)
#endif

View File

@ -10,10 +10,11 @@ SRCFILES := $(call GRABSRC, \
string \
system \
printf \
dlmalloc \
sync \
args \
util \
ubsan \
umalloc \
)
CFLAGS += -isystem $(ROOT)/share -isystem $(ROOT)/ulib -isystem $(ROOT)/std/include \

View File

@ -2,10 +2,13 @@
#include <stddef.h>
#include <system/system.h>
#include <sysdefs/processctl.h>
#include <sysdefs/devctl.h>
#include <errors.h>
#include <dlmalloc/malloc.h>
#include <uprintf.h>
#include <log.h>
#include <util/util.h>
#include <umalloc/umalloc.h>
#include <devids.h>
extern void main(void);
extern uint8_t _bss_start[];
@ -18,7 +21,9 @@ void clearbss(void) {
}
}
char **_args;
#define MAX_ARGS 15
static char *_args[MAX_ARGS];
size_t _argslen;
char **args(void) {
@ -29,23 +34,19 @@ size_t argslen(void) {
return _argslen;
}
Dev_t termdev;
// ulib initialization goes here
void _premain(void) {
clearbss();
_argslen = processctl(-1, PCTL_ARGLEN, 0, 0, 0);
_args = dlmalloc(_argslen * sizeof(*_args));
if (_args == NULL) {
return;
}
for (size_t i = 0; i < _argslen; i++) {
_args[i] = dlmalloc(PROC_ARG_MAX);
if (_args[i] == NULL) {
return;
}
devctl(&termdev, DEVCTL_GET_HANDLE, (uint8_t *)DEV_TERMDEV, 0, 0);
for (size_t i = 0; i < ARRLEN(_args); i++) {
_args[i] = umalloc(PROC_ARG_MAX);
}
processctl(-1, PCTL_ARGV, (uint64_t)_args, _argslen, 0);
processctl(-1, PCTL_ARGV, (uint64_t)&_argslen, (uint64_t)_args, MAX_ARGS);
main();
}

View File

@ -5,35 +5,89 @@
#include <string/conv.h>
#include <string/string.h>
#include <uprintf.h>
#include <errors.h>
int32_t parse_args(char **argv, size_t argc, Arg *defs) {
#define CONSUME_TK() i++
if (!argv || !defs) {
return E_INVALIDARGUMENT;
}
for (size_t i = 0; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] != '\0') {
char *optname = argv[i];
char *arg = argv[i];
if (!arg) {
continue;
}
if (arg[0] == '-' && arg[1] != '\0') {
size_t j = 0;
while (!defs[j].end) {
Arg *def = &defs[j];
if (string_strcmp(def->shortname, optname) == 0) {
if (i < argc - 1) {
switch (def->expected_value) {
case ARG_STRING:
*((char **)def->ptr) = argv[i+1];
break;
case ARG_BOOL:
*((bool *)def->ptr) = string_strcmp(argv[i+1], "yes") == 0;
break;
case ARG_INT: {
char *end;
*((int32_t *)def->ptr) = string_conv_strtol(argv[i+1], &end, 10);
} break;
}
i++;
}
if (!def->shortname || !def->ptr) {
j++;
continue;
}
if (string_strcmp(def->shortname, arg) == 0) {
bool have_next = (i + 1) < argc && argv[i + 1] != NULL;
char *nexttk = have_next ? argv[i + 1] : NULL;
if (nexttk && nexttk[0] == '-' && nexttk[1] != '\0') {
have_next = false;
nexttk = NULL;
}
switch (def->expected_value) {
case ARG_STRING:
if (!have_next) {
break;
}
*((char **)def->ptr) = nexttk;
CONSUME_TK();
break;
case ARG_BOOL:
if (!have_next) {
*((bool *)def->ptr) = true;
} else {
if (string_strcmp(nexttk, "yes") == 0) {
*((bool *)def->ptr) = true;
CONSUME_TK();
} else if (string_strcmp(nexttk, "no") == 0) {
*((bool *)def->ptr) = false;
CONSUME_TK();
} else {
*((bool *)def->ptr) = true;
}
}
break;
case ARG_INT:
if (!have_next) {
break;
}
char *endptr = NULL;
long val = string_conv_strtol(nexttk, &endptr, 10);
if (endptr == NULL) {
break;
}
if (*endptr != '\0') {
break;
}
*((int32_t *)def->ptr) = (int32_t)val;
CONSUME_TK();
break;
default:
break;
}
break;
}
j++;
}
}
}
return ARGP_OK;
return E_OK;
}

View File

@ -28,10 +28,6 @@ typedef struct {
#define ARG_END() ((Arg){ .end = true, })
enum {
ARGP_OK = 0,
};
int32_t parse_args(char **argv, size_t argc, Arg *defs);
#endif // ULIB_ARGS_H_

15
ulib/assert.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef ULIB_ASSERT_H_
#define ULIB_ASSERT_H_
#include <util/util.h>
#include <uprintf.h>
#define ASSERT(X, fmt, ...) \
do { \
if (!(X)) { \
uprintf("ASSERT %s:%d in %s "fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
quit(); \
} \
} while(0)
#endif // ULIB_ASSERT_H_

9
ulib/devids.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef ULIB_DEVIDS_H_
#define ULIB_DEVIDS_H_
enum {
DEV_TERMDEV = 0x10,
DEV_PS2KBDEV = 0x11,
};
#endif // ULIB_DEVIDS_H_

View File

@ -1,82 +0,0 @@
// Config
#include <stddef.h>
#include <dlmalloc/malloc.h>
#include <uprintf.h>
#include <errors.h>
#include <sync/spinlock.h>
#include <string/string.h>
#include <sysdefs/mman.h>
#include <system/system.h>
#define USE_DL_PREFIX 1
#define LACKS_SYS_TYPES_H 1
#define NO_MALLOC_STATS 1
#define LACKS_ERRNO_H 1
#define LACKS_TIME_H 1
#define LACKS_STDLIB_H 1
#define LACKS_SYS_MMAN_H 1
#define LACKS_FCNTL_H 1
#define LACKS_UNISTD_H 1
#define LACKS_SYS_PARAM_H 1
#define LACKS_STRINGS_H 1
#define LACKS_SCHED_H 1
#define HAVE_MMAP 0
#define MORECORE_CONTIGUOUS 0
#define ABORT \
do { \
uprintf("dlmalloc: Aborting...\n"); \
} while(0)
#define MALLOC_FAILURE_ACTION
#define HAVE_MORECORE 1
#define USE_LOCKS 2
#define malloc_getpagesize 0x1000
#define EINVAL E_INVALIDARGUMENT
#define ENOMEM E_NOMEMORY
#define MLOCK_T SpinLock
int ACQUIRE_LOCK(SpinLock *sl) {
spinlock_acquire(sl);
return 0;
}
int RELEASE_LOCK(SpinLock *sl) {
spinlock_release(sl);
return 0;
}
int INITIAL_LOCK(SpinLock *sl) {
spinlock_init(sl);
return 0;
}
static MLOCK_T malloc_global_mutex = { 0 };
#define PAGE_SIZE 0x1000
static size_t _roundpage(size_t sz) {
return (sz + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
}
void *_last = 0;
void *sbrk(ptrdiff_t inc) {
if (inc < 0) {
return 0;
}
if (!inc) {
return _last;
}
uint64_t pages = _roundpage(inc);
uint8_t *maddr = NULL;
int32_t ret = mman_map(NULL, pages, MMAN_MAP_PF_RW, 0, &maddr);
if (ret != E_OK) {
return 0;
}
string_memset(maddr, 0, pages);
_last = (void *)(maddr + inc);
return maddr;
}

View File

@ -1 +0,0 @@
../../dlmalloc/malloc.c

View File

@ -1 +0,0 @@
../../dlmalloc/malloc.h

View File

@ -3,35 +3,45 @@
#define LL_APPEND(head, new) \
do { \
if ((head) != NULL) { \
typeof((head)) __tmp; \
(new)->next = NULL; \
__tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
if ((new) != NULL) { \
if ((head) != NULL) { \
typeof((head)) __tmp; \
(new)->next = NULL; \
__tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
__tmp->next = (new); \
} else { \
(new)->next = NULL; \
(head) = (new); \
} \
__tmp->next = (new); \
} else { \
(new)->next = NULL; \
(head) = (new); \
} \
} while(0)
#define LL_REMOVE(head, ele) \
do { \
typeof((head)) __cur = (head); \
typeof((head)) __prev = NULL; \
while (__cur != (ele)) { \
__prev = __cur; \
__cur = __cur->next; \
} \
if (__prev != NULL) { \
__prev->next = __cur->next; \
if ((head) != NULL && (ele) != NULL) { \
typeof((head)) __cur = (head); \
typeof((head)) __prev = NULL; \
while (__cur != NULL && __cur != (ele)) { \
__prev = __cur; \
__cur = __cur->next; \
} \
if (__cur == (ele)) { \
if (__prev != NULL) { \
__prev->next = __cur->next; \
} else { \
(head) = __cur->next; \
} \
(ele)->next = NULL; \
} \
} \
} while(0)
#define LL_FINDPROP(head, out, propname, propvalue) \
do { \
(out) = NULL; \
typeof((head)) __tmp = (head); \
while (__tmp) { \
if (__tmp->propname == (propvalue)) { \
@ -42,4 +52,20 @@
} \
} while(0)
#define LL_FOREACH_SAFE(head, var, tmp) \
for (var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL) \
)
#define LL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define LL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL && (idx) < (max); \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#endif // ULIB_LINKLIST_H_

View File

@ -1,9 +1,11 @@
#include <stdint.h>
#include <system/system.h>
#include <sysdefs/ipcpipe.h>
#include <sysdefs/devctl.h>
#include <printf/printf.h>
extern Dev_t termdev;
void putchar_(char c) {
char buf = c;
ipcpipe(IPCPIPE_SELFPID, IPCPIPE_OUT, IPCPIPE_WRITE, (uint8_t *)&buf, sizeof(buf));
devctl(&termdev, 0x00, (uint8_t *)&c, 1, 0);
}

View File

@ -1,5 +1,6 @@
#include <stddef.h>
#include <string/string.h>
#include <umalloc/umalloc.h>
size_t string_len(const char *s) {
size_t l = 0;
@ -130,3 +131,44 @@ int string_strncmp( const char * s1, const char * s2, size_t n )
return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
}
}
#define STRING_TOKENIZEALLOC_TOK_SIZE 0xff
char *string_tokenizealloc(char *s, char *delim) {
static char *saved = NULL;
if (s) {
saved = s;
}
if (!delim || !saved) {
return NULL;
}
while (*saved && string_strchr(delim, *saved)) {
saved++;
}
if (!*saved) {
return NULL;
}
char *w = (char *)umalloc(sizeof(char) * STRING_TOKENIZEALLOC_TOK_SIZE);
string_memset(w, 0, sizeof(char) * STRING_TOKENIZEALLOC_TOK_SIZE);
int k = 0;
while (*saved && !string_strchr(delim, *saved)) {
if (k >= STRING_TOKENIZEALLOC_TOK_SIZE - 1) {
break;
}
w[k++] = *saved++;
}
w[k] = '\0';
if (*saved) {
saved++;
}
return w;
}

View File

@ -16,6 +16,7 @@ size_t string_strspn(const char *s, const char *accept);
char *string_strcpy(char *dest, const char *src);
char *string_strchr(const char *s, int c);
int string_strncmp(const char * s1, const char * s2, size_t n);
char *string_tokenizealloc(char *s, char *delim);
#endif

View File

@ -1,27 +1,18 @@
#include <stdint.h>
#include <uprintf.h>
uint64_t syscall(uint64_t num, uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6) {
uint64_t ret = 0;
asm volatile (
"mov %[SYSNUM], %%rax\n"
"mov %[ARG1], %%rdi\n"
"mov %[ARG2], %%rsi\n"
"mov %[ARG3], %%rdx\n"
"mov %[ARG4], %%r10\n"
"mov %[ARG5], %%r8\n"
"mov %[ARG6], %%r9\n"
uint64_t ret;
asm volatile(
"mov %[a4], %%r10\n"
"mov %[a5], %%r8\n"
"mov %[a6], %%r9\n"
"int $0x80\n"
"mov %%rax, %[RESULT]\n"
: [RESULT]"=r"(ret)
: [SYSNUM]"r"(num),
[ARG1]"r"(arg1),
[ARG2]"r"(arg2),
[ARG3]"r"(arg3),
[ARG4]"r"(arg4),
[ARG5]"r"(arg5),
[ARG6]"r"(arg6)
: "rax", "rdi", "rsi", "rdx", "r10", "r8", "r9", "memory"
: "=a"(ret)
: "a"(num), "D"(arg1), "S"(arg2), "d"(arg3),
[a4]"r"(arg4), [a5]"r"(arg5), [a6]"r"(arg6)
: "r10", "r8", "r9", "memory", "cc"
);
return ret;
}

View File

@ -5,6 +5,7 @@
#include <sysdefs/ioctl.h>
#include <sysdefs/processctl.h>
#include <sysdefs/ipcpipe.h>
#include <sysdefs/devctl.h>
#include <uprintf.h>
void debugprint(const char *string) {
@ -34,3 +35,7 @@ int32_t mman_unmap(uint8_t *addr) {
int32_t schedrelease(void) {
return syscall(SYS_SCHEDRELEASE, 0, 0, 0, 0, 0, 0);
}
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra) {
return syscall(SYS_DEVCTL, (uint64_t)devh, cmd, (uint64_t)buffer, (uint64_t)len, (uint64_t)extra, 0);
}

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include <stddef.h>
#include <sysdefs/devctl.h>
void debugprint(const char *string);
int32_t ioctl(uint64_t ioh, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3);
@ -11,5 +12,6 @@ int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, s
int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out);
int32_t mman_unmap(uint8_t *addr);
int32_t schedrelease(void);
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra);
#endif // ULIB_SYSTEM_SYSTEM_H_

224
ulib/ubsan/ubsan.c Normal file
View File

@ -0,0 +1,224 @@
// REFERENCES:
// https://wiki.osdev.org/Undefined_Behavior_Sanitization
#include <stdint.h>
#include <stddef.h>
#include <uprintf.h>
struct source_location {
const char *file;
uint32_t line;
uint32_t column;
};
struct type_descriptor {
uint16_t type_kind;
uint16_t type_info;
char *type_name;
};
struct type_mismatch_data {
struct source_location loc;
struct type_descriptor *type;
unsigned long alignment;
unsigned char type_check_kind;
};
struct type_mismatch_data_v1 {
struct source_location loc;
struct type_descriptor *type;
unsigned char alignment;
unsigned char type_check_kind;
};
struct overflow_data {
struct source_location loc;
struct type_descriptor *type;
};
struct shift_out_of_bounds_data {
struct source_location loc;
struct type_descriptor *lhs_type;
struct type_descriptor *rhs_type;
};
struct out_of_bounds_data {
struct source_location loc;
struct type_descriptor *array_type;
struct type_descriptor *index_type;
};
struct unreachable_data {
struct source_location loc;
};
struct vla_bound_data {
struct source_location loc;
struct type_descriptor *type;
};
struct invalid_value_data {
struct source_location loc;
struct type_descriptor *type;
};
struct nonnull_arg_data {
struct source_location loc;
};
struct nonnull_return_data {
struct source_location loc;
struct source_location attr_loc;
};
struct invalid_builtin_data {
struct source_location loc;
uint8_t kind;
};
struct pointer_overflow_data {
struct source_location loc;
};
static void ubsan_print(struct source_location *loc, const char *message)
{
uprintf("UBSAN error %s:%d:%d %s\n", loc->file, loc->line, loc->column, message);
}
void __ubsan_handle_add_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "addition overflow");
}
void __ubsan_handle_sub_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "subtraction overflow");
}
void __ubsan_handle_mul_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "multiplication overflow");
}
void __ubsan_handle_divrem_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "division overflow");
}
void __ubsan_handle_negate_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "negation overflow");
}
void __ubsan_handle_pointer_overflow(struct overflow_data *data)
{
ubsan_print(&data->loc, "pointer overflow");
}
void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data)
{
ubsan_print(&data->loc, "shift out of bounds");
}
void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data)
{
ubsan_print(&data->loc, "array out of bounds");
}
void __ubsan_handle_load_invalid_value(struct invalid_value_data *data)
{
ubsan_print(&data->loc, "invalid load value");
}
void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, uintptr_t ptr)
{
if (ptr == (uintptr_t)NULL) {
ubsan_print(&data->loc, "null pointer access");
}
else if ((data->alignment != 0) && ((ptr & (((uintptr_t)1 << data->alignment) - (uintptr_t)1)) != 0)) {
ubsan_print(&data->loc, "misaligned pointer is used");
}
else {
ubsan_print(&data->loc, "insufficient space for an object");
}
}
void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data, uintptr_t ptr)
{
if (ptr == (uintptr_t)NULL) {
ubsan_print(&data->loc, "null pointer access");
}
else if ((data->alignment != 0) && ((ptr & (((uintptr_t)1 << data->alignment) - (uintptr_t)1)) != 0)) {
ubsan_print(&data->loc, "misaligned pointer is used");
}
else {
ubsan_print(&data->loc, "insufficient space for an object");
}
}
void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data)
{
ubsan_print(&data->loc, "variable-length argument out of bounds");
}
void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
{
ubsan_print(&data->loc, "null pointer returned from a function 'nonnull' specified");
}
void __ubsan_handle_nonnull_return_v1(struct nonnull_return_data *data, struct source_location *loc)
{
ubsan_print(&data->loc, "null pointer returned from a function 'nonnull' specified");
}
void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
{
ubsan_print(&data->loc, "non-null argument is null");
}
void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
{
ubsan_print(&data->loc, "unreachable code reached");
}
void __ubsan_handle_invalid_builtin(struct invalid_builtin_data *data)
{
ubsan_print(&data->loc, "invalid builtin");
}
void __ubsan_handle_missing_return(struct unreachable_data *data)
{
ubsan_print(&data->loc, "missing return value");
}

View File

@ -3,7 +3,6 @@
#include <ansiq/all.h>
#include <args/args.h>
#include <dlmalloc/malloc.h>
#include <string/string.h>
#include <string/char.h>
#include <sync/spinlock.h>
@ -13,6 +12,9 @@
#include <uprintf.h>
#include <linklist.h>
#include <log.h>
#include <assert.h>
#include <umalloc/umalloc.h>
#include <devids.h>
#include <errors.h>
#include <sysdefs/ioctl.h>

120
ulib/umalloc/umalloc.c Normal file
View File

@ -0,0 +1,120 @@
#include <stdint.h>
#include <stddef.h>
#include <umalloc/umalloc.h>
#include <sysdefs/mman.h>
#include <system/system.h>
#include <errors.h>
#include <linklist.h>
#include <string/string.h>
#include <util/util.h>
#include <assert.h>
#define ARENA_SIZE (1<<20)
#define BLOCK_MAGIC 0xDEADBEEF
typedef struct UmArena {
struct UmArena *next;
uintptr_t mem;
uintptr_t base;
size_t cursor;
int64_t balance;
} __attribute__((aligned(16))) UmArena;
typedef struct {
uint32_t magic;
size_t size;
uint8_t data[];
} __attribute__((aligned(16))) UmBlock;
static UmArena *ARENAS = NULL;
UmArena *um_newarena(void) {
size_t arenasize = ARENA_SIZE;
uint8_t *mem = NULL;
int32_t err = mman_map(NULL, arenasize, MMAN_MAP_PF_RW, 0, &mem);
if (mem == NULL || err != E_OK) {
return NULL;
}
UmArena *arena = (UmArena *)mem;
arena->base = (uintptr_t)mem;
arena->mem = ((uintptr_t)mem + sizeof(UmArena) + 15) & ~0xF;
arena->cursor = 0;
arena->balance = 0;
LL_APPEND(ARENAS, arena);
return arena;
}
void *umalloc(size_t size) {
UmArena *usable = NULL;
size = (size + 15) & ~(size_t)0xF;
UmArena *arena, *arenatmp;
LL_FOREACH_SAFE(ARENAS, arena, arenatmp) {
if (arena->cursor + sizeof(UmBlock) + size <= ARENA_SIZE - ((uintptr_t)arena->mem - arena->base)) {
usable = arena;
break;
}
}
if (usable == NULL) {
usable = um_newarena();
}
if (usable == NULL) {
return NULL;
}
uintptr_t addr = usable->mem + usable->cursor;
UmBlock *block = (UmBlock *)addr;
block->size = size;
block->magic = BLOCK_MAGIC;
usable->cursor += sizeof(UmBlock) + size;
usable->balance += size;
string_memset(block->data, 0, size);
return block->data;
}
void ufree(void *ptr_) {
if (ptr_ == NULL) {
return;
}
uintptr_t ptr = (uintptr_t)ptr_;
UmArena *freeable = NULL;
size_t size = 0;
UmArena *arena, *arenatmp;
LL_FOREACH_SAFE(ARENAS, arena, arenatmp) {
if (ptr >= arena->mem && ptr < arena->mem + arena->cursor) {
UmBlock *block = (UmBlock *)(ptr - sizeof(UmBlock));
if (((uintptr_t)block->data != ptr)
|| (block->magic != BLOCK_MAGIC)
|| (block->size == 0)
|| (block->size > ARENA_SIZE)) {
return;
}
string_memset(block->data, 0xDD, block->size);
block->magic = 0;
arena->balance -= block->size;
ASSERT(arena->balance >= 0, "umalloc: imbalance after free\n");
if (arena->balance == 0) {
LL_REMOVE(ARENAS, arena);
mman_unmap((void *)arena->base);
}
return;
}
}
}

10
ulib/umalloc/umalloc.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef ULIB_UMALLOC_UMALLOC_H_
#define ULIB_UMALLOC_UMALLOC_H_
#include <stdint.h>
#include <stddef.h>
void *umalloc(size_t size);
void ufree(void *ptr_);
#endif // ULIB_UMALLOC_UMALLOC_H_

View File

@ -5,11 +5,21 @@
#define ARRLEN(X) (sizeof((X))/sizeof((X)[0]))
#define ZERO(X) \
#define ZERO(X) string_memset((X), 0, sizeof(*(X)))
#define MIN(a, b) \
({ \
string_memset((X), 0, sizeof(*(X))); \
*(X); \
}) \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
(_a < _b ? _a : _b); \
})
#define MAX(a, b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
(_a > _b ? _a : _b); \
})
void quit(void);

View File

@ -22,6 +22,7 @@ SECTIONS {
{
_bss_start = .;
*(.bss .bss*)
. = ALIGN(4K);
_bss_end = .;
}
}

View File

@ -2,22 +2,26 @@
#include <ulib.h>
uint64_t PID;
Dev_t ps2kbdev;
void tb_runinitscript(void) {
char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb", "-logcmds", "yes" };
int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)&tbargs, ARRLEN(tbargs));
ipcpipe(tb, IPCPIPE_IN, IPCPIPE_ADD_BCAST, NULL, 1);
processctl(tb, PCTL_RUN, 0, 0, 0);
while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 4) {
schedrelease();
int32_t r = devctl(&ps2kbdev, 0x00, NULL, 0, 0);
if (r != E_NOTYET) {
uint8_t b = r;
ipcpipe(tb, IPCPIPE_IN, IPCPIPE_WRITE, &b, 1);
}
}
}
void main(void) {
PID = (uint64_t)processctl(-1, PCTL_GETPID, 0, 0, 0);
devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)DEV_PS2KBDEV, 0, 0);
tb_runinitscript();
@ -25,4 +29,3 @@ void main(void) {
for(;;);
}

View File

@ -61,12 +61,12 @@ void pctl_ls(void) {
uint64_t procslen = processctl(-1, PCTL_PLS_SZ, 0, 0, 0);
char *namebuf = dlmalloc(34);
char *membuf = dlmalloc(20);
char *namebuf = umalloc(34);
char *membuf = umalloc(20);
uprintf("%-30s %s %-6s %-15s %-8s\n", "NAME", "PID", "TYPE", "MEMORY", "STATE");
for (size_t i = 0; i < procslen; i++) {
ProcStat stat = ZERO(&stat);
ProcStat stat; ZERO(&stat);
string_memset(namebuf, 0, 34);
string_memset(membuf, 0, 20);

View File

@ -9,184 +9,110 @@ extern uint64_t PID;
static InterpResult RES;
void tz_init(Tokenizer *tz, const char *str, size_t len) {
void tz_init(Tokenizer *tz, char *str) {
tz->str = str;
tz->len = len;
tz->pos = 0;
tz->tokens = NULL;
}
void tz_free(Tokenizer *tz) {
Token *tk = tz->tokens;
while (tk) {
Token *tmp = tk;
tk = tk->next;
dlfree(tmp);
Token *tk, *tktmp;
LL_FOREACH_SAFE(tz->tokens, tk, tktmp) {
ufree(tk->str);
ufree(tk);
}
tz->tokens = NULL;
}
int tz_next(Tokenizer *tz, Token *out) {
while (tz->pos < tz->len && string_chr_isspace(tz->str[tz->pos])) {
tz->pos++;
}
#define TZ_MAX_TK 1024
if (tz->pos >= tz->len) {
return 0;
}
size_t start = tz->pos;
if (tz->str[start] == '"') {
start++;
tz->pos++;
while (tz->pos < tz->len && tz->str[tz->pos] != '"') {
tz->pos++;
}
if (tz->pos >= tz->len) {
out->ptr = tz->str + start;
out->len = tz->len - start;
tz->pos = tz->len;
void tz_tokenize(Tokenizer *tz) {
size_t len = string_len(tz->str);
for (size_t i = 0; i < len; i++) {
if (tz->str[i] == '\'') {
char *str = umalloc(TZ_MAX_TK);
string_memset(str, 0, TZ_MAX_TK);
i++;
size_t j = 0;
while (i < len && tz->str[i] != '\'') {
str[j++] = tz->str[i++];
}
Token *tk = umalloc(sizeof(*tk));
tk->str = str;
tk->next = NULL;
LL_APPEND(tz->tokens, tk);
} else {
out->ptr = tz->str + start;
out->len = tz->pos - start;
tz->pos++;
char *tkstr = umalloc(TZ_MAX_TK);
string_memset(tkstr, 0, TZ_MAX_TK);
size_t j = 0;
while (i < len && !string_chr_isspace(tz->str[i])) {
tkstr[j++] = tz->str[i++];
}
Token *tk = umalloc(sizeof(*tk));
tk->str = tkstr;
tk->next = NULL;
LL_APPEND(tz->tokens, tk);
}
} else {
while (tz->pos < tz->len && !string_chr_isspace(tz->str[tz->pos])) {
tz->pos++;
}
out->ptr = tz->str + start;
out->len = tz->pos - start;
}
return 1;
}
void tz_classify(Tokenizer *tz) {
const int tmpbufsz = 256;
char *tmpbuf = dlmalloc(tmpbufsz);
Token *tk = tz->tokens;
while (tk) {
if (tk->ptr[0] == '"' && tk->ptr[tk->len - 1] == '"') {
Token *tk, *tktmp;
LL_FOREACH_SAFE(tz->tokens, tk, tktmp) {
if (tk->str[0] == '"') {
tk->type = TOK_STRING;
} else if (tk->ptr[0] == '%') {
RtCmd *cmd = RTCMDS;
while (cmd) {
string_memset(tmpbuf, 0, tmpbufsz);
usnprintf(tmpbuf, tmpbufsz, "%.*s", (int)tk->len, tk->ptr);
if (string_strcmp(tmpbuf, cmd->cmdname) == 0) {
} else if (tk->str[0] == '%') {
RtCmd *cmd, *cmdtmp;
LL_FOREACH_SAFE(RTCMDS, cmd, cmdtmp) {
if (string_strcmp(tk->str, cmd->cmdname) == 0) {
tk->type = TOK_CMD;
tk->cmd = cmd;
break;
}
cmd = cmd->next;
}
} else {
tk->type = TOK_MISC;
}
tk = tk->next;
}
dlfree(tmpbuf);
}
void tz_expandspecial(Tokenizer *tz) {
Token *tk = tz->tokens;
while (tk) {
if (tk->ptr[0] == '$' && tk->len > 1) {
char *aliasbuf = dlmalloc(RTALIAS_NAMEBUF_MAX);
usnprintf(aliasbuf, RTALIAS_NAMEBUF_MAX, "%.*s", (int)tk->len-1, &tk->ptr[1]);
RtAlias *alias = RTALIASES;
while (alias) {
if (string_strcmp(alias->namebuf, aliasbuf) == 0) {
tk->ptr = alias->valbuf;
tk->len = string_len(alias->valbuf);
Token *tk, *tktmp;
LL_FOREACH_SAFE(tz->tokens, tk, tktmp) {
if (tk->str[0] == '$' && string_len(tk->str) > 1) {
RtAlias *alias, *aliastmp;
LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) {
if (string_strcmp(alias->namebuf, tk->str+1) == 0) {
ufree(tk->str);
size_t len = string_len(alias->valbuf)+1;
tk->str = umalloc(len);
string_memset(tk->str, 0, len);
string_memcpy(tk->str, alias->valbuf, string_len(alias->valbuf));
break;
}
alias = alias->next;
}
dlfree(aliasbuf);
}
tk = tk->next;
}
}
bool interp_readline(char *data, const char **bgptr, const char **endptr) {
static char *nextstart;
if (data) {
nextstart = data;
return true;
}
#define LINE_MAX 1024
if (*nextstart == '\0') {
return false;
}
*bgptr = nextstart;
const char *scn = nextstart;
for (;;) {
while (*scn != '\0' && *scn != '\n') {
scn++;
}
if (*scn == '\n') {
if (scn > *bgptr && *(scn - 1) == '\\') {
scn--;
nextstart = scn;
*nextstart = ' ';
scn++;
if (*scn == '\n') {
scn++;
}
nextstart = scn;
continue;
}
}
break;
}
*endptr = scn - 1;
while (string_chr_isspace(**bgptr) && *bgptr < *endptr) {
(*bgptr)++;
}
while (string_chr_isspace(**endptr) && *endptr >= *bgptr) {
(*endptr)--;
}
(*endptr)++;
if (*scn == '\n') {
scn++;
}
nextstart = scn;
return true;
}
bool interp_runstring(const char *string, InterpResult **res, bool logcmds, bool interactive) {
bool interp_runstring(char *string, InterpResult **res, bool logcmds, bool interactive) {
*res = &RES;
string_memset(RES.errmsg, 0, sizeof(RES.errmsg));
rt_init();
bool ok = true;
const char *bg, *end;
interp_readline((char *)string, NULL, NULL);
while (interp_readline(NULL, &bg, &end)) {
size_t linelen = end - bg;
char *line = string_tokenizealloc(string, "\n");
while (line != NULL) {
if (logcmds) {
uprintf("+ %.*s\n", (int)linelen, bg);
uprintf("+%s\n", line);
}
Tokenizer tz = {0};
tz_init(&tz, bg, linelen);
Tokenizer tz; ZERO(&tz);
tz_init(&tz, line);
Token toktmp = {0};
while (tz_next(&tz, &toktmp)) {
Token *tok = dlmalloc(sizeof(*tok));
tok->ptr = toktmp.ptr;
tok->len = toktmp.len;
LL_APPEND(tz.tokens, tok);
}
tz_tokenize(&tz);
tz_classify(&tz);
tz_expandspecial(&tz);
@ -195,36 +121,25 @@ bool interp_runstring(const char *string, InterpResult **res, bool logcmds, bool
if (cmdtk->type == TOK_CMD) {
ok = cmdtk->cmd->fn(cmdtk->next);
if (!ok) {
ok = false;
usprintf(RES.errmsg, "cmd %.*s failed", (int)cmdtk->len, cmdtk->ptr);
tz_free(&tz);
goto done;
usprintf(RES.errmsg, "cmd %s failed", cmdtk->str);
goto next;
}
} else if (cmdtk->type == TOK_MISC) {
char *appname = dlmalloc(1024);
usprintf(appname, "%.*s", (int)cmdtk->len, cmdtk->ptr);
size_t argslen1;
Token *argtk, *argtktmp;
LL_FOREACH_SAFE_IDX(cmdtk->next, argtk, argtktmp, argslen1);
size_t argslen1 = 0;
Token *argtk = cmdtk->next;
while (argtk) {
argslen1++;
argtk = argtk->next;
}
char **args1 = (char **)dlmalloc(sizeof(char *) * argslen1);
argtk = cmdtk->next;
size_t i = 0;
while (argtk) {
args1[i] = (char *)dlmalloc(PROC_ARG_MAX);
size_t i;
char **args1 = (char **)umalloc(sizeof(char *) * argslen1);
LL_FOREACH_SAFE_IDX(cmdtk->next, argtk, argtktmp, i) {
args1[i] = (char *)umalloc(PROC_ARG_MAX);
string_memset(args1[i], 0, PROC_ARG_MAX);
string_memcpy(args1[i], argtk->ptr, argtk->len);
i++;
argtk = argtk->next;
string_memcpy(args1[i], argtk->str, MIN(string_len(argtk->str), PROC_ARG_MAX));
}
int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)appname, (uint64_t)args1, argslen1);
int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)cmdtk->str, (uint64_t)args1, argslen1);
if (app < 0) {
usprintf(RES.errmsg, "Could not run %s: %s\n", appname, ERRSTRING(app));
usprintf(RES.errmsg, "Could not run %s: %s\n", cmdtk->str, ERRSTRING(app));
ok = false;
goto cleanup;
}
@ -244,16 +159,17 @@ bool interp_runstring(const char *string, InterpResult **res, bool logcmds, bool
}
cleanup: {
for (size_t j = 0; j < argslen1; j++) {
dlfree(args1[j]);
}
dlfree(args1);
dlfree(appname);
for (size_t j = 0; j < argslen1; j++) ufree(args1[j]);
ufree(args1);
}
}
next:
tz_free(&tz);
ufree(line);
line = string_tokenizealloc(NULL, "\n");
}
done:
return ok;
}

View File

@ -13,8 +13,7 @@ typedef struct {
typedef struct Token {
struct Token *next;
const char *ptr;
size_t len;
char *str;
enum {
TOK_STRING,
@ -26,13 +25,10 @@ typedef struct Token {
} Token;
typedef struct {
const char *str;
size_t len;
size_t pos;
char *str;
Token *tokens;
} Tokenizer;
bool interp_runstring(const char *string, InterpResult **res, bool logcmds, bool interactive);
bool interp_runstring(char *string, InterpResult **res, bool logcmds, bool interactive);
#endif // TB_INTERP_H_

View File

@ -57,14 +57,14 @@ void do_file(char *filepath) {
return;
}
IoctlStat statbuf = {0};
IoctlStat statbuf; ZERO(&statbuf);
ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, 0, 0);
if (statbuf.type != IOCTLSTAT_FILE) {
LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type);
return;
}
uint8_t *buf = dlmalloc(statbuf.size+1);
uint8_t *buf = umalloc(statbuf.size+1);
string_memset(buf, 0, statbuf.size+1);
if ((ret = ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0)) < 0) {
@ -73,7 +73,7 @@ void do_file(char *filepath) {
}
InterpResult *res;
bool ok = interp_runstring((const char *)buf, &res, CONFIG.logcmds, CONFIG.mode == MODE_INTERACTIVE);
bool ok = interp_runstring((char *)buf, &res, CONFIG.logcmds, CONFIG.mode == MODE_INTERACTIVE);
if (!ok) {
uprintf("Interpreter error:\n");
uprintf("%s\n", res->errmsg);
@ -81,7 +81,7 @@ void do_file(char *filepath) {
}
done:
dlfree(buf);
ufree(buf);
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
}

View File

@ -9,39 +9,38 @@ RtAlias *RTALIASES = NULL;
#define RTCMD(name, _fn) \
do { \
RtCmd *_cmd = dlmalloc(sizeof(*_cmd)); \
RtCmd *_cmd = umalloc(sizeof(*_cmd)); \
_cmd->cmdname = (name); \
_cmd->fn = (_fn); \
LL_APPEND(RTCMDS, _cmd); \
} while(0)
bool rt_print(Token *tks) {
Token *tk = tks;
while (tk) {
uprintf("%.*s", (int)tk->len, tk->ptr);
Token *tk, *tktmp;
LL_FOREACH_SAFE(tks, tk, tktmp) {
uprintf("%s", tk->str);
if (tk->next != NULL) {
uprintf(" ");
}
tk = tk->next;
}
uprintf("\n");
return true;
}
bool rt_mkalias(Token *tks) {
RtAlias *alias = dlmalloc(sizeof(*alias));
RtAlias *alias = umalloc(sizeof(*alias));
string_memset(alias, 0, sizeof(*alias));
Token *tk = tks;
size_t i = 0;
while (tk) {
size_t i;
Token *tk, *tktmp;
LL_FOREACH_SAFE_IDX(tks, tk, tktmp, i) {
if (i == 0) {
usprintf(alias->namebuf, "%.*s", (int)tk->len, tk->ptr);
string_memcpy(alias->namebuf, tk->str, MIN(string_len(tk->str), RTALIAS_NAMEBUF_MAX));
} else if (i == 1) {
usprintf(alias->valbuf, "%.*s", (int)tk->len, tk->ptr);
string_memcpy(alias->valbuf, tk->str, MIN(string_len(tk->str), RTALIAS_VALBUF_MAX));
}
i++;
tk = tk->next;
}
LL_APPEND(RTALIASES, alias);
return true;
}