]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
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
24\r
25\r
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
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
66 Status = PeiServicesFfsFindSectionData (\r
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
75 Status = PeiServicesFfsFindSectionData (\r
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
85 Status = PeiServicesLocatePpi (\r
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
108 // Got the entry point from ImageEntryPoint and ImageStartAddress\r
109 //\r
110 Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
111 *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
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
134 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
135 DEBUG_CODE_BEGIN ();\r
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
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
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
174 DebugEntry = NULL;\r
175 DirectoryEntry = NULL;\r
176 NumberOfRvaAndSizes = 0;\r
177 TEImageAdjust = 0;\r
178 \r
179 if (TEImageHeader == NULL) {\r
180 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
181 // \r
182 // Use PE32 offset get Debug Directory Entry\r
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
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
188 // \r
189 // Use PE32+ offset get Debug Directory Entry\r
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
193 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
194 }\r
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
207 }\r
208 }\r
209\r
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
230 for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
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
250 DEBUG_CODE_END ();\r
251\r
252 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
253\r
254 return EFI_SUCCESS;\r
255}\r