]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
BaseTools/Upt: Add a BOM check for UNI file and fix some help message error
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / CpuExceptionCommon.c
CommitLineData
8f07f895 1/** @file\r
e3644786 2 CPU Exception Handler Library common functions.\r
8f07f895 3\r
9e2364ef 4 Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
8f07f895 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "CpuExceptionCommon.h"\r
16\r
17//\r
e41aad15 18// Error code flag indicating whether or not an error code will be\r
8f07f895 19// pushed on the stack if an exception occurs.\r
20//\r
21// 1 means an error code will be pushed, otherwise 0\r
22//\r
e41aad15
JF
23CONST UINT32 mErrorCodeFlag = 0x00027d00;\r
24RESERVED_VECTORS_DATA *mReservedVectors = NULL;\r
8f07f895 25\r
26//\r
27// Define the maximum message length \r
28//\r
29#define MAX_DEBUG_MESSAGE_LENGTH 0x100\r
30\r
31/**\r
32 Prints a message to the serial port.\r
33\r
34 @param Format Format string for the message to print.\r
35 @param ... Variable argument list whose contents are accessed \r
36 based on the format string specified by Format.\r
37\r
38**/\r
39VOID\r
40EFIAPI\r
41InternalPrintMessage (\r
42 IN CONST CHAR8 *Format,\r
43 ...\r
44 )\r
45{\r
46 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
47 VA_LIST Marker;\r
48\r
49 //\r
50 // Convert the message to an ASCII String\r
51 //\r
52 VA_START (Marker, Format);\r
53 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
54 VA_END (Marker);\r
55\r
56 //\r
57 // Send the print string to a Serial Port \r
58 //\r
59 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));\r
60}\r
61\r
62/**\r
63 Find and display image base address and return image base and its entry point.\r
64 \r
a9c7ab95 65 @param CurrentEip Current instruction pointer.\r
66 @param EntryPoint Return module entry point if module header is found.\r
67 \r
68 @return !0 Image base address.\r
69 @return 0 Image header cannot be found.\r
8f07f895 70**/\r
71UINTN \r
72FindModuleImageBase (\r
73 IN UINTN CurrentEip,\r
74 OUT UINTN *EntryPoint\r
75 )\r
76{\r
77 UINTN Pe32Data;\r
78 EFI_IMAGE_DOS_HEADER *DosHdr;\r
79 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
80 VOID *PdbPointer;\r
81\r
82 //\r
83 // Find Image Base\r
84 //\r
85 Pe32Data = CurrentEip & ~(mImageAlignSize - 1);\r
86 while (Pe32Data != 0) {\r
87 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
88 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
89 //\r
90 // DOS image header is present, so read the PE header after the DOS image header.\r
91 //\r
92 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
9e2364ef
JF
93 //\r
94 // Make sure PE header address does not overflow and is less than the initial address.\r
95 //\r
96 if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CurrentEip)) {\r
97 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
98 //\r
99 // It's PE image.\r
100 //\r
101 InternalPrintMessage ("!!!! Find PE image ");\r
102 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);\r
103 break;\r
104 }\r
8f07f895 105 }\r
106 } else {\r
107 //\r
108 // DOS image header is not present, TE header is at the image base.\r
109 //\r
110 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
111 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&\r
112 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {\r
113 //\r
114 // It's TE image, it TE header and Machine type match\r
115 //\r
116 InternalPrintMessage ("!!!! Find TE image ");\r
117 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
118 break;\r
119 }\r
120 }\r
121\r
122 //\r
123 // Not found the image base, check the previous aligned address\r
124 // \r
125 Pe32Data -= mImageAlignSize;\r
126 }\r
127\r
128 if (Pe32Data != 0) {\r
129 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);\r
130 if (PdbPointer != NULL) {\r
131 InternalPrintMessage ("%a", PdbPointer);\r
132 } else {\r
133 InternalPrintMessage ("(No PDB) " );\r
134 }\r
135 } else {\r
136 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");\r
137 }\r
138\r
139 return Pe32Data;\r
140}\r
141\r
e41aad15
JF
142/**\r
143 Read and save reserved vector information\r
144 \r
145 @param[in] VectorInfo Pointer to reserved vector list.\r
146 @param[out] ReservedVector Pointer to reserved vector data buffer.\r
147 @param[in] VectorCount Vector number to be updated.\r
148 \r
149 @return EFI_SUCCESS Read and save vector info successfully.\r
150 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
151\r
152**/\r
153EFI_STATUS\r
154ReadAndVerifyVectorInfo (\r
155 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,\r
156 OUT RESERVED_VECTORS_DATA *ReservedVector,\r
157 IN UINTN VectorCount\r
158 )\r
159{\r
160 while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {\r
161 if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {\r
162 //\r
163 // If vector attrubute is invalid\r
164 //\r
165 return EFI_INVALID_PARAMETER;\r
166 }\r
167 if (VectorInfo->VectorNumber < VectorCount) {\r
168 ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;\r
169 }\r
170 VectorInfo ++;\r
171 }\r
172 return EFI_SUCCESS;\r
173}