aboutsummaryrefslogtreecommitdiff
path: root/stand/efi/loader/arch
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2022-06-08 12:23:05 +0000
committerToomas Soome <tsoome@FreeBSD.org>2022-07-14 12:59:26 +0000
commitf4ca0fdbe69db4ab8147406e753d869d77485c2c (patch)
tree81d89a409c4f40d4c2db2119c32c335a2025ff08 /stand/efi/loader/arch
parent07007f314700bb556baac724488b4ecbf8e4e29c (diff)
downloadsrc-f4ca0fdbe69db4ab8147406e753d869d77485c2c.tar.gz
src-f4ca0fdbe69db4ab8147406e753d869d77485c2c.zip
loader.efi: faults could try to print out call trace
with grab_faults, we can try to print out the trace of function calls. Without symbol table, we can not translate addresses to function names, but even addresses can help to track the bugs. For loader functions, print out absolute address, so it could be searched from objdump -d output. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D35433
Diffstat (limited to 'stand/efi/loader/arch')
-rw-r--r--stand/efi/loader/arch/amd64/trap.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/stand/efi/loader/arch/amd64/trap.c b/stand/efi/loader/arch/amd64/trap.c
index 1a4306b00e0a..81357e558185 100644
--- a/stand/efi/loader/arch/amd64/trap.c
+++ b/stand/efi/loader/arch/amd64/trap.c
@@ -78,11 +78,21 @@ static uint32_t loader_tss; /* Loader TSS segment */
static struct region_descriptor fw_gdt; /* Descriptor of pristine GDT */
static EFI_PHYSICAL_ADDRESS loader_gdt_pa; /* Address of loader shadow GDT */
+struct frame {
+ struct frame *fr_savfp;
+ uintptr_t fr_savpc;
+};
+
void report_exc(struct trapframe *tf);
void
report_exc(struct trapframe *tf)
{
+ struct frame *fp;
+ uintptr_t pc, base;
+ char buf[80];
+ int ret;
+ base = (uintptr_t)boot_img->ImageBase;
/*
* printf() depends on loader runtime and UEFI firmware health
* to produce the console output, in case of exception, the
@@ -108,6 +118,33 @@ report_exc(struct trapframe *tf)
tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_rcx, tf->tf_r8,
tf->tf_r9, tf->tf_rax, tf->tf_rbx, tf->tf_rbp, tf->tf_r10,
tf->tf_r11, tf->tf_r12, tf->tf_r13, tf->tf_r14, tf->tf_r15);
+
+ fp = (struct frame *)tf->tf_rbp;
+ pc = tf->tf_rip;
+
+ printf("Stack trace:\n");
+ pager_open();
+ while (fp != NULL || pc != 0) {
+ char *source = "PC";
+
+ if (pc >= base && pc < base + boot_img->ImageSize) {
+ pc -= base;
+ source = "loader PC";
+ }
+ (void) snprintf(buf, sizeof (buf), "FP %016lx: %s 0x%016lx\n",
+ (uintptr_t)fp, source, pc);
+ if (pager_output(buf))
+ break;
+
+ if (fp != NULL)
+ fp = fp->fr_savfp;
+
+ if (fp != NULL)
+ pc = fp->fr_savpc;
+ else
+ pc = 0;
+ }
+ pager_close();
printf("Machine stopped.\n");
}