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) \ - -T../gnu-efi/gnuefi/elf_x86_64_efi.lds \ + -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) \ + -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 #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) } +}