1 /** @file
2 
3   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4 
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <Uefi.h>
16 #include <Library/PeCoffGetEntryPointLib.h>
17 #include <Library/UefiLib.h>
18 
19 #include <Guid/DebugImageInfoTable.h>
20 
21 extern EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader;
22 
23 /**
24   The constructor function caches EFI Debug table information for use in the exception handler.
25 
26 
27   @param  ImageHandle   The firmware allocated handle for the EFI image.
28   @param  SystemTable   A pointer to the EFI System Table.
29 
30   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
31 
32 **/
33 EFI_STATUS
34 EFIAPI
DefaultExceptionHandlerConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)35 DefaultExceptionHandlerConstructor (
36   IN EFI_HANDLE                ImageHandle,
37   IN EFI_SYSTEM_TABLE          *SystemTable
38   )
39 {
40   EFI_STATUS  Status;
41 
42   Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
43   if (EFI_ERROR (Status)) {
44     gDebugImageTableHeader = NULL;
45   }
46   return Status;
47 }
48 
49 /**
50   Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image
51   it came from. As long as the PE/COFF image contains a debug directory entry a
52   string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF
53   image. Microsoft tools contain a pointer to the PDB file that contains the debug information.
54 
55   @param  FaultAddress         Address to find PE/COFF image for.
56   @param  ImageBase            Return load address of found image
57   @param  PeCoffSizeOfHeaders  Return the size of the PE/COFF header for the image that was found
58 
59   @retval NULL                 FaultAddress not in a loaded PE/COFF image.
60   @retval                      Path and file name of PE/COFF image.
61 
62 **/
63 CHAR8 *
GetImageName(IN UINTN FaultAddress,OUT UINTN * ImageBase,OUT UINTN * PeCoffSizeOfHeaders)64 GetImageName (
65   IN  UINTN  FaultAddress,
66   OUT UINTN  *ImageBase,
67   OUT UINTN  *PeCoffSizeOfHeaders
68   )
69 {
70   EFI_DEBUG_IMAGE_INFO  *DebugTable;
71   UINTN                 Entry;
72   CHAR8                 *Address;
73 
74   DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
75   if (DebugTable == NULL) {
76     return NULL;
77   }
78 
79   Address = (CHAR8 *)(UINTN)FaultAddress;
80   for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) {
81     if (DebugTable->NormalImage != NULL) {
82       if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
83           (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
84         if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&
85             (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) {
86           *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
87           *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);
88           return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
89         }
90       }
91     }
92   }
93 
94   return NULL;
95 }
96 
97