trace: Add support for UEFI

This commit is contained in:
mintsuki 2021-04-08 01:15:35 +02:00
parent 46a82f1c7f
commit 9caa555973
6 changed files with 205 additions and 23 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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"

View File

@ -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

78
stage23/linker_uefi.ld Normal file
View File

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

View File

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