diff options
| author | Ada Christine <adachristine18@gmail.com> | 2024-02-22 20:05:51 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2024-02-22 20:05:51 +0000 |
| commit | aec58be40927ec0b2a0e6742396f880d52ce38b5 (patch) | |
| tree | 5336b9966808a6d0706e7469d239d1dbc11cb3e2 /kjarna_runtime | |
| parent | e97aa65fc42f08fe666a9a21b69d05ab17231920 (diff) | |
kjarna runtime
Diffstat (limited to 'kjarna_runtime')
| -rw-r--r-- | kjarna_runtime/Makefile | 36 | ||||
| -rw-r--r-- | kjarna_runtime/dynamic_x86_64.c | 81 | ||||
| -rw-r--r-- | kjarna_runtime/kc.h | 45 | ||||
| -rw-r--r-- | kjarna_runtime/kc.ld | 97 | ||||
| -rw-r--r-- | kjarna_runtime/kc_main.c | 26 | ||||
| -rw-r--r-- | kjarna_runtime/reloc_x86_64.c | 42 | ||||
| -rw-r--r-- | kjarna_runtime/start_x86_64.S | 57 |
7 files changed, 384 insertions, 0 deletions
diff --git a/kjarna_runtime/Makefile b/kjarna_runtime/Makefile new file mode 100644 index 0000000..568beba --- /dev/null +++ b/kjarna_runtime/Makefile @@ -0,0 +1,36 @@ +include ../defaults.mk + +LDFLAGS += -z max-page-size=4096 --export-dynamic -pic \ + -z separate-code -pie -Bsymbolic -shared \ + -z noexecstack -g + +VPATH := ../lib + +TARGET := kjarna.os +.DEFAULT: $(TARGET) + +CPPFLAGS += -I../api -I. + +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 +LIB_OBJS := memcmp.o memcpy.o memmove.o memset.o string.o +APP_OBJS := kc_main.o + +OBJS := $(CRT_OBJS) $(LIB_OBJS) $(APP_OBJS) + +DEPS := $(patsubst %.o,%.d,$(OBJS)) + +$(TARGET): $(LDSCRIPT) $(MAKEFILE_LIST) +$(TARGET): $(OBJS) + +CLEANLIST := $(wildcard $(OBJS) $(TARGET)) +DCLEANLIST := $(wildcard $(DEPS)) + +include ../rules.mk +-include $(DEPS) + +.DEFAULT: $(TARGET) + diff --git a/kjarna_runtime/dynamic_x86_64.c b/kjarna_runtime/dynamic_x86_64.c new file mode 100644 index 0000000..e49f13d --- /dev/null +++ b/kjarna_runtime/dynamic_x86_64.c @@ -0,0 +1,81 @@ +#include <kc.h> + +#include <libc/string.h> +#include <lib/elf.h> + +extern void _rtld_link(void); + +struct elf64_relatab +{ + Elf64_Rela *entries; + size_t size; + size_t entsize; +}; + +struct elf64_symtab +{ + Elf64_Sym *entries; + const char *strings; + size_t strsize; +}; + +struct elf64_dso_info +{ + char *base; + struct elf64_relatab jmprel; + struct elf64_relatab reladyn; + struct elf64_symtab dynsym; + Elf64_Addr *pltgot; +}; + +static struct elf64_dso_info dso_info; + +void kc_dynamic_init(char *base, Elf64_Dyn *dyn) +{ + dso_info = (struct elf64_dso_info) + { + base, + { + elf64_dt_ptr(base, dyn, DT_JMPREL), + elf64_dt_val(dyn, DT_PLTRELSZ), + elf64_dt_val(dyn, DT_PLTREL) == DT_RELA ? sizeof(Elf64_Rela) : -1 + }, + { + elf64_dt_ptr(base, dyn, DT_RELA), + elf64_dt_val(dyn, DT_RELASZ), + elf64_dt_val(dyn, DT_RELAENT) + }, + { + elf64_dt_ptr(base, dyn, DT_SYMTAB), + elf64_dt_ptr(base, dyn, DT_STRTAB), + elf64_dt_val(dyn, DT_STRSZ) + }, + elf64_dt_ptr(base, dyn, DT_PLTGOT) + }; + + if (dso_info.pltgot != nullptr) + { + dso_info.pltgot[1] = (uintptr_t)&dso_info; + 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); +} + +void *kc_dynamic_link(struct elf64_dso_info *dso, int index) +{ + 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; + + if (strcmp(name, "write") == 0) + { + *fixup = (uintptr_t)*entry_params->interface->write; + return fixup; + } + + return nullptr; +} + diff --git a/kjarna_runtime/kc.h b/kjarna_runtime/kc.h new file mode 100644 index 0000000..842d7be --- /dev/null +++ b/kjarna_runtime/kc.h @@ -0,0 +1,45 @@ +#pragma once + +#ifndef __ASSEMBLER__ + +#include <elf/elf64.h> + +#include <stddef.h> + +#include <kjarna/interface.h> + +extern struct kjarna_entry_params *entry_params; + +#define KC_EXPORT __attribute__((visibility("default"))) + +extern unsigned char kc_image_base; +extern unsigned char kc_text_begin; +extern unsigned char kc_text_end; +extern unsigned char kc_rodata_begin; +extern unsigned char kc_data_begin; +extern unsigned char kc_data_end; +extern unsigned char kc_image_end; + +struct elf64_dso_info; + +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); + +#else + +.extern kc_image_base +.extern kc_text_begin +.extern kc_text_end +.extern kc_rodata_begin +.extern kc_rodata_end +.extern kc_data_begin +.extern kc_data_end +.extern kc_image_end +.extern _DYNAMIC + +.extern kc_dynamic_init +.extern kc_dynamic_link + +#endif // __ASSEMBLER__ + diff --git a/kjarna_runtime/kc.ld b/kjarna_runtime/kc.ld new file mode 100644 index 0000000..f7b0339 --- /dev/null +++ b/kjarna_runtime/kc.ld @@ -0,0 +1,97 @@ +ENTRY(_start) + +SECTIONS +{ + PROVIDE_HIDDEN(kc_image_base = .); + + . = SIZEOF_HEADERS; + + .rela.plt : + { + *(.rela.plt) + } + + .rela.dyn : + { + *(.rela.dyn) + } + + .hash : + { + *(.hash) + } + + .dynsym : + { + *(.dynsym) + } + + .dynstr : + { + *(.dynstr) + } + + .rodata : + { + *(.rodata) + *(.rodata.*) + } + + .text : ALIGN(4K) + { + PROVIDE_HIDDEN(kc_text_begin = .); + *(.text.start) + *(.text) + } + + .plt : + { + *(.plt) + . = ALIGN(4K); + PROVIDE_HIDDEN(kc_text_end = .); + } =0xcc + + .dynamic : ALIGN(4K) + { + PROVIDE_HIDDEN(kc_data_begin = .); + *(.dynamic) + } + + .got : + { + *(.got) + } + + .got.plt : + { + *(.got.plt) + } + + .data : + { + *(.data) + } + + .data.rel : + { + *(.data.rel) + *(.data.rel.*) + } + + .bss : + { + *(.bss) + *(.dynbss) + . = ALIGN(4K); + PROVIDE_HIDDEN(kc_data_end = .); + } + + PROVIDE_HIDDEN(kc_image_end = .); + + /DISCARD/ : + { + *(.eh_frame) + *(.comment) + } +} + diff --git a/kjarna_runtime/kc_main.c b/kjarna_runtime/kc_main.c new file mode 100644 index 0000000..acfcdc1 --- /dev/null +++ b/kjarna_runtime/kc_main.c @@ -0,0 +1,26 @@ +#include <kjarna/interface.h> + +extern int write(int, void *, size_t); + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + write(1, "hello, runtime world!\r\n", -1); + + while (1); + + return 0; +} + +struct kjarna_entry_params *entry_params; + +int kjarna_entry(struct kjarna_entry_params *params) +{ + entry_params = params; + entry_params->interface->write(1, "hello, entry world\r\n", -1); + + return main(params->argc, params->argv); +} + diff --git a/kjarna_runtime/reloc_x86_64.c b/kjarna_runtime/reloc_x86_64.c new file mode 100644 index 0000000..63dc6e7 --- /dev/null +++ b/kjarna_runtime/reloc_x86_64.c @@ -0,0 +1,42 @@ +#include <kc.h> + +#define STARTCODE __attribute__((section(".text.start"))) + +STARTCODE +static void do_rela(void *base, Elf64_Rela *rela) +{ + union + { + Elf_Byte word8; + Elf64_Half word16; + Elf64_Word word32; + Elf64_Xword word64; + } + *fixup; + + switch (ELF64_R_TYPE(rela->r_info)) + { + case R_X86_64_JUMP_SLOT: + fixup = (void *)(rela->r_offset + (uintptr_t)base); + fixup->word64 += (uintptr_t)base; + break; + case R_X86_64_RELATIVE: + fixup = (void *)(rela->r_offset + (uintptr_t)base); + fixup->word64 = (rela->r_addend + (uintptr_t)base); + break; + default: + break; + } +} + +STARTCODE +void kc_reloc(void *base, Elf64_Rela *entries, size_t size, size_t entsize) +{ + // perform the actual relocation + + for (size_t i = 0; entries && (i < size / entsize); i++) + { + do_rela(base, &entries[i]); + } +} + diff --git a/kjarna_runtime/start_x86_64.S b/kjarna_runtime/start_x86_64.S new file mode 100644 index 0000000..f7725c6 --- /dev/null +++ b/kjarna_runtime/start_x86_64.S @@ -0,0 +1,57 @@ +#include <kc.h> + +.section .text.start + +.extern kjarna_entry + +.hidden _start +.global _start +.type _start, @function +_start: + push %rbp + push %rdi + push %rsi + mov %rsp, %rbp + and $-0x10, %rsp + lea kc_image_base(%rip), %rdi + lea _DYNAMIC(%rip), %rsi + call kc_dynamic_init + mov %rbp, %rsp + pop %rsi + pop %rdi + mov %rsp, %rbp + and $-0x10, %rsp + call kjarna_entry + mov %rbp, %rsp + pop %rbp + ret +.size _start, . - _start + +.section .text + +.hidden _rtld_link +.global _rtld_link +.type _rtld_link, @function +_rtld_link: + push %rbp + mov %rsp, %rbp + push %rdx + push %rsi + push %rdi + mov 8(%rbp), %rdi + mov 16(%rbp), %rsi + push %rbp + mov %rsp, %rbp + and $-0x10, %rsp + call kc_dynamic_link + mov %rbp, %rsp + pop %rbp + pop %rdi + pop %rsi + pop %rdx + mov %rbp, %rsp + pop %rbp + add $0x10, %rsp + jmp *(%rax) +.size _rtld_link, . - _rtld_link + |
