From 912a4c7169e171a40b52d88c0ac82445855b979b Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Sat, 6 Apr 2024 15:37:04 +0000 Subject: more abstract build --- service/Makefile | 4 +- service/arch/x86_64/dynamic.c | 139 ++++++++++++++++++++++++++++++++++++++++ service/arch/x86_64/rtld_link.S | 36 +++++++++++ service/arch/x86_64/start.S | 30 +++++++++ service/dynamic_x86_64.c | 139 ---------------------------------------- service/start_x86_64.S | 63 ------------------ 6 files changed, 207 insertions(+), 204 deletions(-) create mode 100644 service/arch/x86_64/dynamic.c create mode 100644 service/arch/x86_64/rtld_link.S create mode 100644 service/arch/x86_64/start.S delete mode 100644 service/dynamic_x86_64.c delete mode 100644 service/start_x86_64.S (limited to 'service') diff --git a/service/Makefile b/service/Makefile index d6e762d..1a4e400 100644 --- a/service/Makefile +++ b/service/Makefile @@ -4,7 +4,7 @@ LDFLAGS += -z max-page-size=4096 --export-dynamic -pic \ -z separate-code -pie -Bsymbolic -shared \ -z noexecstack -g -VPATH := ../lib +VPATH := ../lib arch/x86_64/ TARGET := kjarna.os .DEFAULT: $(TARGET) @@ -15,7 +15,7 @@ CFLAGS += -fPIC -fvisibility=hidden -mgeneral-regs-only LDSCRIPT := kc.ld -CRT_OBJS := start_x86_64.o dynamic_x86_64.o elf64.o kjarna.o +CRT_OBJS := start.o rtld_link.o dynamic.o elf64.o kjarna.o LIB_OBJS := memcmp.o memcpy.o memmove.o memset.o string.o stdio.o \ printf.o APP_OBJS := main.o diff --git a/service/arch/x86_64/dynamic.c b/service/arch/x86_64/dynamic.c new file mode 100644 index 0000000..02538ec --- /dev/null +++ b/service/arch/x86_64/dynamic.c @@ -0,0 +1,139 @@ +#include + +#include +#include + +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_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); + + // 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)*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) +{ + size_t entries = rela->size / rela->entsize; + + for (size_t i = 0; rela->entries && (i < entries); i++) + { + do_rela(base, &rela->entries[i]); + } +} + diff --git a/service/arch/x86_64/rtld_link.S b/service/arch/x86_64/rtld_link.S new file mode 100644 index 0000000..7300a18 --- /dev/null +++ b/service/arch/x86_64/rtld_link.S @@ -0,0 +1,36 @@ +.section .text + +.extern kc_dynamic_link + +.hidden _rtld_link +.global _rtld_link +.type _rtld_link, @function +_rtld_link: + push %rbp + mov %rsp, %rbp + push %r9 + push %r8 + push %rcx + 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 + pop %rcx + pop %r8 + pop %r9 + mov %rbp, %rsp + pop %rbp + add $0x10, %rsp + jmp *(%rax) +.size _rtld_link, . - _rtld_link + diff --git a/service/arch/x86_64/start.S b/service/arch/x86_64/start.S new file mode 100644 index 0000000..a9d5ada --- /dev/null +++ b/service/arch/x86_64/start.S @@ -0,0 +1,30 @@ +.section .text.start + +.extern kc_image_base; +.extern _DYNAMIC; +.extern kc_dynamic_init; +.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 + diff --git a/service/dynamic_x86_64.c b/service/dynamic_x86_64.c deleted file mode 100644 index 02538ec..0000000 --- a/service/dynamic_x86_64.c +++ /dev/null @@ -1,139 +0,0 @@ -#include - -#include -#include - -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_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); - - // 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)*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) -{ - size_t entries = rela->size / rela->entsize; - - for (size_t i = 0; rela->entries && (i < entries); i++) - { - do_rela(base, &rela->entries[i]); - } -} - diff --git a/service/start_x86_64.S b/service/start_x86_64.S deleted file mode 100644 index 19db34f..0000000 --- a/service/start_x86_64.S +++ /dev/null @@ -1,63 +0,0 @@ -#include - -.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 %r9 - push %r8 - push %rcx - 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 - pop %rcx - pop %r8 - pop %r9 - mov %rbp, %rsp - pop %rbp - add $0x10, %rsp - jmp *(%rax) -.size _rtld_link, . - _rtld_link - -- cgit v1.3.1-1-g115d