ArmPkg/DefaultExceptionHandlerLib AARCH64: add minimal backtrace to crash dump

When dumping the CPU state after an unhandled fault, walk the stack
frames and decode the return addresses so we can show a minimal
backtrace. Unfortunately, we do not have sufficient information to
show the function names, but at least we can see the modules and the
return addresses inside the modules.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
index 31fc936..84b442f 100644
--- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
+++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
@@ -152,9 +152,30 @@
     CHAR8  *Pdb;

     UINTN  ImageBase;

     UINTN  PeCoffSizeOfHeader;

+    UINT64 *Fp;

+

     Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);

     if (Pdb != NULL) {

       DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb, ImageBase));

+

+      Pdb = GetImageName (SystemContext.SystemContextAArch64->LR, &ImageBase,

+              &PeCoffSizeOfHeader);

+      if (Pdb != NULL) {

+        DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at 0x%016lx \n",

+          Pdb, SystemContext.SystemContextAArch64->LR, ImageBase));

+      }

+      for (Fp = (UINT64 *)SystemContext.SystemContextAArch64->FP;

+           *Fp != 0;

+           Fp = (UINT64 *)Fp[0]) {

+        if (Fp[1] == SystemContext.SystemContextAArch64->LR) {

+         continue;

+        }

+        Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);

+        if (Pdb != NULL) {

+          DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at 0x%016lx \n",

+            Pdb, Fp[1], ImageBase));

+        }

+      }

     }

   DEBUG_CODE_END ();