:: commit 9caa55597394d1b549518c7c9b1908b5397d19a7

mintsuki <mintsuki@protonmail.com> — 2021-04-07 23:15

parents: 46a82f1c7f

trace: Add support for UEFI

diff --git a/stage23/Makefile b/stage23/Makefile
index 405379f2..edce122e 100644
--- a/stage23/Makefile
+++ b/stage23/Makefile
@@ -151,12 +151,12 @@ $(BUILDDIR)/stage2.bin: $(BUILDDIR)/limine.sys
 $(BUILDDIR)/stage2.map.o: $(BUILDDIR)/limine_stage2only.elf
 	GENSYMS="`pwd`/gensyms.sh" && \
 	cd "`dirname $<`" && \
-	"$$GENSYMS" $(OBJDUMP) $< stage2
+	"$$GENSYMS" $(OBJDUMP) $< stage2 32
 
 $(BUILDDIR)/full.map.o: $(BUILDDIR)/limine_nomap.elf
 	GENSYMS="`pwd`/gensyms.sh" && \
 	cd "`dirname $<`" && \
-	"$$GENSYMS" $(OBJDUMP) $< full
+	"$$GENSYMS" $(OBJDUMP) $< full 32
 
 $(BUILDDIR)/limine.sys: $(BUILDDIR)/limine.elf
 	$(OBJCOPY) -O binary $< $@
@@ -179,12 +179,25 @@ endif
 
 ifeq ($(TARGET), uefi)
 
+$(BUILDDIR)/full.map.o: $(BUILDDIR)/limine_efi_nomap.elf
+	GENSYMS="`pwd`/gensyms.sh" && \
+	cd "`dirname $<`" && \
+	"$$GENSYMS" $(OBJDUMP) $< full 64
+
 $(BUILDDIR)/BOOTX64.EFI: $(BUILDDIR)/limine_efi.elf
 	$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 $< $@
 
-$(BUILDDIR)/limine_efi.elf: $(OBJ) $(BUILDDIR)/font.o $(BUILDDIR)/sys/smp_trampoline.o
+$(BUILDDIR)/limine_efi_nomap.elf: $(OBJ) $(BUILDDIR)/font.o $(BUILDDIR)/sys/smp_trampoline.o
+	$(CC) \
+		-Tlinker_uefi_nomap.ld \
+		../gnu-efi/gnuefi/crt0-efi-x86_64.o \
+		../gnu-efi/gnuefi/libgnuefi.a \
+		../gnu-efi/lib/x86_64/efi_stub.o \
+		$^ $(LDFLAGS) $(INTERNAL_LDFLAGS) -o $@
+
+$(BUILDDIR)/limine_efi.elf: $(OBJ) $(BUILDDIR)/font.o $(BUILDDIR)/sys/smp_trampoline.o $(BUILDDIR)/full.map.o
 	$(CC) \
-		-T../gnu-efi/gnuefi/elf_x86_64_efi.lds \
+		-Tlinker_uefi.ld \
 		../gnu-efi/gnuefi/crt0-efi-x86_64.o \
 		../gnu-efi/gnuefi/libgnuefi.a \
 		../gnu-efi/lib/x86_64/efi_stub.o \
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index 49c48205..aeb37802 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -60,7 +60,13 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
         panic("Can't determine boot disk");
     }
 
-    stage3_common();
+    // Invalid return address of 0 to end stacktraces here
+    asm volatile (
+        "push 0\n\t"
+        "jmp stage3_common\n\t"
+    );
+
+    __builtin_unreachable();
 }
 #endif
 
diff --git a/stage23/gensyms.sh b/stage23/gensyms.sh
index fe6c0618..89362cd1 100755
--- a/stage23/gensyms.sh
+++ b/stage23/gensyms.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-set -e
+set -e -o pipefail
 
 TMP1=$(mktemp)
 TMP2=$(mktemp)
@@ -15,10 +15,14 @@ echo "section .$3_map" > "$TMP4"
 echo "global $3_map" >> "$TMP4"
 echo "$3_map:" >> "$TMP4"
 
-paste -d'$' "$TMP2" "$TMP3" | sed 's/^/dd 0x/g' | sed 's/$/", 0/g' | sed 's/\$/\ndb "/g' >> "$TMP4"
-
-echo "dd 0xffffffff" >> "$TMP4"
-
-nasm -f elf32 "$TMP4" -o $3.map.o
+if [ "$4" = "32" ]; then
+    paste -d'$' "$TMP2" "$TMP3" | sed 's/^/dd 0x/g' | sed 's/$/", 0/g' | sed 's/\$/\ndb "/g' >> "$TMP4"
+    echo "dd 0xffffffff" >> "$TMP4"
+    nasm -f elf32 "$TMP4" -o $3.map.o
+elif [ "$4" = "64" ]; then
+    paste -d'$' "$TMP2" "$TMP3" | sed 's/^/dq 0x/g' | sed 's/$/", 0/g' | sed 's/\$/\ndb "/g' >> "$TMP4"
+    echo "dq 0xffffffffffffffff" >> "$TMP4"
+    nasm -f elf64 "$TMP4" -o $3.map.o
+fi
 
 rm "$TMP1" "$TMP2" "$TMP3" "$TMP4"
diff --git a/stage23/lib/trace.s2.c b/stage23/lib/trace.s2.c
index 957fad8a..47fb9a85 100644
--- a/stage23/lib/trace.s2.c
+++ b/stage23/lib/trace.s2.c
@@ -9,16 +9,26 @@
 #include <mm/pmm.h>
 
 #if defined (bios)
+extern symbol stage2_map;
+#elif defined (uefi)
+extern symbol ImageBase;
+#endif
 
-extern symbol stage2_map, full_map;
+extern symbol full_map;
 
 static char *trace_address(size_t *off, size_t addr) {
     char *limine_map;
 
+#if defined (bios)
     if (!stage3_loaded)
         limine_map = stage2_map;
     else
         limine_map = full_map;
+#elif defined (uefi)
+    limine_map = full_map;
+
+    addr -= (size_t)ImageBase;
+#endif
 
     uintptr_t prev_addr = 0;
     char     *prev_sym  = NULL;
@@ -38,7 +48,11 @@ static char *trace_address(size_t *off, size_t addr) {
 void print_stacktrace(size_t *base_ptr) {
     if (base_ptr == NULL) {
         asm volatile (
+#if defined (bios)
             "mov %0, ebp"
+#elif defined (uefi)
+            "mov %0, rbp"
+#endif
             : "=g"(base_ptr)
             :: "memory"
         );
@@ -61,14 +75,3 @@ void print_stacktrace(size_t *base_ptr) {
     }
     print("End of trace.\n");
 }
-
-#endif
-
-#if defined (uefi)
-
-void print_stacktrace(size_t *base_ptr) {
-    (void)base_ptr;
-    print("Stacktrace unavailable when using UEFI.\n");
-}
-
-#endif
diff --git a/stage23/linker_uefi.ld b/stage23/linker_uefi.ld
new file mode 100644
index 00000000..7a607ce2
--- /dev/null
+++ b/stage23/linker_uefi.ld
@@ -0,0 +1,78 @@
+/* The following code originates from gnu-efi */
+
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0;
+  ImageBase = .;
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
+  . = ALIGN(4096);
+  .eh_frame :
+  {
+    *(.eh_frame)
+  }
+  . = ALIGN(4096);
+  .text :
+  {
+   _text = .;
+   *(.text)
+   *(.text.*)
+   *(.gnu.linkonce.t.*)
+   . = ALIGN(16);
+  }
+  _etext = .;
+  _text_size = . - _text;
+  . = ALIGN(4096);
+  .reloc :
+  {
+   *(.reloc)
+  }
+  . = ALIGN(4096);
+  .data :
+  {
+   _data = .;
+   *(.rodata*)
+   *(.got.plt)
+   *(.got)
+   *(.data*)
+   *(.sdata)
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   *(.rel.local)
+   *(.full_map*)
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+
+  _edata = .;
+  _data_size = . - _etext;
+  . = ALIGN(4096);
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .rela :
+  {
+    *(.rela.data*)
+    *(.rela.got)
+    *(.rela.stab)
+  }
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  .ignored.reloc :
+  {
+    *(.rela.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+}
diff --git a/stage23/linker_uefi_nomap.ld b/stage23/linker_uefi_nomap.ld
new file mode 100644
index 00000000..c340c5ac
--- /dev/null
+++ b/stage23/linker_uefi_nomap.ld
@@ -0,0 +1,78 @@
+/* The following code originates from gnu-efi */
+
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0;
+  ImageBase = .;
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
+  . = ALIGN(4096);
+  .eh_frame :
+  {
+    *(.eh_frame)
+  }
+  . = ALIGN(4096);
+  .text :
+  {
+   _text = .;
+   *(.text)
+   *(.text.*)
+   *(.gnu.linkonce.t.*)
+   . = ALIGN(16);
+  }
+  _etext = .;
+  _text_size = . - _text;
+  . = ALIGN(4096);
+  .reloc :
+  {
+   *(.reloc)
+  }
+  . = ALIGN(4096);
+  .data :
+  {
+   _data = .;
+   *(.rodata*)
+   *(.got.plt)
+   *(.got)
+   *(.data*)
+   *(.sdata)
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   *(.rel.local)
+   full_map = .;
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+
+  _edata = .;
+  _data_size = . - _etext;
+  . = ALIGN(4096);
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .rela :
+  {
+    *(.rela.data*)
+    *(.rela.got)
+    *(.rela.stab)
+  }
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  .ignored.reloc :
+  {
+    *(.rela.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+}
tab: 248 wrap: offon