add lunaix dynamic linker as submodule
authorMinep <lunaixsky@qq.com>
Wed, 23 Aug 2023 16:32:15 +0000 (17:32 +0100)
committerMinep <lunaixsky@qq.com>
Wed, 23 Aug 2023 16:32:15 +0000 (17:32 +0100)
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

12 files changed:
.gitmodules [new file with mode: 0644]
lunaix-os/includes/lunaix/exebi/elf32.h
lunaix-os/includes/lunaix/mm/page.h
lunaix-os/includes/lunaix/spike.h
lunaix-os/kernel.mk
lunaix-os/kernel/debug/trace.c
lunaix-os/kernel/exe/elf32/elf32bfmt.c
lunaix-os/kernel/exe/elf32/ldelf32.c
lunaix-os/kernel/mm/mmap.c
lunaix-os/kernel/mm/vmap.c
lunaix-os/makefile
lunaix-os/usr/ld [new submodule]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..8431bd9
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "lunaix-os/usr/ld"]
+       path = lunaix-os/usr/ld
+       url = git@github.com:Minep/lunaix-ld.git
index 634ccd6bd4cbe52355c9d5340d98eba178cb77e7..33da3a5769614c2a781b789cbbda603c7284757f 100644 (file)
@@ -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);
index 38dcf71aaa8ffe5ab5316e2438c68c28041e3189..7b8ba223388d370d27ff9743a5b2801f822b63a8 100644 (file)
@@ -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))
 
index ae193570f2b3bfaeb0af329d4e17f9ae94adb26e..356e4b392bcca12b28dd5f93b2f56fc81e3c3910 100644 (file)
                              : (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
index ba15fa37834e9d35ba2b2460c66b929c8f653233..5d645140271c724e8305e4d27b35f3e1680daca2 100644 (file)
@@ -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)
index e43d8733478b104139bedaf3f23eaba8d0b2e0eb..ae183d4f03afecf15a7497d03f0a5d7253aaf65c 100644 (file)
@@ -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));
 }
 
index 451c3946bd915dd23b5d0eaa631c092901f50a92..8d2814330ad72d66ba8c52791bc63297b68e39ed 100644 (file)
@@ -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
index ec54a6538dc1b93e3ff1e297d44270bdb3bb1dbb..97db4bdcfb43609fbc04ce3915d49ebdd9da49f1 100644 (file)
@@ -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, &param);
+    int status = mem_map(NULL, &seg_reg, PG_ALIGN(va), elfile, &param);
 
     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;
index fcdd91c27d899b9358b80c1ca89ce178575d7fd2..8a4c9bc6af509a653477f61833b389b2ce9e549d 100644 (file)
@@ -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,
index 35f61e425e45d9e464eb2635e0ee1091016f4ee9..4b1b311f70afd31a3dce6e52154d19de2bb65ed3 100644 (file)
@@ -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;
index 75135161de33113b4d8b938d09b57894aa2f4e0a..af90c0644f797997749d3626796a9dcf0f3731df 100644 (file)
@@ -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 (submodule)
index 0000000..19cf404
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 19cf404f8839aa07dd818136ef62d34935a00cba