From b632f535c4a6882bdca0317fb88cbe6e165f24eb Mon Sep 17 00:00:00 2001 From: Minep Date: Wed, 23 Aug 2023 17:32:15 +0100 Subject: [PATCH] add lunaix dynamic linker as submodule fix: elf32 should load the PT_LOAD segments only fix: vmap does not respect the passed mapping attribute flags fix: mmap does not take account of flen fix: makefile does not recompiled on changed source file. fix: incorrect modulo operation on PG_SIZE fix: unwanted infinite loop elimination reported in #16 --- .gitmodules | 3 ++ lunaix-os/includes/lunaix/exebi/elf32.h | 6 +++- lunaix-os/includes/lunaix/mm/page.h | 2 +- lunaix-os/includes/lunaix/spike.h | 9 +++-- lunaix-os/kernel.mk | 12 ++++--- lunaix-os/kernel/debug/trace.c | 6 ++-- lunaix-os/kernel/exe/elf32/elf32bfmt.c | 15 ++++++--- lunaix-os/kernel/exe/elf32/ldelf32.c | 44 +++++++++++++++---------- lunaix-os/kernel/mm/mmap.c | 1 + lunaix-os/kernel/mm/vmap.c | 2 +- lunaix-os/makefile | 10 +++--- lunaix-os/usr/ld | 1 + 12 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 .gitmodules create mode 160000 lunaix-os/usr/ld diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8431bd9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lunaix-os/usr/ld"] + path = lunaix-os/usr/ld + url = git@github.com:Minep/lunaix-ld.git diff --git a/lunaix-os/includes/lunaix/exebi/elf32.h b/lunaix-os/includes/lunaix/exebi/elf32.h index 634ccd6..33da3a5 100644 --- a/lunaix-os/includes/lunaix/exebi/elf32.h +++ b/lunaix-os/includes/lunaix/exebi/elf32.h @@ -11,6 +11,7 @@ typedef unsigned int elf32_wrd_t; #define ET_NONE 0 #define ET_EXEC 2 +#define ET_DYN 3 #define PT_LOAD 1 #define PT_INTERP 3 @@ -78,7 +79,10 @@ struct elf32 struct elf32 elf = { .elf_file = elf_vfile, .pheaders = (void*)0 } int -elf32_check_exec(const struct elf32* elf); +elf32_check_exec(const struct elf32* elf, int type); + +int +elf32_check_arch(const struct elf32* elf); int elf32_open(struct elf32* elf, const char* path); diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index 38dcf71..7b8ba22 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -13,7 +13,7 @@ #define PTE_NULL 0 #define PG_ALIGN(addr) ((ptr_t)(addr)&0xFFFFF000UL) -#define PG_MOD(addr) ((ptr_t)(addr) & ~PG_SIZE) +#define PG_MOD(addr) ((ptr_t)(addr) & (PG_SIZE - 1)) #define PG_ALIGNED(addr) (!((ptr_t)(addr)&0x00000FFFUL)) #define PN(addr) (((ptr_t)(addr) >> 12)) diff --git a/lunaix-os/includes/lunaix/spike.h b/lunaix-os/includes/lunaix/spike.h index ae19357..356e4b3 100644 --- a/lunaix-os/includes/lunaix/spike.h +++ b/lunaix-os/includes/lunaix/spike.h @@ -65,10 +65,13 @@ : (31 - __builtin_clz(x))) #define DO_SPIN \ - while (1) \ - ; + { \ + volatile int __infloop = 1; \ + while (__infloop) \ + ; \ + } -inline static void +inline static void noret spin() { DO_SPIN diff --git a/lunaix-os/kernel.mk b/lunaix-os/kernel.mk index ba15fa3..5d64514 100644 --- a/lunaix-os/kernel.mk +++ b/lunaix-os/kernel.mk @@ -35,15 +35,17 @@ CFLAGS += -include flags.h $(call status_,CC,$<) @$(CC) $(CFLAGS) $(kinc_opts) -c $< -o $@ -$(kbin): $(kbin_dir) $(ksrc_files) $(ksrc_objs) - $(call status_,LD,$@) - @$(CC) -T link/linker.ld -o $(kbin) $(ksrc_objs) $(LDFLAGS) - $(kbin_dir)/modksyms: $(kbin) $(call status_,GEN,$@) @$(PY) scripts/syms_export.py --bits=32 --order=little -o "$@" "$<" -all: $(kbin) $(kbin_dir)/modksyms +.PHONY: __do_relink +__do_relink: $(ksrc_objs) + $(call status_,LD,$@) + @$(CC) -T link/linker.ld -o $(kbin) $(ksrc_objs) $(LDFLAGS) + +.PHONY: all +all: __do_relink $(kbin_dir)/modksyms clean: @rm -f $(ksrc_objs) diff --git a/lunaix-os/kernel/debug/trace.c b/lunaix-os/kernel/debug/trace.c index e43d873..ae183d4 100644 --- a/lunaix-os/kernel/debug/trace.c +++ b/lunaix-os/kernel/debug/trace.c @@ -133,8 +133,10 @@ trace_printswctx(const isr_param* p, char* direction) struct ksym_entry* sym = trace_sym_lookup(p->execp->eip); - kprintf( - KDEBUG ">> (sw:%s) iv:%d, errno:%p <<\n", direction, p->execp->vector); + kprintf(KDEBUG ">> (sw:%s) iv:%d, errno:%p <<\n", + direction, + p->execp->vector, + p->execp->err_code); kprintf(KDEBUG "%p:%s\n", p->execp->eip, ksym_getstr(sym)); } diff --git a/lunaix-os/kernel/exe/elf32/elf32bfmt.c b/lunaix-os/kernel/exe/elf32/elf32bfmt.c index 451c394..8d28143 100644 --- a/lunaix-os/kernel/exe/elf32/elf32bfmt.c +++ b/lunaix-os/kernel/exe/elf32/elf32bfmt.c @@ -164,12 +164,19 @@ elf32_read_phdr(struct elf32* elf) } int -elf32_check_exec(const struct elf32* elf) +elf32_check_exec(const struct elf32* elf, int type) +{ + const struct elf32_ehdr* ehdr = &elf->eheader; + + return (ehdr->e_entry) && ehdr->e_type == type; +} + +int +elf32_check_arch(const struct elf32* elf) { const struct elf32_ehdr* ehdr = &elf->eheader; return *(u32_t*)(ehdr->e_ident) == ELFMAGIC && ehdr->e_ident[EI_CLASS] == ELFCLASS32 && - ehdr->e_ident[EI_DATA] == ELFDATA2LSB && ehdr->e_type == ET_EXEC && - ehdr->e_machine == EM_386; -} + ehdr->e_ident[EI_DATA] == ELFDATA2LSB && ehdr->e_machine == EM_386; +} \ No newline at end of file diff --git a/lunaix-os/kernel/exe/elf32/ldelf32.c b/lunaix-os/kernel/exe/elf32/ldelf32.c index ec54a65..97db4bd 100644 --- a/lunaix-os/kernel/exe/elf32/ldelf32.c +++ b/lunaix-os/kernel/exe/elf32/ldelf32.c @@ -8,7 +8,8 @@ int elf32_smap(struct load_context* ldctx, const struct elf32* elf, - struct elf32_phdr* phdre) + struct elf32_phdr* phdre, + uintptr_t base_va) { struct v_file* elfile = (struct v_file*)elf->elf_file; @@ -25,21 +26,22 @@ elf32_smap(struct load_context* ldctx, proct |= PROT_EXEC; } + uintptr_t va = phdre->p_va + base_va; struct exec_container* container = ldctx->container; struct mmap_param param = { .vms_mnt = container->vms_mnt, .pvms = &container->proc->mm, .proct = proct, .offset = PG_ALIGN(phdre->p_offset), .mlen = ROUNDUP(phdre->p_memsz, PG_SIZE), - .flen = phdre->p_filesz + PG_MOD(phdre->p_va), + .flen = phdre->p_filesz, .flags = MAP_FIXED | MAP_PRIVATE, .type = REGION_TYPE_CODE }; struct mm_region* seg_reg; - int status = mem_map(NULL, &seg_reg, PG_ALIGN(phdre->p_va), elfile, ¶m); + int status = mem_map(NULL, &seg_reg, PG_ALIGN(va), elfile, ¶m); if (!status) { - size_t next_addr = phdre->p_memsz + phdre->p_va; + size_t next_addr = phdre->p_memsz + va; ldctx->end = MAX(ldctx->end, ROUNDUP(next_addr, PG_SIZE)); ldctx->mem_sz += phdre->p_memsz; } else { @@ -63,13 +65,19 @@ load_executable(struct load_context* context, const struct v_file* exefile) goto done; } - if (!elf32_check_exec(&elf)) { + if (!elf32_check_arch(&elf)) { + errno = EINVAL; + goto done; + } + + if (!(elf32_check_exec(&elf, ET_EXEC) || elf32_check_exec(&elf, ET_DYN))) { errno = ENOEXEC; goto done; } ldpath = valloc(512); errno = elf32_find_loader(&elf, ldpath, 512); + uintptr_t load_base = 0; if (errno < 0) { goto done; @@ -89,35 +97,37 @@ load_executable(struct load_context* context, const struct v_file* exefile) } // Is this the valid loader? - if (!elf32_static_linked(&elf) || !elf32_check_exec(&elf)) { + if (!elf32_static_linked(&elf) || !elf32_check_exec(&elf, ET_DYN)) { errno = ELIBBAD; goto done_close_elf32; } - // TODO: relocate loader - } else { - context->entry = elf.eheader.e_entry; + load_base = UMMAP_START; } + context->entry = elf.eheader.e_entry + load_base; + struct v_file* elfile = (struct v_file*)elf.elf_file; for (size_t i = 0; i < elf.eheader.e_phnum && !errno; i++) { struct elf32_phdr* phdr = &elf.pheaders[i]; - if (phdr->p_type == PT_LOAD) { - if (phdr->p_align != PG_SIZE) { - // surprising alignment! - errno = ENOEXEC; - continue; - } + if (phdr->p_type != PT_LOAD) { + continue; + } - errno = elf32_smap(context, &elf, phdr); + if (phdr->p_align != PG_SIZE) { + // surprising alignment! + errno = ENOEXEC; + break; } - // TODO Handle relocation + + errno = elf32_smap(context, &elf, phdr, load_base); } done_close_elf32: elf32_close(&elf); + done: vfree_safe(ldpath); return errno; diff --git a/lunaix-os/kernel/mm/mmap.c b/lunaix-os/kernel/mm/mmap.c index fcdd91c..8a4c9bc 100644 --- a/lunaix-os/kernel/mm/mmap.c +++ b/lunaix-os/kernel/mm/mmap.c @@ -331,6 +331,7 @@ __DEFINE_LXSYSCALL3(void*, sys_mmap, void*, addr, size_t, length, va_list, lst) struct mmap_param param = { .flags = options, .mlen = ROUNDUP(length, PG_SIZE), + .flen = length, .offset = offset, .type = REGION_TYPE_GENERAL, .proct = proct, diff --git a/lunaix-os/kernel/mm/vmap.c b/lunaix-os/kernel/mm/vmap.c index 35f61e4..4b1b311 100644 --- a/lunaix-os/kernel/mm/vmap.c +++ b/lunaix-os/kernel/mm/vmap.c @@ -55,7 +55,7 @@ vmm_vmap(ptr_t paddr, size_t size, pt_attr attr) done: ptr_t alloc_begin = current_addr - examed_size; for (size_t i = 0; i < size; i += PG_SIZE) { - vmm_set_mapping(VMS_SELF, alloc_begin + i, paddr + i, PG_PREM_RW, 0); + vmm_set_mapping(VMS_SELF, alloc_begin + i, paddr + i, attr, 0); pmm_ref_page(KERNEL_PID, paddr + i); } start = alloc_begin + size; diff --git a/lunaix-os/makefile b/lunaix-os/makefile index 7513516..af90c06 100644 --- a/lunaix-os/makefile +++ b/lunaix-os/makefile @@ -37,13 +37,15 @@ $(kbuild_dir): @mkdir -p $(os_img_dir)/boot/grub @mkdir -p $(os_img_dir)/usr +.PHONY: kernel export BUILD_DIR=$(kbin_dir) export BUILD_NAME=$(kbin) -$(kbin): +kernel: $(call status,TASK,$(notdir $@)) @$(MAKE) $(MKFLAGS) -I $(mkinc_dir) -f kernel.mk all -$(kimg): usr/build $(kbin) +.PHONY: image +image: usr/build kernel $(call status,TASK,$(notdir $@)) @./config-grub.sh ${OS_NAME} $(os_img_dir)/boot/grub/grub.cfg @cp -r usr/build/* $(os_img_dir)/usr @@ -57,10 +59,10 @@ check: $(DEPS) check-cc GRUB_TEMPLATE prepare: check $(os_img_dir) export BUILD_MODE=release -bootable: $(kbuild_dir) $(kimg) +bootable: $(kbuild_dir) image export BUILD_MODE=debug -bootable-debug: $(kbuild_dir) $(kimg) +bootable-debug: $(kbuild_dir) image user: $(call status,$@) diff --git a/lunaix-os/usr/ld b/lunaix-os/usr/ld new file mode 160000 index 0000000..19cf404 --- /dev/null +++ b/lunaix-os/usr/ld @@ -0,0 +1 @@ +Subproject commit 19cf404f8839aa07dd818136ef62d34935a00cba -- 2.27.0