]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
Import two CPU Exception Handler Library instances: SecPeiCpuExceptionHandler.inf...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / CpuExceptionCommon.c
1 /** @file
2 CPU Exception Hanlder Library common functions.
3
4 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
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 "CpuExceptionCommon.h"
16
17 //
18 // Error code flag indicating whether or not an error code will be
19 // pushed on the stack if an exception occurs.
20 //
21 // 1 means an error code will be pushed, otherwise 0
22 //
23 UINT32 mErrorCodeFlag = 0x00027d00;
24
25 //
26 // Define the maximum message length
27 //
28 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
29
30 /**
31 Prints a message to the serial port.
32
33 @param Format Format string for the message to print.
34 @param ... Variable argument list whose contents are accessed
35 based on the format string specified by Format.
36
37 **/
38 VOID
39 EFIAPI
40 InternalPrintMessage (
41 IN CONST CHAR8 *Format,
42 ...
43 )
44 {
45 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
46 VA_LIST Marker;
47
48 //
49 // Convert the message to an ASCII String
50 //
51 VA_START (Marker, Format);
52 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
53 VA_END (Marker);
54
55 //
56 // Send the print string to a Serial Port
57 //
58 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
59 }
60
61 /**
62 Find and display image base address and return image base and its entry point.
63
64 @return EFI_SUCCESS Image base address.
65 @return 0 Image header cannot be found.
66 **/
67 UINTN
68 FindModuleImageBase (
69 IN UINTN CurrentEip,
70 OUT UINTN *EntryPoint
71 )
72 {
73 UINTN Pe32Data;
74 EFI_IMAGE_DOS_HEADER *DosHdr;
75 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
76 VOID *PdbPointer;
77
78 //
79 // Find Image Base
80 //
81 Pe32Data = CurrentEip & ~(mImageAlignSize - 1);
82 while (Pe32Data != 0) {
83 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
84 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
85 //
86 // DOS image header is present, so read the PE header after the DOS image header.
87 //
88 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
89 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
90 //
91 // It's PE image.
92 //
93 InternalPrintMessage ("!!!! Find PE image ");
94 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);
95 break;
96 }
97 } else {
98 //
99 // DOS image header is not present, TE header is at the image base.
100 //
101 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
102 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&
103 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {
104 //
105 // It's TE image, it TE header and Machine type match
106 //
107 InternalPrintMessage ("!!!! Find TE image ");
108 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
109 break;
110 }
111 }
112
113 //
114 // Not found the image base, check the previous aligned address
115 //
116 Pe32Data -= mImageAlignSize;
117 }
118
119 if (Pe32Data != 0) {
120 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
121 if (PdbPointer != NULL) {
122 InternalPrintMessage ("%a", PdbPointer);
123 } else {
124 InternalPrintMessage ("(No PDB) " );
125 }
126 } else {
127 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");
128 }
129
130 return Pe32Data;
131 }
132