--- /dev/null
+[submodule "lunaix-os/usr/ld"]
+ path = lunaix-os/usr/ld
+ url = git@github.com:Minep/lunaix-ld.git
#define ET_NONE 0
#define ET_EXEC 2
+#define ET_DYN 3
#define PT_LOAD 1
#define PT_INTERP 3
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);
#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))
: (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
$(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)
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));
}
}
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
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;
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 {
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;
}
// 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;
struct mmap_param param = { .flags = options,
.mlen = ROUNDUP(length, PG_SIZE),
+ .flen = length,
.offset = offset,
.type = REGION_TYPE_GENERAL,
.proct = proct,
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;
@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
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,$@)
--- /dev/null
+Subproject commit 19cf404f8839aa07dd818136ef62d34935a00cba