TianoCore EDK2 master
Loading...
Searching...
No Matches
Image.c
Go to the documentation of this file.
1
9#include "PeiMain.h"
10
11EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {
13};
14
15EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
16 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
17 &gEfiPeiLoadFilePpiGuid,
18 &mPeiLoadImagePpi
19};
20
35EFIAPI
37 IN VOID *FileHandle,
38 IN UINTN FileOffset,
39 IN UINTN *ReadSize,
40 OUT VOID *Buffer
41 )
42{
43 CHAR8 *Destination8;
44 CHAR8 *Source8;
45
46 Destination8 = Buffer;
47 Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset);
48 if (Destination8 != Source8) {
49 CopyMem (Destination8, Source8, *ReadSize);
50 }
51
52 return EFI_SUCCESS;
53}
54
69 IN PEI_CORE_INSTANCE *Private,
70 IN EFI_PHYSICAL_ADDRESS ImageBase,
71 IN UINT32 ImageSize
72 )
73{
74 UINT32 DxeCodePageNumber;
75 UINT64 ReservedCodeSize;
76 EFI_PHYSICAL_ADDRESS PeiCodeBase;
77 UINT32 BaseOffsetPageNumber;
78 UINT32 TopOffsetPageNumber;
79 UINT32 Index;
80 UINT64 *MemoryUsageBitMap;
81
82 //
83 // The reserved code range includes RuntimeCodePage range, Boot time code range and PEI code range.
84 //
85 DxeCodePageNumber = PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber);
86 DxeCodePageNumber += PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber);
87 ReservedCodeSize = EFI_PAGES_TO_SIZE (DxeCodePageNumber + PcdGet32 (PcdLoadFixAddressPeiCodePageNumber));
88 PeiCodeBase = Private->LoadModuleAtFixAddressTopAddress - ReservedCodeSize;
89
90 //
91 // Test the memory range for loading the image in the PEI code range.
92 //
93 if (((Private->LoadModuleAtFixAddressTopAddress - EFI_PAGES_TO_SIZE (DxeCodePageNumber)) < (ImageBase + ImageSize)) ||
94 (PeiCodeBase > ImageBase))
95 {
96 return EFI_NOT_FOUND;
97 }
98
99 //
100 // Test if the memory is available or not.
101 //
102 MemoryUsageBitMap = Private->PeiCodeMemoryRangeUsageBitMap;
103 BaseOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase - PeiCodeBase));
104 TopOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase + ImageSize - PeiCodeBase));
105 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
106 if ((MemoryUsageBitMap[Index / 64] & LShiftU64 (1, (Index % 64))) != 0) {
107 //
108 // This page is already used.
109 //
110 return EFI_NOT_FOUND;
111 }
112 }
113
114 //
115 // Being here means the memory range is available. So mark the bits for the memory range
116 //
117 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
118 MemoryUsageBitMap[Index / 64] |= LShiftU64 (1, (Index % 64));
119 }
120
121 return EFI_SUCCESS;
122}
123
139 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
140 IN PEI_CORE_INSTANCE *Private
141 )
142{
143 UINTN SectionHeaderOffset;
144 EFI_STATUS Status;
145 EFI_IMAGE_SECTION_HEADER SectionHeader;
147 EFI_PHYSICAL_ADDRESS FixLoadingAddress;
148 UINT16 Index;
149 UINTN Size;
150 UINT16 NumberOfSections;
151 UINT64 ValueInSectionHeader;
152
153 FixLoadingAddress = 0;
154 Status = EFI_NOT_FOUND;
155
156 //
157 // Get PeHeader pointer
158 //
159 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
160 if (ImageContext->IsTeImage) {
161 //
162 // for TE image, the fix loading address is saved in first section header that doesn't point
163 // to code section.
164 //
165 SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER);
166 NumberOfSections = ImgHdr->Te.NumberOfSections;
167 } else {
168 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
169 sizeof (UINT32) +
170 sizeof (EFI_IMAGE_FILE_HEADER) +
171 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
172 NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
173 }
174
175 //
176 // Get base address from the first section header that doesn't point to code section.
177 //
178 for (Index = 0; Index < NumberOfSections; Index++) {
179 //
180 // Read section header from file
181 //
182 Size = sizeof (EFI_IMAGE_SECTION_HEADER);
183 Status = ImageContext->ImageRead (
184 ImageContext->Handle,
185 SectionHeaderOffset,
186 &Size,
187 &SectionHeader
188 );
189 if (EFI_ERROR (Status)) {
190 return Status;
191 }
192
193 Status = EFI_NOT_FOUND;
194
195 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
196 //
197 // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
198 // that doesn't point to code section in image header, as well as ImageBase field of image header. A notable thing is
199 // that for PEIM, the value in ImageBase field may not be equal to the value in PointerToRelocations & PointerToLineNumbers because
200 // for XIP PEIM, ImageBase field holds the image base address running on the Flash. And PointerToRelocations & PointerToLineNumbers
201 // hold the image base address when it is shadow to the memory. And there is an assumption that when the feature is enabled, if a
202 // module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers fields should NOT be Zero, or
203 // else, these 2 fields should be set to Zero
204 //
205 ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
206 if (ValueInSectionHeader != 0) {
207 //
208 // Found first section header that doesn't point to code section.
209 //
210 if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) > 0) {
211 //
212 // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field
213 // hold the absolute address of image base running in memory
214 //
215 FixLoadingAddress = ValueInSectionHeader;
216 } else {
217 //
218 // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field
219 // hold the offset relative to a platform-specific top address.
220 //
221 FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + (INT64)ValueInSectionHeader);
222 }
223
224 //
225 // Check if the memory range is available.
226 //
227 Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, (UINT32)ImageContext->ImageSize);
228 if (!EFI_ERROR (Status)) {
229 //
230 // The assigned address is valid. Return the specified loading address
231 //
232 ImageContext->ImageAddress = FixLoadingAddress;
233 }
234 }
235
236 break;
237 }
238
239 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
240 }
241
242 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
243 return Status;
244}
245
266 IN EFI_PEI_FILE_HANDLE FileHandle,
267 IN VOID *Pe32Data,
268 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
269 OUT UINT64 *ImageSize,
270 OUT EFI_PHYSICAL_ADDRESS *EntryPoint
271 )
272{
273 EFI_STATUS Status;
274 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
275 PEI_CORE_INSTANCE *Private;
276 UINT64 AlignImageSize;
277 BOOLEAN IsXipImage;
278 EFI_STATUS ReturnStatus;
279 BOOLEAN IsS3Boot;
280 BOOLEAN IsPeiModule;
281 BOOLEAN IsRegisterForShadow;
283
285
286 ReturnStatus = EFI_SUCCESS;
287 IsXipImage = FALSE;
288 ZeroMem (&ImageContext, sizeof (ImageContext));
289 ImageContext.Handle = Pe32Data;
290 ImageContext.ImageRead = PeiImageRead;
291
292 Status = PeCoffLoaderGetImageInfo (&ImageContext);
293 if (EFI_ERROR (Status)) {
294 return Status;
295 }
296
297 //
298 // Initialize local IsS3Boot and IsRegisterForShadow variable
299 //
300 IsS3Boot = FALSE;
301 if (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) {
302 IsS3Boot = TRUE;
303 }
304
305 IsRegisterForShadow = FALSE;
306 if ( (Private->CurrentFileHandle == FileHandle)
307 && (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] == PEIM_STATE_REGISTER_FOR_SHADOW))
308 {
309 IsRegisterForShadow = TRUE;
310 }
311
312 //
313 // XIP image that ImageAddress is same to Image handle.
314 //
315 if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
316 IsXipImage = TRUE;
317 }
318
319 //
320 // Get file type first
321 //
322 Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
323 ASSERT_EFI_ERROR (Status);
324
325 //
326 // Check whether the file type is PEI module.
327 //
328 IsPeiModule = FALSE;
329 if ((FileInfo.FileType == EFI_FV_FILETYPE_PEI_CORE) ||
330 (FileInfo.FileType == EFI_FV_FILETYPE_PEIM) ||
331 (FileInfo.FileType == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER))
332 {
333 IsPeiModule = TRUE;
334 }
335
336 //
337 // When Image has no reloc section, it can't be relocated into memory.
338 //
339 if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) &&
340 ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
341 (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
342 (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
343 )
344 {
345 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data));
346 }
347
348 //
349 // Set default base address to current image address.
350 //
351 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
352
353 //
354 // Allocate Memory for the image when memory is ready, and image is relocatable.
355 // On normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory.
356 // On S3 boot, PcdShadowPeimOnS3Boot decides whether load PEIM or PeiCore into memory.
357 //
358 if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) &&
359 ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
360 (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
361 (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
362 )
363 {
364 //
365 // Allocate more buffer to avoid buffer overflow.
366 //
367 if (ImageContext.IsTeImage) {
368 AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
369 } else {
370 AlignImageSize = ImageContext.ImageSize;
371 }
372
373 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
374 AlignImageSize += ImageContext.SectionAlignment;
375 }
376
377 if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
378 Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext, Private);
379 if (EFI_ERROR (Status)) {
380 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
381 //
382 // The PEIM is not assigned valid address, try to allocate page to load it.
383 //
384 Status = PeiServicesAllocatePages (
386 EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
387 &ImageContext.ImageAddress
388 );
389 }
390 } else {
391 Status = PeiServicesAllocatePages (
393 EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
394 &ImageContext.ImageAddress
395 );
396 }
397
398 if (!EFI_ERROR (Status)) {
399 //
400 // Adjust the Image Address to make sure it is section alignment.
401 //
402 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
403 ImageContext.ImageAddress =
404 (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
405 ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
406 }
407
408 //
409 // Fix alignment requirement when Load IPF TeImage into memory.
410 // Skip the reserved space for the stripped PeHeader when load TeImage into memory.
411 //
412 if (ImageContext.IsTeImage) {
413 ImageContext.ImageAddress = ImageContext.ImageAddress +
414 ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize -
415 sizeof (EFI_TE_IMAGE_HEADER);
416 }
417 } else {
418 //
419 // No enough memory resource.
420 //
421 if (IsXipImage) {
422 //
423 // XIP image can still be invoked.
424 //
425 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
426 ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
427 } else {
428 //
429 // Non XIP image can't be loaded because no enough memory is allocated.
430 //
431 ASSERT (FALSE);
432 return EFI_OUT_OF_RESOURCES;
433 }
434 }
435 }
436
437 //
438 // Load the image to our new buffer
439 //
440 Status = PeCoffLoaderLoadImage (&ImageContext);
441 if (EFI_ERROR (Status)) {
442 if (ImageContext.ImageError == IMAGE_ERROR_INVALID_SECTION_ALIGNMENT) {
443 DEBUG ((DEBUG_ERROR, "PEIM Image Address 0x%11p doesn't meet with section alignment 0x%x.\n", (VOID *)(UINTN)ImageContext.ImageAddress, ImageContext.SectionAlignment));
444 }
445
446 return Status;
447 }
448
449 //
450 // Relocate the image in our new buffer
451 //
452 Status = PeCoffLoaderRelocateImage (&ImageContext);
453 if (EFI_ERROR (Status)) {
454 return Status;
455 }
456
457 //
458 // Flush the instruction cache so the image data is written before we execute it
459 //
460 if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
461 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
462 }
463
464 *ImageAddress = ImageContext.ImageAddress;
465 *ImageSize = ImageContext.ImageSize;
466 *EntryPoint = ImageContext.EntryPoint;
467
468 return ReturnStatus;
469}
470
483 IN VOID *Pe32Data,
484 IN VOID *ImageAddress
485 )
486{
487 EFI_STATUS Status;
488 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
489
490 ZeroMem (&ImageContext, sizeof (ImageContext));
491 ImageContext.Handle = Pe32Data;
492 ImageContext.ImageRead = PeiImageRead;
493
494 Status = PeCoffLoaderGetImageInfo (&ImageContext);
495 if (EFI_ERROR (Status)) {
496 ASSERT_EFI_ERROR (Status);
497 return Status;
498 }
499
500 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)ImageAddress;
501
502 //
503 // Load the image in place
504 //
505 Status = PeCoffLoaderLoadImage (&ImageContext);
506 if (EFI_ERROR (Status)) {
507 ASSERT_EFI_ERROR (Status);
508 return Status;
509 }
510
511 //
512 // Relocate the image in place
513 //
514 Status = PeCoffLoaderRelocateImage (&ImageContext);
515 if (EFI_ERROR (Status)) {
516 ASSERT_EFI_ERROR (Status);
517 return Status;
518 }
519
520 //
521 // Flush the instruction cache so the image data is written before we execute it
522 //
523 if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
524 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
525 }
526
527 return Status;
528}
529
542 IN EFI_PEI_FILE_HANDLE FileHandle,
543 OUT VOID **Pe32Data
544 )
545{
546 EFI_STATUS Status;
547 EFI_SECTION_TYPE SearchType1;
548 EFI_SECTION_TYPE SearchType2;
549 UINT32 AuthenticationState;
550
551 *Pe32Data = NULL;
552
553 if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
554 SearchType1 = EFI_SECTION_TE;
555 SearchType2 = EFI_SECTION_PE32;
556 } else {
557 SearchType1 = EFI_SECTION_PE32;
558 SearchType2 = EFI_SECTION_TE;
559 }
560
561 //
562 // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
563 // is true, TE will be searched first).
564 //
566 SearchType1,
567 0,
568 FileHandle,
569 Pe32Data,
570 &AuthenticationState
571 );
572 //
573 // If we didn't find a first exe section, try to find the second exe section.
574 //
575 if (EFI_ERROR (Status)) {
577 SearchType2,
578 0,
579 FileHandle,
580 Pe32Data,
581 &AuthenticationState
582 );
583 }
584
585 return Status;
586}
587
610 IN CONST EFI_PEI_SERVICES **PeiServices,
611 IN EFI_PEI_FILE_HANDLE FileHandle,
612 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,
613 OUT UINT64 *ImageSizeArg OPTIONAL,
614 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
615 OUT UINT32 *AuthenticationState
616 )
617{
618 EFI_STATUS Status;
619 VOID *Pe32Data;
620 EFI_PHYSICAL_ADDRESS ImageAddress;
621 UINT64 ImageSize;
622 EFI_PHYSICAL_ADDRESS ImageEntryPoint;
623 UINT16 Machine;
624 EFI_SECTION_TYPE SearchType1;
625 EFI_SECTION_TYPE SearchType2;
626 CHAR8 *AsciiString;
627 CHAR8 EfiFileName[512];
628 UINTN Index;
629 UINTN StartIndex;
630
631 *EntryPoint = 0;
632 ImageSize = 0;
633 *AuthenticationState = 0;
634
635 if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
636 SearchType1 = EFI_SECTION_TE;
637 SearchType2 = EFI_SECTION_PE32;
638 } else {
639 SearchType1 = EFI_SECTION_PE32;
640 SearchType2 = EFI_SECTION_TE;
641 }
642
643 //
644 // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
645 // is true, TE will be searched first).
646 //
648 SearchType1,
649 0,
650 FileHandle,
651 &Pe32Data,
652 AuthenticationState
653 );
654 //
655 // If we didn't find a first exe section, try to find the second exe section.
656 //
657 if (EFI_ERROR (Status)) {
659 SearchType2,
660 0,
661 FileHandle,
662 &Pe32Data,
663 AuthenticationState
664 );
665 if (EFI_ERROR (Status)) {
666 //
667 // PEI core only carry the loader function for TE and PE32 executables
668 // If this two section does not exist, just return.
669 //
670 return Status;
671 }
672 }
673
674 DEBUG ((DEBUG_INFO, "Loading PEIM %g\n", FileHandle));
675
676 //
677 // If memory is installed, perform the shadow operations
678 //
680 FileHandle,
681 Pe32Data,
682 &ImageAddress,
683 &ImageSize,
684 &ImageEntryPoint
685 );
686
687 if (EFI_ERROR (Status)) {
688 return Status;
689 }
690
691 //
692 // Got the entry point from the loaded Pe32Data
693 //
694 Pe32Data = (VOID *)((UINTN)ImageAddress);
695 *EntryPoint = ImageEntryPoint;
696
697 Machine = PeCoffLoaderGetMachineType (Pe32Data);
698
699 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {
700 if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {
701 return EFI_UNSUPPORTED;
702 }
703 }
704
705 if (ImageAddressArg != NULL) {
706 *ImageAddressArg = ImageAddress;
707 }
708
709 if (ImageSizeArg != NULL) {
710 *ImageSizeArg = ImageSize;
711 }
712
713 //
714 // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
715 //
716 if (Machine != EFI_IMAGE_MACHINE_IA64) {
717 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));
718 } else {
719 //
720 // For IPF Image, the real entry point should be print.
721 //
722 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));
723 }
724
725 //
726 // Print Module Name by PeImage PDB file name.
727 //
728 AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data);
729
730 if (AsciiString != NULL) {
731 StartIndex = 0;
732 for (Index = 0; AsciiString[Index] != 0; Index++) {
733 if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) {
734 StartIndex = Index + 1;
735 }
736 }
737
738 //
739 // Copy the PDB file name to our temporary string, and replace .pdb with .efi
740 // The PDB file name is limited in the range of 0~511.
741 // If the length is bigger than 511, trim the redundant characters to avoid overflow in array boundary.
742 //
743 for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
744 EfiFileName[Index] = AsciiString[Index + StartIndex];
745 if (EfiFileName[Index] == 0) {
746 EfiFileName[Index] = '.';
747 }
748
749 if (EfiFileName[Index] == '.') {
750 EfiFileName[Index + 1] = 'e';
751 EfiFileName[Index + 2] = 'f';
752 EfiFileName[Index + 3] = 'i';
753 EfiFileName[Index + 4] = 0;
754 break;
755 }
756 }
757
758 if (Index == sizeof (EfiFileName) - 4) {
759 EfiFileName[Index] = 0;
760 }
761
762 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
763 }
764
765 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
766
767 return EFI_SUCCESS;
768}
769
784EFIAPI
787 IN EFI_PEI_FILE_HANDLE FileHandle,
788 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,
789 OUT UINT64 *ImageSizeArg OPTIONAL,
790 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
791 OUT UINT32 *AuthenticationState
792 )
793{
794 return PeiLoadImageLoadImage (
796 FileHandle,
797 ImageAddressArg,
798 ImageSizeArg,
799 EntryPoint,
800 AuthenticationState
801 );
802}
803
813BOOLEAN
815 IN VOID *Pe32Data
816 )
817{
819 EFI_IMAGE_DOS_HEADER *DosHdr;
820
821 ASSERT (Pe32Data != NULL);
822
823 DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
824 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
825 //
826 // DOS image header is present, so read the PE header after the DOS image header.
827 //
828 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));
829 } else {
830 //
831 // DOS image header is not present, so PE header is at the image base.
832 //
833 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
834 }
835
836 //
837 // Three cases with regards to relocations:
838 // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable
839 // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
840 // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
841 // has no base relocs to apply
842 // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
843 //
844 // Look at the file header to determine if relocations have been stripped, and
845 // save this info in the image context for later use.
846 //
847 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
848 if ((Hdr.Te->DataDirectory[0].Size == 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {
849 return TRUE;
850 } else {
851 return FALSE;
852 }
853 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
854 if ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {
855 return TRUE;
856 } else {
857 return FALSE;
858 }
859 }
860
861 return FALSE;
862}
863
882 IN CONST EFI_PEI_SERVICES **PeiServices,
883 IN EFI_PEI_FILE_HANDLE FileHandle,
884 IN UINT8 PeimState,
885 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
886 OUT UINT32 *AuthenticationState
887 )
888{
889 EFI_STATUS PpiStatus;
890 EFI_STATUS Status;
891 UINTN Index;
892 EFI_PEI_LOAD_FILE_PPI *LoadFile;
893 EFI_PHYSICAL_ADDRESS ImageAddress;
894 UINT64 ImageSize;
895 BOOLEAN IsStrip;
896
897 IsStrip = FALSE;
898 //
899 // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
900 // one at a time, until one reports EFI_SUCCESS.
901 //
902 Index = 0;
903 do {
904 PpiStatus = PeiServicesLocatePpi (
905 &gEfiPeiLoadFilePpiGuid,
906 Index,
907 NULL,
908 (VOID **)&LoadFile
909 );
910 if (!EFI_ERROR (PpiStatus)) {
911 Status = LoadFile->LoadFile (
912 LoadFile,
913 FileHandle,
914 &ImageAddress,
915 &ImageSize,
916 EntryPoint,
917 AuthenticationState
918 );
919 if (!EFI_ERROR (Status) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {
920 //
921 // The shadowed PEIM must be relocatable.
922 //
923 if (PeimState == PEIM_STATE_REGISTER_FOR_SHADOW) {
924 IsStrip = RelocationIsStrip ((VOID *)(UINTN)ImageAddress);
925 ASSERT (!IsStrip);
926 if (IsStrip) {
927 return EFI_UNSUPPORTED;
928 }
929 }
930
931 //
932 // The image to be started must have the machine type supported by PeiCore.
933 //
934 ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress)));
935 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) {
936 return EFI_UNSUPPORTED;
937 }
938
939 return EFI_SUCCESS;
940 }
941 }
942
943 Index++;
944 } while (!EFI_ERROR (PpiStatus));
945
946 return PpiStatus;
947}
948
958VOID
960 IN PEI_CORE_INSTANCE *PrivateData,
961 IN PEI_CORE_INSTANCE *OldCoreData
962 )
963{
964 if (OldCoreData == NULL) {
965 //
966 // The first time we are XIP (running from FLASH). We need to remember the
967 // FLASH address so we can reinstall the memory version that runs faster
968 //
969 PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
970 PeiServicesInstallPpi (PrivateData->XipLoadFile);
971 } else {
972 //
973 // 2nd time we are running from memory so replace the XIP version with the
974 // new memory version.
975 //
976 PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
977 }
978}
UINT64 UINTN
VOID *EFIAPI InvalidateInstructionCacheRange(IN VOID *Address, IN UINTN Length)
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
Definition: Unaligned.c:191
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS GetPeCoffImageFixLoadingAssignedAddress(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: Image.c:427
EFI_STATUS CheckAndMarkFixLoadingMemoryUsageBitMap(IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINTN ImageSize)
Definition: Image.c:347
VOID InitializeImageServices(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_INSTANCE *OldCoreData)
Definition: Image.c:959
EFI_STATUS PeiLoadImage(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINT8 PeimState, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState)
Definition: Image.c:881
BOOLEAN RelocationIsStrip(IN VOID *Pe32Data)
Definition: Image.c:814
EFI_STATUS LoadAndRelocatePeCoffImageInPlace(IN VOID *Pe32Data, IN VOID *ImageAddress)
Definition: Image.c:482
EFI_STATUS EFIAPI PeiImageRead(IN VOID *FileHandle, IN UINTN FileOffset, IN UINTN *ReadSize, OUT VOID *Buffer)
Definition: Image.c:36
EFI_STATUS PeiLoadImageLoadImage(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, OUT UINT64 *ImageSizeArg OPTIONAL, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState)
Definition: Image.c:609
EFI_STATUS LoadAndRelocatePeCoffImage(IN EFI_PEI_FILE_HANDLE FileHandle, IN VOID *Pe32Data, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT UINT64 *ImageSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint)
Definition: Image.c:265
EFI_STATUS PeiGetPe32Data(IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **Pe32Data)
Definition: Image.c:541
EFI_STATUS EFIAPI PeiLoadImageLoadImageWrapper(IN CONST EFI_PEI_LOAD_FILE_PPI *This, IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, OUT UINT64 *ImageSizeArg OPTIONAL, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState)
Definition: Image.c:785
EFI_STATUS EFIAPI PeiServicesFfsGetFileInfo(IN CONST EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO *FileInfo)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesAllocatePages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI PeiServicesReInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
RETURN_STATUS EFIAPI PeCoffLoaderLoadImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:1248
RETURN_STATUS EFIAPI PeCoffLoaderRelocateImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:957
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:578
#define EFI_IMAGE_SCN_CNT_CODE
0x00000020
Definition: PeImage.h:319
#define EFI_IMAGE_FILE_RELOCS_STRIPPED
0x0001 Relocation info stripped from file.
Definition: PeImage.h:99
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a)
Definition: PeiMain.h:343
EFI_STATUS EFIAPI PeiServicesFfsFindSectionData3(IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus)
#define EFI_SECTION_PE32
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_IMAGE_MACHINE_IA64
Definition: UefiBaseType.h:223
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EfiBootServicesCode
PEI_CORE_FV_HANDLE * Fv
Definition: PeiMain.h:259
EFI_BOOT_MODE BootMode
Definition: PiHob.h:74
UINT32 e_lfanew
File address of new exe header.
Definition: PeImage.h:75
UINT16 e_magic
Magic number.
Definition: PeImage.h:57
UINT16 Signature
The signature for TE format = "VZ".
Definition: PeImage.h:780
EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]
Only base relocation and debug directory.
Definition: PeImage.h:788
UINT8 NumberOfSections
From the original file header.
Definition: PeImage.h:782
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100
PHYSICAL_ADDRESS EntryPoint
Definition: PeCoffLib.h:95
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79