]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Core/Pei/Image/Image.c
Fix one bug in PeiMain to make it output correct ImageStartAddress. And in DxeIplX64P...
[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
2d10530b 108 // Got the entry point from ImageEntryPoint\r
a0b7c09f 109 //\r
2d10530b
LG
110 *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
111 return EFI_SUCCESS;\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
174 DebugEntry = NULL;\r
175 DirectoryEntry = NULL;\r
176 TEImageAdjust = 0;\r
177 if (TEImageHeader == NULL) {\r
178 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
179 // \r
180 // Use PE32 offset\r
181 //\r
182 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
183 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
184 } else {\r
185 // \r
186 // Use PE32+ offset\r
187 //\r
188 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
189 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
190 } \r
191\r
192 if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
193 DirectoryEntry = NULL;\r
194 DebugEntry = NULL;\r
195 }\r
196 } else {\r
197 if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
198 DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
199 TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
200 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
201 TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
202 TEImageAdjust);\r
a0b7c09f 203 }\r
204 }\r
2ce31132 205\r
ec412251 206 if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
207 for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {\r
208 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
209 if (DebugEntry->SizeOfData > 0) {\r
210 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
211 switch (* (UINT32 *) CodeViewEntryPointer) {\r
212 case CODEVIEW_SIGNATURE_NB10:\r
213 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
214 break;\r
215\r
216 case CODEVIEW_SIGNATURE_RSDS:\r
217 AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
218 break;\r
219\r
220 default:\r
221 AsciiString = NULL;\r
222 break;\r
223 }\r
224 if (AsciiString != NULL) {\r
225 FileNameFound = FALSE;\r
226 for (Index = 0, Index1 = 0; (AsciiString[Index] != 0) && (Index < sizeof (AsciiString)); Index++) {\r
227 if (AsciiString[Index] == '\\') {\r
228 Index1 = Index;\r
229 FileNameFound = TRUE;\r
230 }\r
231 }\r
232\r
233 if (FileNameFound) {\r
234 for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
235 AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
236 }\r
237 AsciiBuffer[Index - (Index1 + 1)] = 0;\r
238 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
239 break;\r
240 }\r
241 }\r
242 }\r
243 }\r
244 }\r
245 }\r
2ce31132 246 DEBUG_CODE_END ();\r
a0b7c09f 247\r
248 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
249\r
250 return EFI_SUCCESS;\r
251}\r