From 09aa85cf875db1e6fd1317cd2b9947b9d3675d6c Mon Sep 17 00:00:00 2001 From: Minep Date: Wed, 4 Jan 2023 16:35:48 +0000 Subject: [PATCH] feat: closedir(2) regression: execve fix: wrong signature for printf fix: sys_readdir context misuse fix: page fault handler: offset calculation for memory-mapped file fix: (merged) interrupt reworks in favour of execve. fix: mmap: gap fitting --- lunaix-os/includes/lunaix/dirent.h | 19 -------------- lunaix-os/kernel/asm/x86/interrupt.S | 10 ++++++++ lunaix-os/kernel/asm/x86/pfault.c | 8 +++--- lunaix-os/kernel/loader/exec.c | 9 ++++--- lunaix-os/kernel/mm/mmap.c | 6 ++--- lunaix-os/kernel/mm/region.c | 2 +- lunaix-os/makefile.prog | 2 +- lunaix-os/makefile.usr | 2 +- lunaix-os/uprog/init.c | 2 +- lunaix-os/uprog/ls.c | 2 ++ lunaix-os/usr/api/dirent.c | 2 +- lunaix-os/usr/includes/dirent.h | 7 ++++-- lunaix-os/usr/includes/stdio.h | 5 +--- lunaix-os/usr/includes/string.h | 3 +++ lunaix-os/usr/libc/printf.c | 2 +- lunaix-os/usr/libc/readdir.c | 37 ++++++++++++++++++++-------- 16 files changed, 67 insertions(+), 51 deletions(-) delete mode 100644 lunaix-os/includes/lunaix/dirent.h diff --git a/lunaix-os/includes/lunaix/dirent.h b/lunaix-os/includes/lunaix/dirent.h deleted file mode 100644 index 160365d..0000000 --- a/lunaix-os/includes/lunaix/dirent.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __LUNAIX_DIRENT_H -#define __LUNAIX_DIRENT_H - -#define DIRENT_NAME_MAX_LEN 256 - -#define DT_FILE 0x0 -#define DT_DIR 0x1 -#define DT_SYMLINK 0x2 -#define DT_PIPE 0x2 - -struct dirent -{ - unsigned int d_type; - unsigned int d_offset; - unsigned int d_nlen; - char d_name[DIRENT_NAME_MAX_LEN]; -}; - -#endif /* __LUNAIX_DIRENT_H */ diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index c869db0..23df5b5 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -19,6 +19,16 @@ .skip 128 tmp_stack: +/* + This perhaps the ugliest part in the project. + It contains code to handle arbitrary depth of + nested interrupt and all those corner cases and + nasty gotchas. + + Be aware the twists, offsets and hidden dependencies! + +*/ + .section .text .global interrupt_wrapper interrupt_wrapper: diff --git a/lunaix-os/kernel/asm/x86/pfault.c b/lunaix-os/kernel/asm/x86/pfault.c index 2b0a8f1..610c1cb 100644 --- a/lunaix-os/kernel/asm/x86/pfault.c +++ b/lunaix-os/kernel/asm/x86/pfault.c @@ -79,6 +79,7 @@ intr_routine_page_fault(const isr_param* param) } *pte = *pte | pa | PG_PRESENT; + memset(PG_ALIGN(ptr), 0, PG_SIZE); goto resolved; } // permission denied on anon page (e.g., write on readonly page) @@ -88,8 +89,10 @@ intr_routine_page_fault(const isr_param* param) // if mfile is set (Non-anonymous), then it is a mem map if (hit_region->mfile && !PG_IS_PRESENT(*pte)) { struct v_file* file = hit_region->mfile; - u32_t offset = - ((ptr - hit_region->start) & (PG_SIZE - 1)) + hit_region->foff; + + ptr = PG_ALIGN(ptr); + + u32_t offset = (ptr - hit_region->start) + hit_region->foff; uintptr_t pa = pmm_alloc_page(__current->pid, 0); if (!pa) { @@ -99,7 +102,6 @@ intr_routine_page_fault(const isr_param* param) cpu_invplg(pte); *pte = (*pte & 0xFFF) | pa | PG_PRESENT; - ptr = PG_ALIGN(ptr); memset(ptr, 0, PG_SIZE); int errno = 0; diff --git a/lunaix-os/kernel/loader/exec.c b/lunaix-os/kernel/loader/exec.c index cf0a422..0105753 100644 --- a/lunaix-os/kernel/loader/exec.c +++ b/lunaix-os/kernel/loader/exec.c @@ -47,7 +47,7 @@ __exec_remap_heap(struct ld_param* param, struct proc_mm* pvms) struct mmap_param map_param = { .pvms = pvms, .vms_mnt = param->vms_mnt, - .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED, + .flags = MAP_ANON | MAP_PRIVATE, .type = REGION_TYPE_HEAP, .proct = PROT_READ | PROT_WRITE, .mlen = DEFAULT_HEAP_PAGES * PG_SIZE }; @@ -181,11 +181,12 @@ __DEFINE_LXSYSCALL3(int, schedule(); fail("should not reach"); } + goto done; } - isr_param* intr_ctx = &__current->intr_ctx; - intr_ctx->esp = ldparam.info.stack_top; - intr_ctx->eip = ldparam.info.entry; + volatile struct exec_param* execp = __current->intr_ctx.execp; + execp->esp = ldparam.info.stack_top; + execp->eip = ldparam.info.entry; // we will jump to new entry point (_u_start) upon syscall's // return so execve 'will not return' from the perspective of it's invoker diff --git a/lunaix-os/kernel/mm/mmap.c b/lunaix-os/kernel/mm/mmap.c index da1a0b6..3a8677d 100644 --- a/lunaix-os/kernel/mm/mmap.c +++ b/lunaix-os/kernel/mm/mmap.c @@ -67,13 +67,13 @@ mem_map(void** addr_out, { if (last_end < found_loc) { size_t avail_space = pos->start - found_loc; - if ((int)avail_space > 0 && avail_space > param->mlen) { + if (pos->start > found_loc && avail_space > param->mlen) { goto found; } found_loc = pos->end + PG_SIZE; } - last_end = pos->end + PG_SIZE; + last_end = pos->end; } return ENOMEM; @@ -213,7 +213,7 @@ mem_unmap(ptr_t mnt, vm_regions_t* regions, void* addr, size_t length) } } - while (&pos->head != regions && cur_addr > pos->start) { + while (&pos->head != regions && cur_addr >= pos->start) { u32_t l = pos->end - cur_addr; pos->end = cur_addr; diff --git a/lunaix-os/kernel/mm/region.c b/lunaix-os/kernel/mm/region.c index f883edb..6340cfb 100644 --- a/lunaix-os/kernel/mm/region.c +++ b/lunaix-os/kernel/mm/region.c @@ -46,7 +46,7 @@ region_add(vm_regions_t* lead, struct mm_region* vmregion) cur_end = n->end; pos = n; n = list_entry(n->head.next, struct mm_region, head); - } while ((ptr_t)&pos->head != (ptr_t)lead); + } while ((ptr_t)&n->head != (ptr_t)lead); // XXX caution. require mm_region::head to be the lead of struct llist_insert_after(&pos->head, &vmregion->head); diff --git a/lunaix-os/makefile.prog b/lunaix-os/makefile.prog index 1c09c78..2c8b8e7 100644 --- a/lunaix-os/makefile.prog +++ b/lunaix-os/makefile.prog @@ -7,6 +7,6 @@ PROGRAMES := $(patsubst uprog/%.c, $(USR_DIR)/%, $(SRC_FILES)) $(USR_DIR)/%: @echo " BUILD $(*F)" - @$(CC) -T usr/link-usr.ld $(INCLUDES) $(CFLAGS) $(LDFLAGS) uprog/$(*F).c $(BIN_DIR)/$(USR_LIB) -o $@ + @$(CC) -T usr/link-usr.ld $(INCLUDES) $(CFLAGS) -g $(LDFLAGS) uprog/$(*F).c $(BIN_DIR)/$(USR_LIB) -o $@ all: $(PROGRAMES) \ No newline at end of file diff --git a/lunaix-os/makefile.usr b/lunaix-os/makefile.usr index d71ad71..7cbec35 100644 --- a/lunaix-os/makefile.usr +++ b/lunaix-os/makefile.usr @@ -16,7 +16,7 @@ $(OBJECT_DIR)/%.S.o: %.S $(OBJECT_DIR)/%.c.o: %.c @mkdir -p $(@D) @echo " CC $<" - @$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS) + @$(CC) $(INCLUDES) $(CFLAGS) -g -c $< -o $@ $(BIN_DIR)/$(USR_LIB): $(OBJS) @echo " AR $@" diff --git a/lunaix-os/uprog/init.c b/lunaix-os/uprog/init.c index c0c3fdd..dd083ad 100644 --- a/lunaix-os/uprog/init.c +++ b/lunaix-os/uprog/init.c @@ -18,7 +18,7 @@ main(int argc, const char** argv) return 0; } - printf("(%p) user space!\n", main); + printf("(%p) user space!\n", (void*)main); pid_t pid; if (!(pid = fork())) { diff --git a/lunaix-os/uprog/ls.c b/lunaix-os/uprog/ls.c index 605723c..accc7f7 100644 --- a/lunaix-os/uprog/ls.c +++ b/lunaix-os/uprog/ls.c @@ -26,5 +26,7 @@ main(int argc, const char* argv[]) } } + closedir(dir); + return 0; } \ No newline at end of file diff --git a/lunaix-os/usr/api/dirent.c b/lunaix-os/usr/api/dirent.c index 10d9213..e309582 100644 --- a/lunaix-os/usr/api/dirent.c +++ b/lunaix-os/usr/api/dirent.c @@ -1,4 +1,4 @@ #include -#include +#include __LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent) diff --git a/lunaix-os/usr/includes/dirent.h b/lunaix-os/usr/includes/dirent.h index 30ed892..78d57e3 100644 --- a/lunaix-os/usr/includes/dirent.h +++ b/lunaix-os/usr/includes/dirent.h @@ -6,7 +6,7 @@ typedef struct { int dirfd; - int prev_res; + struct lx_dirent _lxd; } DIR; struct dirent @@ -16,7 +16,10 @@ struct dirent }; DIR* -opendir(const char* dir); +opendir(const char* dirp); + +int +closedir(DIR* dirp); struct dirent* readdir(DIR* dir); diff --git a/lunaix-os/usr/includes/stdio.h b/lunaix-os/usr/includes/stdio.h index f898bed..0ef2e14 100644 --- a/lunaix-os/usr/includes/stdio.h +++ b/lunaix-os/usr/includes/stdio.h @@ -4,10 +4,7 @@ #define stdout 0 #define stdin 1 -void +int printf(const char* fmt, ...); -const char* -strchr(const char* str, int character); - #endif /* __LUNAIX_USTDIO_H */ diff --git a/lunaix-os/usr/includes/string.h b/lunaix-os/usr/includes/string.h index a309924..4c45ce2 100644 --- a/lunaix-os/usr/includes/string.h +++ b/lunaix-os/usr/includes/string.h @@ -12,4 +12,7 @@ strnlen(const char* str, size_t max_len); char* strncpy(char* dest, const char* src, size_t n); +const char* +strchr(const char* str, int character); + #endif /* __LUNAIX_STRING_H */ diff --git a/lunaix-os/usr/libc/printf.c b/lunaix-os/usr/libc/printf.c index 2557117..3268a3f 100644 --- a/lunaix-os/usr/libc/printf.c +++ b/lunaix-os/usr/libc/printf.c @@ -2,7 +2,7 @@ #include #include -void +int printf(const char* fmt, ...) { char buf[1024]; diff --git a/lunaix-os/usr/libc/readdir.c b/lunaix-os/usr/libc/readdir.c index 9d2b23e..f8285b8 100644 --- a/lunaix-os/usr/libc/readdir.c +++ b/lunaix-os/usr/libc/readdir.c @@ -2,6 +2,7 @@ #include #include #include +#include DIR* opendir(const char* dir) @@ -12,10 +13,28 @@ opendir(const char* dir) return NULL; } - _dir = (DIR){ .dirfd = fd, .prev_res = 0 }; + _dir = (DIR){ .dirfd = fd }; return &_dir; } +int +closedir(DIR* dirp) +{ + if (!dirp || dirp->dirfd == -1) { + // TODO migrate the status.h + return -1; + } + + int err = close(dirp->dirfd); + + if (!err) { + dirp->dirfd = -1; + return 0; + } + + return -1; +} + struct dirent* readdir(DIR* dir) { @@ -24,18 +43,16 @@ readdir(DIR* dir) return NULL; } - struct lx_dirent _lxd; - int more = sys_readdir(dir->dirfd, &_lxd); + struct lx_dirent* _lxd = &dir->_lxd; + + int more = sys_readdir(dir->dirfd, _lxd); - _dirent.d_type = _lxd.d_type; - strncpy(_dirent.d_name, _lxd.d_name, 256); + _dirent.d_type = _lxd->d_type; + strncpy(_dirent.d_name, _lxd->d_name, 256); - if (more || dir->prev_res) { - dir->prev_res = more; + if (more) { return &_dirent; } - if (!dir->prev_res) { - return NULL; - } + return NULL; } \ No newline at end of file -- 2.27.0