]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/Pei/Image/Image.c
Print the warning information for the image without relocation only when load it...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Image / Image.c
... / ...
CommitLineData
1/** @file\r
2 Pei Core Load Image Support\r
3 \r
4Copyright (c) 2006 - 2010, Intel Corporation \r
5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13**/\r
14\r
15#include "PeiMain.h"\r
16\r
17\r
18EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {\r
19 PeiLoadImageLoadImageWrapper\r
20};\r
21\r
22\r
23EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
24 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
25 &gEfiPeiLoadFilePpiGuid,\r
26 &mPeiLoadImagePpi\r
27};\r
28\r
29/**\r
30\r
31 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
32\r
33\r
34 @param FileHandle - The handle to the PE/COFF file\r
35 @param FileOffset - The offset, in bytes, into the file to read\r
36 @param ReadSize - The number of bytes to read from the file starting at FileOffset\r
37 @param Buffer - A pointer to the buffer to read the data into.\r
38\r
39 @return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
40\r
41**/\r
42EFI_STATUS\r
43EFIAPI\r
44PeiImageRead (\r
45 IN VOID *FileHandle,\r
46 IN UINTN FileOffset,\r
47 IN UINTN *ReadSize,\r
48 OUT VOID *Buffer\r
49 )\r
50{\r
51 CHAR8 *Destination8;\r
52 CHAR8 *Source8;\r
53 UINTN Length;\r
54\r
55 Destination8 = Buffer;\r
56 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
57 if (Destination8 != Source8) {\r
58 Length = *ReadSize;\r
59 while ((Length--) > 0) {\r
60 *(Destination8++) = *(Source8++);\r
61 }\r
62 }\r
63\r
64 return EFI_SUCCESS;\r
65}\r
66\r
67/**\r
68\r
69 Support routine to get the Image read file function.\r
70\r
71 @param ImageContext - The context of the image being loaded\r
72\r
73 @retval EFI_SUCCESS - If Image function location is found\r
74\r
75**/\r
76EFI_STATUS\r
77GetImageReadFunction (\r
78 IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
79 )\r
80{\r
81 PEI_CORE_INSTANCE *Private;\r
82 VOID* MemoryBuffer;\r
83\r
84 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
85\r
86 if (!Private->PeiMemoryInstalled || (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) {\r
87 ImageContext->ImageRead = PeiImageRead;\r
88 } else {\r
89 MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
90 ASSERT (MemoryBuffer != NULL);\r
91\r
92 CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
93\r
94 ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
95 }\r
96\r
97 return EFI_SUCCESS;\r
98}\r
99\r
100/**\r
101\r
102 Loads and relocates a PE/COFF image into memory.\r
103 If the image is not relocatable, it will not be loaded into memory and be loaded as XIP image.\r
104\r
105 @param Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated\r
106 @param ImageAddress - The base address of the relocated PE/COFF image\r
107 @param ImageSize - The size of the relocated PE/COFF image\r
108 @param EntryPoint - The entry point of the relocated PE/COFF image\r
109\r
110 @retval EFI_SUCCESS The file was loaded and relocated\r
111 @retval EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file\r
112\r
113**/\r
114EFI_STATUS\r
115LoadAndRelocatePeCoffImage (\r
116 IN VOID *Pe32Data,\r
117 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
118 OUT UINT64 *ImageSize,\r
119 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
120 )\r
121{\r
122 EFI_STATUS Status;\r
123 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
124 PEI_CORE_INSTANCE *Private;\r
125\r
126 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
127\r
128 ZeroMem (&ImageContext, sizeof (ImageContext));\r
129 ImageContext.Handle = Pe32Data;\r
130 Status = GetImageReadFunction (&ImageContext);\r
131\r
132 ASSERT_EFI_ERROR (Status);\r
133\r
134 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
135 if (EFI_ERROR (Status)) {\r
136 return Status;\r
137 }\r
138 //\r
139 // When Image has no reloc section, it can't be relocated into memory.\r
140 //\r
141 if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
142 DEBUG ((EFI_D_INFO, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
143 }\r
144\r
145 //\r
146 // Set default base address to current image address.\r
147 //\r
148 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data;\r
149 \r
150 //\r
151 // Allocate Memory for the image when memory is ready, boot mode is not S3, and image is relocatable.\r
152 //\r
153 if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
154 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
155 ASSERT (ImageContext.ImageAddress != 0);\r
156 if (ImageContext.ImageAddress == 0) {\r
157 return EFI_OUT_OF_RESOURCES;\r
158 }\r
159 \r
160 //\r
161 // Skip the reserved space for the stripped PeHeader when load TeImage into memory.\r
162 //\r
163 if (ImageContext.IsTeImage) {\r
164 ImageContext.ImageAddress = ImageContext.ImageAddress + \r
165 ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -\r
166 sizeof (EFI_TE_IMAGE_HEADER);\r
167 }\r
168 }\r
169\r
170 //\r
171 // Load the image to our new buffer\r
172 //\r
173 Status = PeCoffLoaderLoadImage (&ImageContext);\r
174 if (EFI_ERROR (Status)) {\r
175 return Status;\r
176 }\r
177 //\r
178 // Relocate the image in our new buffer\r
179 //\r
180 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
181 if (EFI_ERROR (Status)) {\r
182 return Status;\r
183 }\r
184\r
185 //\r
186 // Flush the instruction cache so the image data is written before we execute it\r
187 //\r
188 if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
189 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
190 }\r
191\r
192 *ImageAddress = ImageContext.ImageAddress;\r
193 *ImageSize = ImageContext.ImageSize;\r
194 *EntryPoint = ImageContext.EntryPoint;\r
195\r
196 return EFI_SUCCESS;\r
197}\r
198\r
199/**\r
200 Loads a PEIM into memory for subsequent execution. If there are compressed \r
201 images or images that need to be relocated into memory for performance reasons, \r
202 this service performs that transformation.\r
203\r
204 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
205 @param FileHandle Pointer to the FFS file header of the image.\r
206 @param ImageAddressArg Pointer to PE/TE image.\r
207 @param ImageSizeArg Size of PE/TE image.\r
208 @param EntryPoint Pointer to entry point of specified image file for output.\r
209 @param AuthenticationState - Pointer to attestation authentication state of image.\r
210\r
211 @retval EFI_SUCCESS Image is successfully loaded.\r
212 @retval EFI_NOT_FOUND Fail to locate necessary PPI.\r
213 @retval EFI_UNSUPPORTED Image Machine Type is not supported.\r
214\r
215**/\r
216EFI_STATUS\r
217PeiLoadImageLoadImage (\r
218 IN CONST EFI_PEI_SERVICES **PeiServices,\r
219 IN EFI_PEI_FILE_HANDLE FileHandle,\r
220 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
221 OUT UINT64 *ImageSizeArg, OPTIONAL\r
222 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
223 OUT UINT32 *AuthenticationState\r
224 )\r
225{\r
226 EFI_STATUS Status;\r
227 VOID *Pe32Data;\r
228 EFI_PHYSICAL_ADDRESS ImageAddress;\r
229 UINT64 ImageSize;\r
230 EFI_PHYSICAL_ADDRESS ImageEntryPoint;\r
231 UINT16 Machine;\r
232 EFI_SECTION_TYPE SearchType1;\r
233 EFI_SECTION_TYPE SearchType2;\r
234\r
235 *EntryPoint = 0;\r
236 ImageSize = 0;\r
237 *AuthenticationState = 0;\r
238\r
239 if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {\r
240 SearchType1 = EFI_SECTION_TE;\r
241 SearchType2 = EFI_SECTION_PE32;\r
242 } else {\r
243 SearchType1 = EFI_SECTION_PE32;\r
244 SearchType2 = EFI_SECTION_TE;\r
245 }\r
246\r
247 //\r
248 // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst \r
249 // is true, TE will be searched first).\r
250 //\r
251 Status = PeiServicesFfsFindSectionData (\r
252 SearchType1,\r
253 FileHandle,\r
254 &Pe32Data\r
255 );\r
256 //\r
257 // If we didn't find a first exe section, try to find the second exe section.\r
258 //\r
259 if (EFI_ERROR (Status)) {\r
260 Status = PeiServicesFfsFindSectionData (\r
261 SearchType2,\r
262 FileHandle,\r
263 &Pe32Data\r
264 );\r
265 if (EFI_ERROR (Status)) {\r
266 //\r
267 // PEI core only carry the loader function fro TE and PE32 executables\r
268 // If this two section does not exist, just return.\r
269 //\r
270 return Status;\r
271 }\r
272 }\r
273 \r
274 //\r
275 // If memory is installed, perform the shadow operations\r
276 //\r
277 Status = LoadAndRelocatePeCoffImage (\r
278 Pe32Data,\r
279 &ImageAddress,\r
280 &ImageSize,\r
281 &ImageEntryPoint\r
282 );\r
283\r
284 ASSERT_EFI_ERROR (Status);\r
285\r
286\r
287 if (EFI_ERROR (Status)) {\r
288 return Status;\r
289 }\r
290\r
291 //\r
292 // Got the entry point from the loaded Pe32Data\r
293 //\r
294 Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
295 *EntryPoint = ImageEntryPoint;\r
296 \r
297 Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
298 \r
299 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
300 if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {\r
301 return EFI_UNSUPPORTED;\r
302 }\r
303 }\r
304\r
305 if (ImageAddressArg != NULL) {\r
306 *ImageAddressArg = ImageAddress;\r
307 }\r
308\r
309 if (ImageSizeArg != NULL) {\r
310 *ImageSizeArg = ImageSize;\r
311 }\r
312 \r
313 DEBUG_CODE_BEGIN ();\r
314 CHAR8 *AsciiString;\r
315 CHAR8 AsciiBuffer[512];\r
316 INT32 Index;\r
317 INT32 Index1;\r
318\r
319 //\r
320 // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
321 //\r
322 if (Machine != EFI_IMAGE_MACHINE_IA64) {\r
323 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));\r
324 } else {\r
325 //\r
326 // For IPF Image, the real entry point should be print.\r
327 //\r
328 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));\r
329 }\r
330 \r
331 //\r
332 // Print Module Name by PeImage PDB file name.\r
333 //\r
334 AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data);\r
335 \r
336 if (AsciiString != NULL) {\r
337 for (Index = (INT32) AsciiStrLen (AsciiString) - 1; Index >= 0; Index --) {\r
338 if (AsciiString[Index] == '\\') {\r
339 break;\r
340 }\r
341 }\r
342\r
343 if (Index != 0) {\r
344 for (Index1 = 0; AsciiString[Index + 1 + Index1] != '.'; Index1 ++) {\r
345 AsciiBuffer [Index1] = AsciiString[Index + 1 + Index1];\r
346 }\r
347 AsciiBuffer [Index1] = '\0';\r
348 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
349 }\r
350 }\r
351\r
352 DEBUG_CODE_END ();\r
353\r
354 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
355\r
356 return EFI_SUCCESS;\r
357\r
358}\r
359\r
360\r
361/**\r
362 The wrapper function of PeiLoadImageLoadImage().\r
363\r
364 @param This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
365 @param FileHandle - Pointer to the FFS file header of the image.\r
366 @param ImageAddressArg - Pointer to PE/TE image.\r
367 @param ImageSizeArg - Size of PE/TE image.\r
368 @param EntryPoint - Pointer to entry point of specified image file for output.\r
369 @param AuthenticationState - Pointer to attestation authentication state of image.\r
370\r
371 @return Status of PeiLoadImageLoadImage().\r
372\r
373**/\r
374EFI_STATUS\r
375EFIAPI\r
376PeiLoadImageLoadImageWrapper (\r
377 IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
378 IN EFI_PEI_FILE_HANDLE FileHandle,\r
379 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
380 OUT UINT64 *ImageSizeArg, OPTIONAL\r
381 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
382 OUT UINT32 *AuthenticationState\r
383 )\r
384{\r
385 return PeiLoadImageLoadImage (\r
386 GetPeiServicesTablePointer (),\r
387 FileHandle,\r
388 ImageAddressArg,\r
389 ImageSizeArg,\r
390 EntryPoint,\r
391 AuthenticationState\r
392 );\r
393}\r
394\r
395/**\r
396 Check whether the input image has the relocation.\r
397\r
398 @param Pe32Data Pointer to the PE/COFF or TE image.\r
399\r
400 @retval TRUE Relocation is stripped.\r
401 @retval FALSE Relocation is not stripped.\r
402\r
403**/\r
404BOOLEAN\r
405RelocationIsStrip (\r
406 IN VOID *Pe32Data\r
407 )\r
408{\r
409 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
410 EFI_IMAGE_DOS_HEADER *DosHdr;\r
411\r
412 ASSERT (Pe32Data != NULL);\r
413\r
414 DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
415 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
416 //\r
417 // DOS image header is present, so read the PE header after the DOS image header.\r
418 //\r
419 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
420 } else {\r
421 //\r
422 // DOS image header is not present, so PE header is at the image base.\r
423 //\r
424 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
425 }\r
426\r
427 //\r
428 // Three cases with regards to relocations:\r
429 // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable\r
430 // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable\r
431 // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but\r
432 // has no base relocs to apply\r
433 // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.\r
434 //\r
435 // Look at the file header to determine if relocations have been stripped, and\r
436 // save this info in the image context for later use.\r
437 //\r
438 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
439 if ((Hdr.Te->DataDirectory[0].Size == 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {\r
440 return TRUE;\r
441 } else {\r
442 return FALSE;\r
443 }\r
444 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
445 if ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {\r
446 return TRUE;\r
447 } else {\r
448 return FALSE;\r
449 }\r
450 }\r
451\r
452 return FALSE;\r
453}\r
454\r
455/**\r
456 Routine to load image file for subsequent execution by LoadFile Ppi.\r
457 If any LoadFile Ppi is not found, the build-in support function for the PE32+/TE \r
458 XIP image format is used.\r
459\r
460 @param PeiServices - An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
461 @param FileHandle - Pointer to the FFS file header of the image.\r
462 @param PeimState - The dispatch state of the input PEIM handle.\r
463 @param EntryPoint - Pointer to entry point of specified image file for output.\r
464 @param AuthenticationState - Pointer to attestation authentication state of image.\r
465\r
466 @retval EFI_SUCCESS - Image is successfully loaded.\r
467 @retval EFI_NOT_FOUND - Fail to locate necessary PPI\r
468 @retval Others - Fail to load file.\r
469\r
470**/\r
471EFI_STATUS\r
472PeiLoadImage (\r
473 IN CONST EFI_PEI_SERVICES **PeiServices,\r
474 IN EFI_PEI_FILE_HANDLE FileHandle,\r
475 IN UINT8 PeimState,\r
476 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
477 OUT UINT32 *AuthenticationState\r
478 )\r
479{\r
480 EFI_STATUS PpiStatus;\r
481 EFI_STATUS Status;\r
482 UINTN Index;\r
483 EFI_PEI_LOAD_FILE_PPI *LoadFile;\r
484 EFI_PHYSICAL_ADDRESS ImageAddress;\r
485 UINT64 ImageSize;\r
486 BOOLEAN IsStrip;\r
487\r
488 IsStrip = FALSE;\r
489 //\r
490 // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.\r
491 // one at a time, until one reports EFI_SUCCESS.\r
492 //\r
493 Index = 0;\r
494 do {\r
495 PpiStatus = PeiServicesLocatePpi (\r
496 &gEfiPeiLoadFilePpiGuid,\r
497 Index,\r
498 NULL,\r
499 (VOID **)&LoadFile\r
500 );\r
501 if (!EFI_ERROR (PpiStatus)) {\r
502 Status = LoadFile->LoadFile (\r
503 LoadFile, \r
504 FileHandle, \r
505 &ImageAddress, \r
506 &ImageSize,\r
507 EntryPoint,\r
508 AuthenticationState\r
509 );\r
510 if (!EFI_ERROR (Status)) {\r
511 //\r
512 // The shadowed PEIM must be relocatable.\r
513 //\r
514 if (PeimState == PEIM_STATE_REGISITER_FOR_SHADOW) {\r
515 IsStrip = RelocationIsStrip ((VOID *) (UINTN) ImageAddress);\r
516 ASSERT (!IsStrip);\r
517 if (IsStrip) {\r
518 return EFI_UNSUPPORTED;\r
519 }\r
520 }\r
521\r
522 //\r
523 // The image to be started must have the machine type supported by PeiCore.\r
524 //\r
525 ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress)));\r
526 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) {\r
527 return EFI_UNSUPPORTED;\r
528 }\r
529 return Status;\r
530 }\r
531 }\r
532 Index++;\r
533 } while (!EFI_ERROR (PpiStatus));\r
534\r
535 return PpiStatus;\r
536}\r
537\r
538\r
539/**\r
540\r
541 Install Pei Load File PPI.\r
542\r
543\r
544 @param PrivateData - Pointer to PEI_CORE_INSTANCE.\r
545 @param OldCoreData - Pointer to PEI_CORE_INSTANCE.\r
546\r
547**/\r
548VOID\r
549InitializeImageServices (\r
550 IN PEI_CORE_INSTANCE *PrivateData,\r
551 IN PEI_CORE_INSTANCE *OldCoreData\r
552 )\r
553{\r
554 if (OldCoreData == NULL) {\r
555 //\r
556 // The first time we are XIP (running from FLASH). We need to remember the\r
557 // FLASH address so we can reinstall the memory version that runs faster\r
558 //\r
559 PrivateData->XipLoadFile = &gPpiLoadFilePpiList;\r
560 PeiServicesInstallPpi (PrivateData->XipLoadFile);\r
561 } else {\r
562 //\r
563 // 2nd time we are running from memory so replace the XIP version with the \r
564 // new memory version. \r
565 //\r
566 PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); \r
567 }\r
568}\r
569\r
570\r
571\r
572\r