diff options
| author | Ada Christine <adachristine18@gmail.com> | 2024-02-24 00:16:09 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2024-02-24 00:16:09 +0000 |
| commit | a8a62bdba61177342ae38274c8196bc7a7c46fa0 (patch) | |
| tree | 7147b2807cdc96716dde96c0807693ddd366ebb9 | |
| parent | aec58be40927ec0b2a0e6742396f880d52ce38b5 (diff) | |
kjarna runtime
| -rw-r--r-- | api/posix/unistd.h | 4 | ||||
| -rw-r--r-- | kjarna/efi/file.c | 27 | ||||
| -rw-r--r-- | kjarna_runtime/Makefile | 2 | ||||
| -rw-r--r-- | kjarna_runtime/dynamic_x86_64.c | 72 | ||||
| -rw-r--r-- | kjarna_runtime/kc.h | 3 | ||||
| -rw-r--r-- | kjarna_runtime/start_x86_64.S | 6 |
6 files changed, 99 insertions, 15 deletions
diff --git a/api/posix/unistd.h b/api/posix/unistd.h index 6bd69f5..e440a4a 100644 --- a/api/posix/unistd.h +++ b/api/posix/unistd.h @@ -6,6 +6,8 @@ enum seek_whence { - SEEK_SET + SEEK_SET, + SEEK_CUR, + SEEK_END }; diff --git a/kjarna/efi/file.c b/kjarna/efi/file.c index 12364e6..e9da83e 100644 --- a/kjarna/efi/file.c +++ b/kjarna/efi/file.c @@ -145,27 +145,44 @@ int efi_close(int fd) off_t efi_lseek(int fd, off_t offset, int whence) { - if (whence != SEEK_SET) + EFI_FILE_PROTOCOL *file = fd_to_file(fd); + + if (file == nullptr) { efi_errno = EFI_INVALID_PARAMETER; return -1; } - EFI_FILE_PROTOCOL *file = fd_to_file(fd); + off_t current = 0; - if (file == nullptr) + if (whence == SEEK_END) + { + efi_errno = file->SetPosition(file, (UINTN)-1); + } + + if (EFI_ERROR(efi_errno)) + { + return -1; + } + + if (whence == SEEK_CUR || whence == SEEK_END) + { + efi_errno = file->GetPosition(file, (UINTN *)¤t); + } + + if (EFI_ERROR(efi_errno)) { - efi_errno = EFI_INVALID_PARAMETER; return -1; } - efi_errno = file->SetPosition(file, (UINTN)offset); + efi_errno = file->SetPosition(file, (UINTN)(offset + current)); return !EFI_ERROR(efi_errno) ? offset : -1; } static ssize_t efi_console_read(EFI_SIMPLE_TEXT_INPUT_PROTOCOL *console, CHAR16 *buffer, size_t length) { + //TODO: implement user input (void)console; (void)buffer; efi_errno = EFI_INVALID_PARAMETER; diff --git a/kjarna_runtime/Makefile b/kjarna_runtime/Makefile index 568beba..855f479 100644 --- a/kjarna_runtime/Makefile +++ b/kjarna_runtime/Makefile @@ -15,7 +15,7 @@ CFLAGS += -fPIC -fvisibility=hidden -mgeneral-regs-only LDSCRIPT := kc.ld -CRT_OBJS := start_x86_64.o reloc_x86_64.o dynamic_x86_64.o elf64.o +CRT_OBJS := start_x86_64.o dynamic_x86_64.o elf64.o LIB_OBJS := memcmp.o memcpy.o memmove.o memset.o string.o APP_OBJS := kc_main.o diff --git a/kjarna_runtime/dynamic_x86_64.c b/kjarna_runtime/dynamic_x86_64.c index e49f13d..3d85582 100644 --- a/kjarna_runtime/dynamic_x86_64.c +++ b/kjarna_runtime/dynamic_x86_64.c @@ -59,23 +59,81 @@ void kc_dynamic_init(char *base, Elf64_Dyn *dyn) dso_info.pltgot[2] = (uintptr_t)_rtld_link; } - kc_reloc(dso_info.base, dso_info.reladyn.entries, dso_info.reladyn.size, dso_info.reladyn.entsize); - kc_reloc(dso_info.base, dso_info.jmprel.entries, dso_info.jmprel.size, dso_info.jmprel.entsize); + kc_dynamic_reloc(base, &dso_info.jmprel); + kc_dynamic_reloc(base, &dso_info.reladyn); } void *kc_dynamic_link(struct elf64_dso_info *dso, int index) { + struct kjarna_interface *ftab = entry_params->interface; + int symindex = ELF64_R_SYM(dso->jmprel.entries[index].r_info); int strindex = dso->dynsym.entries[symindex].st_name; const char *name = &dso->dynsym.strings[strindex]; - uintptr_t *fixup = (uintptr_t *)dso->base + dso->jmprel.entries[index].r_offset; + uintptr_t *fixup = (uintptr_t *)(dso->base + dso->jmprel.entries[index].r_offset); - if (strcmp(name, "write") == 0) + // TODO: generate a symbol table for kjarna interface + // TODO: implement symbol lookup (maybe hashed too) + if (strcmp(name, "open") == 0) + { + *fixup = (uintptr_t)*ftab->open; + } + else if (strcmp(name, "close") == 0) + { + *fixup = (uintptr_t)*ftab->close; + } + else if (strcmp(name, "read") == 0) + { + *fixup = (uintptr_t)*ftab->read; + } + else if (strcmp(name, "write") == 0) + { + *fixup = (uintptr_t)*ftab->write; + } + else if (strcmp(name, "lseek") == 0) { - *fixup = (uintptr_t)*entry_params->interface->write; - return fixup; + *fixup = (uintptr_t)*ftab->lseek; } + else if (strcmp(name, "mmap") == 0) + { + *fixup = (uintptr_t)*ftab->mmap; + } + else if (strcmp(name, "munmap") == 0) + { + *fixup = (uintptr_t)*ftab->munmap; + } + else + { + return nullptr; + } + + return fixup; +} + +static void do_rela(char *base, Elf64_Rela *rela) +{ + uintptr_t *fixup = (uintptr_t *)(base + rela->r_offset); + + switch (ELF64_R_TYPE(rela->r_info)) + { + case R_X86_64_JUMP_SLOT: + *fixup += (uintptr_t)base; + break; + case R_X86_64_RELATIVE: + *fixup = (uintptr_t)(rela->r_addend + base); + break; + default: + break; + } +} + +void kc_dynamic_reloc(char *base, struct elf64_relatab *rela) +{ + // perform the actual relocation - return nullptr; + for (size_t i = 0; rela->entries && (i < rela->size); i += rela->entsize) + { + do_rela(base, &rela->entries[i]); + } } diff --git a/kjarna_runtime/kc.h b/kjarna_runtime/kc.h index 842d7be..ff3a1ca 100644 --- a/kjarna_runtime/kc.h +++ b/kjarna_runtime/kc.h @@ -21,10 +21,11 @@ extern unsigned char kc_data_end; extern unsigned char kc_image_end; struct elf64_dso_info; +struct elf64_relatab; extern void kc_dynamic_init(char *base, Elf64_Dyn *dyn); extern void *kc_dynamic_link(struct elf64_dso_info *dso, int index); -extern void kc_reloc(void *base, Elf64_Rela *entries, size_t size, size_t entsize); +extern void kc_dynamic_reloc(char *base, struct elf64_relatab *dso); #else diff --git a/kjarna_runtime/start_x86_64.S b/kjarna_runtime/start_x86_64.S index f7725c6..1db92a4 100644 --- a/kjarna_runtime/start_x86_64.S +++ b/kjarna_runtime/start_x86_64.S @@ -35,6 +35,9 @@ _start: _rtld_link: push %rbp mov %rsp, %rbp + push %r9 + push %r8 + push %rcx push %rdx push %rsi push %rdi @@ -49,6 +52,9 @@ _rtld_link: pop %rdi pop %rsi pop %rdx + pop %rcx + pop %r8 + pop %r9 mov %rbp, %rsp pop %rbp add $0x10, %rsp |
