diff options
Diffstat (limited to 'ArmPkg/Drivers/CpuDxe/Exception.c')
-rw-r--r-- | ArmPkg/Drivers/CpuDxe/Exception.c | 114 |
1 files changed, 110 insertions, 4 deletions
diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Drivers/CpuDxe/Exception.c index 9910bd2b88..1f84e314b4 100644 --- a/ArmPkg/Drivers/CpuDxe/Exception.c +++ b/ArmPkg/Drivers/CpuDxe/Exception.c @@ -13,7 +13,8 @@ **/
#include "CpuDxe.h"
-#include <Library/CacheMaintenanceLib.h>
+
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL; VOID
ExceptionHandlersStart (
@@ -120,6 +121,76 @@ RegisterDebuggerInterruptHandler ( return EFI_SUCCESS;
}
+
+UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } + + return SizeOfHeaders; +}
+
+
+CHAR8 *
+GetImageName (
+ IN UINT32 FaultAddress,
+ OUT UINT32 *ImageBase,
+ OUT UINT32 *PeCoffSizeOfHeaders
+ )
+{
+ EFI_DEBUG_IMAGE_INFO *DebugTable; + UINTN Entry; + CHAR8 *Address; + +
+ DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
+ if (DebugTable == NULL) {
+ return NULL;
+ }
+
+ Address = (CHAR8 *)(UINTN)FaultAddress;
+ for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) { + if (DebugTable->NormalImage != NULL) { + if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && + (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) { + if ((Address >= DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) && + (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) { + *ImageBase = (UINT32)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase; + *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase); + return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase); + } + } + } + }
+
+ return NULL;
+}
+
+
CHAR8 *gExceptionTypeString[] = {
"Reset",
"Undefined Instruction",
@@ -174,11 +245,41 @@ CommonCExceptionHandler ( }
//
- // Code after here is the default exception handler...
+ // Code after here is the default exception handler... Dump the context
//
- DEBUG ((EFI_D_ERROR, "%a Exception from %08x\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC));
- ASSERT (FALSE);
+ DEBUG ((EFI_D_ERROR, "\n%a Exception from instruction at 0x%08x CPSR 0x%08x\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR));
+ DEBUG_CODE_BEGIN ();
+ CHAR8 *Pdb; + UINT32 ImageBase; + UINT32 PeCoffSizeOfHeader; + UINT32 Offset; +
+ Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);
+ Offset = SystemContext.SystemContextArm->PC - ImageBase;
+ if (Pdb != NULL) {
+ DEBUG ((EFI_D_ERROR, "%a\n", Pdb));
+ //
+ // A PE/COFF image loads its headers into memory so the headers are
+ // included in the linked addressess. ELF and Mach-O images do not
+ // include the headers so the first byte of the image is usually
+ // text (code). If you look at link maps from ELF or Mach-O images
+ // you need to subtact out the size of the PE/COFF header to get
+ // get the offset that matches the link map.
+ //
+ DEBUG ((EFI_D_ERROR, "loadded at 0x%08x (PE/COFF offset) 0x%08x (ELF or Mach-O offset) 0x%08x\n", ImageBase, Offset, Offset - PeCoffSizeOfHeader));
+ }
+ DEBUG_CODE_END ();
+ DEBUG ((EFI_D_ERROR, " R0 0x%08x R1 0x%08x R2 0x%08x R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));
+ DEBUG ((EFI_D_ERROR, " R4 0x%08x R5 0x%08x R6 0x%08x R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));
+ DEBUG ((EFI_D_ERROR, " R8 0x%08x R9 0x%08x R10 0x%08x R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));
+ DEBUG ((EFI_D_ERROR, "R12 0x%08x SP 0x%08x LR 0x%08x PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));
+ DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));
+
+ ASSERT (FALSE);
+// while (TRUE) {
+// CpuSleep ();
+// }
}
@@ -195,6 +296,11 @@ InitializeExceptions ( BOOLEAN Enabled;
EFI_PHYSICAL_ADDRESS Base;
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader); + if (EFI_ERROR (Status)) { + gDebugImageTableHeader = NULL; + } +
//
// Disable interrupts
//
|