]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Core/Pei/Image/Image.c
Fix one bugger in Image.c in PeiCore module to get the correct module name for debug...
[mirror_edk2.git] / EdkModulePkg / Core / Pei / Image / Image.c
CommitLineData
a0b7c09f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Image.c\r
15\r
16Abstract:\r
17\r
18 Pei Core Load Image Support\r
19\r
20--*/\r
21\r
22#include <PeiMain.h>\r
23\r
2ce31132 24\r
25\r
a0b7c09f 26EFI_STATUS\r
27PeiLoadImage (\r
28 IN EFI_PEI_SERVICES **PeiServices,\r
29 IN EFI_FFS_FILE_HEADER *PeimFileHeader,\r
30 OUT VOID **EntryPoint\r
31 )\r
32/*++\r
33\r
34Routine Description:\r
35\r
36 Routine for loading file image.\r
37\r
38Arguments:\r
39\r
40 PeiServices - The PEI core services table.\r
41 PeimFileHeader - Pointer to the FFS file header of the image.\r
42 EntryPoint - Pointer to entry point of specified image file for output.\r
43\r
44Returns:\r
45\r
46 Status - EFI_SUCCESS - Image is successfully loaded.\r
47 EFI_NOT_FOUND - Fail to locate necessary PPI\r
48 Others - Fail to load file.\r
49\r
50--*/\r
51{\r
52 EFI_STATUS Status;\r
53 VOID *Pe32Data;\r
54 EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;\r
a0b7c09f 55 EFI_PHYSICAL_ADDRESS ImageAddress;\r
56 UINT64 ImageSize;\r
57 EFI_PHYSICAL_ADDRESS ImageEntryPoint;\r
58 EFI_TE_IMAGE_HEADER *TEImageHeader;\r
59\r
60 *EntryPoint = NULL;\r
61 TEImageHeader = NULL;\r
62\r
63 //\r
64 // Try to find a PE32 section.\r
65 //\r
84a99d48 66 Status = PeiServicesFfsFindSectionData (\r
a0b7c09f 67 EFI_SECTION_PE32,\r
68 PeimFileHeader,\r
69 &Pe32Data\r
70 );\r
71 //\r
72 // If we didn't find a PE32 section, try to find a TE section.\r
73 //\r
74 if (EFI_ERROR (Status)) {\r
84a99d48 75 Status = PeiServicesFfsFindSectionData (\r
a0b7c09f 76 EFI_SECTION_TE,\r
77 PeimFileHeader,\r
78 (VOID **) &TEImageHeader\r
79 );\r
80 if (EFI_ERROR (Status) || TEImageHeader == NULL) {\r
81 //\r
82 // There was not a PE32 or a TE section, so assume that it's a Compressed section\r
83 // and use the LoadFile\r
84 //\r
84a99d48 85 Status = PeiServicesLocatePpi (\r
a0b7c09f 86 &gEfiPeiFvFileLoaderPpiGuid,\r
87 0,\r
88 NULL,\r
89 (VOID **)&FvLoadFilePpi\r
90 );\r
91 if (EFI_ERROR (Status)) {\r
92 return EFI_NOT_FOUND;\r
93 }\r
94\r
95 Status = FvLoadFilePpi->FvLoadFile (\r
96 FvLoadFilePpi,\r
97 PeimFileHeader,\r
98 &ImageAddress,\r
99 &ImageSize,\r
100 &ImageEntryPoint\r
101 );\r
102\r
103 if (EFI_ERROR (Status)) {\r
104 return EFI_NOT_FOUND;\r
105 }\r
106\r
107 //\r
7c9e5810 108 // Got the entry point from ImageEntryPoint and ImageStartAddress\r
a0b7c09f 109 //\r
7c9e5810 110 Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
2d10530b 111 *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
a0b7c09f 112 } else {\r
113 //\r
114 // Retrieve the entry point from the TE image header\r
115 //\r
116 ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
117 *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
118 TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
119 }\r
120 } else {\r
121 //\r
122 // Retrieve the entry point from the PE/COFF image header\r
123 //\r
124 ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
125 Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);\r
126 if (EFI_ERROR (Status)) {\r
127 return EFI_NOT_FOUND;\r
128 }\r
129 }\r
130\r
131 //\r
132 // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
133 //\r
a61513d6 134 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
2ce31132 135 DEBUG_CODE_BEGIN ();\r
ec412251 136 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
137 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
138 UINTN DirCount;\r
139 UINTN Index;\r
140 UINTN Index1;\r
141 BOOLEAN FileNameFound;\r
142 CHAR8 *AsciiString;\r
143 CHAR8 AsciiBuffer[512];\r
144 VOID *CodeViewEntryPointer;\r
145 INTN TEImageAdjust;\r
146 EFI_IMAGE_DOS_HEADER *DosHeader;\r
147 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
148 UINT32 NumberOfRvaAndSizes;\r
149\r
5b18234d 150 Hdr.Pe32 = NULL;\r
151 if (TEImageHeader == NULL) {\r
152 DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
153 if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
154 //\r
155 // DOS image header is present, so read the PE header after the DOS image header\r
156 //\r
157 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHeader->e_lfanew) & 0x0ffff));\r
158 } else {\r
159 //\r
160 // DOS image header is not present, so PE header is at the image base\r
161 //\r
162 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
163 }\r
ec412251 164 }\r
165\r
166 //\r
167 // Find the codeview info in the image and display the file name\r
168 // being loaded.\r
169 //\r
170 // Per the PE/COFF spec, you can't assume that a given data directory\r
171 // is present in the image. You have to check the NumberOfRvaAndSizes in\r
172 // the optional header to verify a desired directory entry is there.\r
173 //\r
7c9e5810
LG
174 DebugEntry = NULL;\r
175 DirectoryEntry = NULL;\r
176 NumberOfRvaAndSizes = 0;\r
177 TEImageAdjust = 0;\r
178 \r
ec412251 179 if (TEImageHeader == NULL) {\r
180 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
181 // \r
7c9e5810 182 // Use PE32 offset get Debug Directory Entry\r
ec412251 183 //\r
184 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
185 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
7c9e5810
LG
186 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
187 } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
ec412251 188 // \r
7c9e5810 189 // Use PE32+ offset get Debug Directory Entry\r
ec412251 190 //\r
191 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
192 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
7c9e5810
LG
193 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
194 }\r
ec412251 195\r
196 if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
197 DirectoryEntry = NULL;\r
198 DebugEntry = NULL;\r
199 }\r
200 } else {\r
201 if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
202 DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
203 TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
204 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
205 TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
206 TEImageAdjust);\r
a0b7c09f 207 }\r
208 }\r
2ce31132 209\r
ec412251 210 if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
211 for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {\r
212 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
213 if (DebugEntry->SizeOfData > 0) {\r
214 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
215 switch (* (UINT32 *) CodeViewEntryPointer) {\r
216 case CODEVIEW_SIGNATURE_NB10:\r
217 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
218 break;\r
219\r
220 case CODEVIEW_SIGNATURE_RSDS:\r
221 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
222 break;\r
223\r
224 default:\r
225 AsciiString = NULL;\r
226 break;\r
227 }\r
228 if (AsciiString != NULL) {\r
229 FileNameFound = FALSE;\r
b5ace64c 230 for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
ec412251 231 if (AsciiString[Index] == '\\') {\r
232 Index1 = Index;\r
233 FileNameFound = TRUE;\r
234 }\r
235 }\r
236\r
237 if (FileNameFound) {\r
238 for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
239 AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
240 }\r
241 AsciiBuffer[Index - (Index1 + 1)] = 0;\r
242 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
243 break;\r
244 }\r
245 }\r
246 }\r
247 }\r
248 }\r
249 }\r
2ce31132 250 DEBUG_CODE_END ();\r
a0b7c09f 251\r
252 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
253\r
254 return EFI_SUCCESS;\r
255}\r