]> git.proxmox.com Git - mirror_edk2.git/blob - 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
1 /** @file
2 CPU Exception Handler Library common functions.
3
4 Copyright (c) 2012 - 2014, 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 CONST UINT32 mErrorCodeFlag = 0x00027d00;
24 RESERVED_VECTORS_DATA *mReservedVectors = NULL;
25
26 //
27 // Define the maximum message length
28 //
29 #define MAX_DEBUG_MESSAGE_LENGTH 0x100
30
31 /**
32 Prints a message to the serial port.
33
34 @param Format Format string for the message to print.
35 @param ... Variable argument list whose contents are accessed
36 based on the format string specified by Format.
37
38 **/
39 VOID
40 EFIAPI
41 InternalPrintMessage (
42 IN CONST CHAR8 *Format,
43 ...
44 )
45 {
46 CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
47 VA_LIST Marker;
48
49 //
50 // Convert the message to an ASCII String
51 //
52 VA_START (Marker, Format);
53 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
54 VA_END (Marker);
55
56 //
57 // Send the print string to a Serial Port
58 //
59 SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
60 }
61
62 /**
63 Find and display image base address and return image base and its entry point.
64
65 @param CurrentEip Current instruction pointer.
66 @param EntryPoint Return module entry point if module header is found.
67
68 @return !0 Image base address.
69 @return 0 Image header cannot be found.
70 **/
71 UINTN
72 FindModuleImageBase (
73 IN UINTN CurrentEip,
74 OUT UINTN *EntryPoint
75 )
76 {
77 UINTN Pe32Data;
78 EFI_IMAGE_DOS_HEADER *DosHdr;
79 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
80 VOID *PdbPointer;
81
82 //
83 // Find Image Base
84 //
85 Pe32Data = CurrentEip & ~(mImageAlignSize - 1);
86 while (Pe32Data != 0) {
87 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
88 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
89 //
90 // DOS image header is present, so read the PE header after the DOS image header.
91 //
92 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
93 //
94 // Make sure PE header address does not overflow and is less than the initial address.
95 //
96 if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CurrentEip)) {
97 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
98 //
99 // It's PE image.
100 //
101 InternalPrintMessage ("!!!! Find PE image ");
102 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff);
103 break;
104 }
105 }
106 } else {
107 //
108 // DOS image header is not present, TE header is at the image base.
109 //
110 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
111 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&
112 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) {
113 //
114 // It's TE image, it TE header and Machine type match
115 //
116 InternalPrintMessage ("!!!! Find TE image ");
117 *EntryPoint = (UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
118 break;
119 }
120 }
121
122 //
123 // Not found the image base, check the previous aligned address
124 //
125 Pe32Data -= mImageAlignSize;
126 }
127
128 if (Pe32Data != 0) {
129 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
130 if (PdbPointer != NULL) {
131 InternalPrintMessage ("%a", PdbPointer);
132 } else {
133 InternalPrintMessage ("(No PDB) " );
134 }
135 } else {
136 InternalPrintMessage ("!!!! Can't find image information. !!!!\n");
137 }
138
139 return Pe32Data;
140 }
141
142 /**
143 Read and save reserved vector information
144
145 @param[in] VectorInfo Pointer to reserved vector list.
146 @param[out] ReservedVector Pointer to reserved vector data buffer.
147 @param[in] VectorCount Vector number to be updated.
148
149 @return EFI_SUCCESS Read and save vector info successfully.
150 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
151
152 **/
153 EFI_STATUS
154 ReadAndVerifyVectorInfo (
155 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,
156 OUT RESERVED_VECTORS_DATA *ReservedVector,
157 IN UINTN VectorCount
158 )
159 {
160 while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
161 if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {
162 //
163 // If vector attrubute is invalid
164 //
165 return EFI_INVALID_PARAMETER;
166 }
167 if (VectorInfo->VectorNumber < VectorCount) {
168 ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;
169 }
170 VectorInfo ++;
171 }
172 return EFI_SUCCESS;
173 }