diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/user/app/testelf/main.c | 18 | ||||
-rw-r--r-- | src/usertestelf.c | 69 | ||||
-rw-r--r-- | src/usertestelf.ld | 23 |
3 files changed, 18 insertions, 92 deletions
diff --git a/src/user/app/testelf/main.c b/src/user/app/testelf/main.c new file mode 100644 index 0000000..a80d233 --- /dev/null +++ b/src/user/app/testelf/main.c @@ -0,0 +1,18 @@ +#include <shared/printf.h> +#include <shared/syscalls.h> +#include <user/lib/elf.h> +#include <user/lib/elfload.h> +#include <user/lib/stdlib.h> + +const char *str = "Hello!\n", *str2 = "World.\n"; + +__attribute__((visibility("hidden"))) +extern char _image_base[]; + +int main(void) { + elf_selfreloc(); + printf("loaded at %x\n", &_image_base); + printf(str); + printf(str2); + _syscall_exit(0); +} diff --git a/src/usertestelf.c b/src/usertestelf.c deleted file mode 100644 index 1cbfcc5..0000000 --- a/src/usertestelf.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <shared/printf.h> -#include <user/lib/elf.h> -#include <user/lib/syscall.c> - -const char *str = "Hello!\n", *str2 = "World.\n"; - -__attribute__((visibility("hidden"))) -extern struct Elf64_Dyn _DYNAMIC[]; - -__attribute__((visibility("hidden"))) -extern char _image_base[]; - -static void printf_backend(void *arg, const char *buf, size_t len) { - (void)arg; - _syscall_write(1, buf, len, -1); - _syscall_debug_klog(buf, len); -} - -int printf(const char *fmt, ...) { - int ret = 0; - va_list argp; - va_start(argp, fmt); - ret = __printf_internal(fmt, argp, printf_backend, 0); - va_end(argp); - return ret; -} - - -static struct Elf64_Dyn *dyn_gettag(Elf64_Xword tag) { - for (size_t i = 0;; i++) { - if (_DYNAMIC[i].d_tag == tag) return &_DYNAMIC[i]; - if (_DYNAMIC[i].d_tag == DT_NULL) return NULL; - } -} - -static void reloc(void) { - // TODO DT_REL - if (dyn_gettag(DT_PLTGOT) || dyn_gettag(DT_JMPREL)) { - printf("elf: unimplemented tag in _DYNAMIC\n"); - } - - struct Elf64_Dyn *rela_tag = dyn_gettag(DT_RELA); - if (rela_tag) { - /* not checking pointer validity, - * crashing on an invalid elf is fine */ - size_t relasz = dyn_gettag(DT_RELASZ)->d_val; - size_t relaent = dyn_gettag(DT_RELAENT)->d_val; - for (size_t o = 0; o < relasz; o += relaent) { - struct Elf64_Rela *r = (void*)_image_base + rela_tag->d_ptr + o; - uintptr_t *target = (void*)_image_base + r->r_offset; - - switch (ELF64_R_TYPE(r->r_info)) { - case R_X86_64_RELATIVE: - *target = (uintptr_t)&_image_base + r->r_addend; - break; - default: - printf("elf: unsupported relocation type\n"); - } - } - } -} - -int main(void) { - printf("loaded at %x\n", &_image_base); - reloc(); - printf(str); - printf(str2); - _syscall_exit(0); -} diff --git a/src/usertestelf.ld b/src/usertestelf.ld deleted file mode 100644 index fcb5fc8..0000000 --- a/src/usertestelf.ld +++ /dev/null @@ -1,23 +0,0 @@ -ENTRY(main) - -SECTIONS -{ - _image_base = .; - .text BLOCK(4K) : ALIGN(4K) - { - *(.text) - } - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } -} |