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) }
+}
