summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2024-02-24 00:16:09 +0000
committerAda Christine <adachristine18@gmail.com>2024-02-24 00:16:09 +0000
commita8a62bdba61177342ae38274c8196bc7a7c46fa0 (patch)
tree7147b2807cdc96716dde96c0807693ddd366ebb9
parentaec58be40927ec0b2a0e6742396f880d52ce38b5 (diff)
kjarna runtime
-rw-r--r--api/posix/unistd.h4
-rw-r--r--kjarna/efi/file.c27
-rw-r--r--kjarna_runtime/Makefile2
-rw-r--r--kjarna_runtime/dynamic_x86_64.c72
-rw-r--r--kjarna_runtime/kc.h3
-rw-r--r--kjarna_runtime/start_x86_64.S6
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 *)&current);
+ }
+
+ 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