From f61da8be06fdfebc598cba783e78117319231140 Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Sun, 3 Mar 2024 08:44:42 +0000 Subject: build changes --- service/Makefile | 37 +++++++++++++ service/dynamic_x86_64.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ service/kc.h | 46 ++++++++++++++++ service/kc.ld | 97 +++++++++++++++++++++++++++++++++ service/kjarna.c | 13 +++++ service/main.c | 17 ++++++ service/start_x86_64.S | 63 +++++++++++++++++++++ 7 files changed, 412 insertions(+) create mode 100644 service/Makefile create mode 100644 service/dynamic_x86_64.c create mode 100644 service/kc.h create mode 100644 service/kc.ld create mode 100644 service/kjarna.c create mode 100644 service/main.c create mode 100644 service/start_x86_64.S (limited to 'service') diff --git a/service/Makefile b/service/Makefile new file mode 100644 index 0000000..d6e762d --- /dev/null +++ b/service/Makefile @@ -0,0 +1,37 @@ +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/posix -I../api/libc -I../api -I. + +CFLAGS += -fPIC -fvisibility=hidden -mgeneral-regs-only + +LDSCRIPT := kc.ld + +CRT_OBJS := start_x86_64.o dynamic_x86_64.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 + +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/service/dynamic_x86_64.c b/service/dynamic_x86_64.c new file mode 100644 index 0000000..02538ec --- /dev/null +++ b/service/dynamic_x86_64.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/kc.h b/service/kc.h new file mode 100644 index 0000000..ff3a1ca --- /dev/null +++ b/service/kc.h @@ -0,0 +1,46 @@ +#pragma once + +#ifndef __ASSEMBLER__ + +#include + +#include + +#include + +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; +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_dynamic_reloc(char *base, struct elf64_relatab *dso); + +#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/service/kc.ld b/service/kc.ld new file mode 100644 index 0000000..f7b0339 --- /dev/null +++ b/service/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/service/kjarna.c b/service/kjarna.c new file mode 100644 index 0000000..6b37d1e --- /dev/null +++ b/service/kjarna.c @@ -0,0 +1,13 @@ +#include + +struct kjarna_entry_params *entry_params; + +extern int main(int argc, char **argv); + +int kjarna_entry(struct kjarna_entry_params *params) +{ + entry_params = params; + + return main(params->argc, params->argv); +} + diff --git a/service/main.c b/service/main.c new file mode 100644 index 0000000..12a5522 --- /dev/null +++ b/service/main.c @@ -0,0 +1,17 @@ +#include +#include + +#define KJARNA_REVISION 1 + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + printf("kjarna %d\n", KJARNA_REVISION); + + while (1); + + return 0; +} + diff --git a/service/start_x86_64.S b/service/start_x86_64.S new file mode 100644 index 0000000..19db34f --- /dev/null +++ b/service/start_x86_64.S @@ -0,0 +1,63 @@ +#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