summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
l---------initrd/init.elf1
-rw-r--r--src/kernel/vfs/request.c1
-rw-r--r--src/user/app/main.c20
-rw-r--r--src/user/lib/elfload.c1
-rw-r--r--src/user/lib/elfload.h2
-rw-r--r--src/user/lib/elfreloc.c42
-rw-r--r--src/user/linker.ld10
-rw-r--r--src/user_bootstrap/main.c2
9 files changed, 70 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 72e7883..f1b6ce3 100644
--- a/Makefile
+++ b/Makefile
@@ -67,12 +67,19 @@ out/bootstrap: src/user_bootstrap/linker.ld $(call from_sources, src/user_bootst
initrd/test.elf: out/test.elf
@# dummy
+initrd/init.elf: out/init.elf
+ @# dummy
+
out/test.elf: src/usertestelf.ld out/obj/usertestelf.c.o out/obj/user/lib/syscall.s.o $(call from_sources, src/shared/)
@mkdir -p $(@D)
@$(CC) $(LFLAGS) -Wl,-pie -Wl,-no-dynamic-linker -T $^ -o $@
+out/init.elf: src/user/linker.ld $(call from_sources, src/user/) $(call from_sources, src/shared/)
+ @mkdir -p $(@D)
+ @$(CC) $(LFLAGS) -Wl,-pie -Wl,-no-dynamic-linker -T $^ -o $@
+
# TODO automatically resolve symlinks
-out/initrd.tar: $(shell find initrd/) out/test.elf
+out/initrd.tar: $(shell find initrd/) out/test.elf out/init.elf
cd initrd; tar chf ../$@ *
out/fs/boot/init: out/bootstrap out/initrd.tar
@@ -95,6 +102,10 @@ out/obj/%.c.o: src/%.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -c $^ -o $@
+out/obj/user/%.c.o: src/user/%.c
+ @mkdir -p $(@D)
+ @$(CC) $(CFLAGS) -fPIE -c $^ -o $@
+
out/obj/usertestelf.c.o: src/usertestelf.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -fPIE -c $^ -o $@
diff --git a/initrd/init.elf b/initrd/init.elf
new file mode 120000
index 0000000..21a467a
--- /dev/null
+++ b/initrd/init.elf
@@ -0,0 +1 @@
+../out/init.elf \ No newline at end of file
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index b056a31..102a7e8 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -15,6 +15,7 @@ void vfsreq_create(struct vfs_request req_) {
req->backend->refcount++;
if (req->caller) {
+ // TODO after running `run_tests` from vga, this is entered with state == PS_WAITS4FS
process_transition(req->caller, PS_WAITS4FS);
req->caller->waits4fs.req = req;
}
diff --git a/src/user/app/main.c b/src/user/app/main.c
index 6672344..28c4aa0 100644
--- a/src/user/app/main.c
+++ b/src/user/app/main.c
@@ -1,23 +1,21 @@
+#include <shared/flags.h>
+#include <shared/syscalls.h>
+#include <stdint.h>
+#include <user/app/shell.h>
#include <user/driver/driver.h>
#include <user/fs/misc.h>
-#include <user/app/shell.h>
-#include <user/lib/stdlib.h>
#include <user/fs/tar.h>
+#include <user/lib/elfload.h>
+#include <user/lib/stdlib.h>
#include <user/tests/main.h>
-#include <shared/flags.h>
-#include <shared/syscalls.h>
-#include <stdint.h>
-extern char _bss_start; // provided by the linker
-extern char _bss_end;
-extern char _initrd;
+// extern char _initrd;
void read_file(const char *path, size_t len);
__attribute__((section(".text.startup")))
int main(void) {
- // allocate bss
- _syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT);
+ elf_selfreloc();
file_reopen(stdout, "/com1", 0);
printf("preinit\n");
@@ -30,7 +28,7 @@ int main(void) {
}
if (!fork2_n_mount("/")) fs_dir_inject("/kdev/"); // TODO should be part of fs_whitelist
- MOUNT("/init/", tar_driver(&_initrd));
+ // MOUNT("/init/", tar_driver(&_initrd));
MOUNT("/tmp/", tmpfs_drv());
MOUNT("/keyboard", ps2_drv());
MOUNT("/vga_tty", ansiterm_drv());
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index c32232e..6c75268 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -76,6 +76,7 @@ void elf_exec(void *base) {
struct Elf64_Ehdr *ehdr = base;
void *exebase;
if (!valid_ehdr(ehdr)) return;
+ _syscall_debug_klog("here", 4);
size_t spread = elf_spread(base);
switch (ehdr->e_type) {
case ET_EXEC:
diff --git a/src/user/lib/elfload.h b/src/user/lib/elfload.h
index c6afbdd..f79be6e 100644
--- a/src/user/lib/elfload.h
+++ b/src/user/lib/elfload.h
@@ -3,3 +3,5 @@
void elf_execf(libc_file *f);
void elf_exec(void *elf);
+
+void elf_selfreloc(void); // elfreloc.c
diff --git a/src/user/lib/elfreloc.c b/src/user/lib/elfreloc.c
new file mode 100644
index 0000000..550fe97
--- /dev/null
+++ b/src/user/lib/elfreloc.c
@@ -0,0 +1,42 @@
+#include <user/lib/elf.h>
+#include <user/lib/stdlib.h>
+
+__attribute__((visibility("hidden")))
+extern struct Elf64_Dyn _DYNAMIC[];
+
+__attribute__((visibility("hidden")))
+extern char _image_base[];
+
+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;
+ }
+}
+
+void elf_selfreloc(void) {
+ // TODO DT_REL
+ if (dyn_gettag(DT_PLTGOT) || dyn_gettag(DT_JMPREL)) {
+ _klogf("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:
+ _klogf("elf: unsupported relocation type\n");
+ }
+ }
+ }
+}
diff --git a/src/user/linker.ld b/src/user/linker.ld
index f2c9d24..fcb5fc8 100644
--- a/src/user/linker.ld
+++ b/src/user/linker.ld
@@ -1,12 +1,10 @@
ENTRY(main)
-OUTPUT_FORMAT("binary")
SECTIONS
{
- . = 2M;
+ _image_base = .;
.text BLOCK(4K) : ALIGN(4K)
{
- *(.text.startup)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
@@ -17,15 +15,9 @@ SECTIONS
{
*(.data)
}
-
- _initrd = .; /* is just appended onto the end of the binary */
- . += 2M;
-
- _bss_start = .;
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
- _bss_end = .;
}
diff --git a/src/user_bootstrap/main.c b/src/user_bootstrap/main.c
index baa9803..71647c4 100644
--- a/src/user_bootstrap/main.c
+++ b/src/user_bootstrap/main.c
@@ -51,7 +51,7 @@ __attribute__((section(".text.startup")))
int main(void) {
_syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT);
- void *init = tar_find(&_initrd, "test.elf");
+ void *init = tar_find(&_initrd, "init.elf");
elf_exec(init);
_syscall_debug_klog("bootstrap failed", sizeof("bootstrap failed"));