TianoCore EDK2 master
Loading...
Searching...
No Matches
Image.c
Go to the documentation of this file.
1
9#include "DxeMain.h"
10#include "Image.h"
11
12//
13// Module Globals
14//
15LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;
16
17typedef struct {
18 LIST_ENTRY Link;
20 UINT16 MachineType;
22
23STATIC LIST_ENTRY mAvailableEmulators;
24STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent;
25STATIC VOID *mPeCoffEmuProtocolNotifyRegistration;
26
27//
28// This code is needed to build the Image handle for the DXE Core
29//
30LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
31 LOADED_IMAGE_PRIVATE_DATA_SIGNATURE, // Signature
32 NULL, // Image handle
33 EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, // Image type
34 TRUE, // If entrypoint has been called
35 NULL, // EntryPoint
36 {
38 NULL, // Parent handle
39 NULL, // System handle
40
41 NULL, // Device handle
42 NULL, // File path
43 NULL, // Reserved
44
45 0, // LoadOptionsSize
46 NULL, // LoadOptions
47
48 NULL, // ImageBase
49 0, // ImageSize
50 EfiBootServicesCode, // ImageCodeType
51 EfiBootServicesData // ImageDataType
52 },
53 (EFI_PHYSICAL_ADDRESS)0, // ImageBasePage
54 0, // NumberOfPages
55 NULL, // FixupData
56 0, // Tpl
57 EFI_SUCCESS, // Status
58 0, // ExitDataSize
59 NULL, // ExitData
60 NULL, // JumpBuffer
61 NULL, // JumpContext
62 0, // Machine
63 NULL, // PeCoffEmu
64 NULL, // RuntimeData
65 NULL // LoadedImageDevicePath
66};
67//
68// The field is define for Loading modules at fixed address feature to tracker the PEI code
69// memory range usage. It is a bit mapped array in which every bit indicates the correspoding memory page
70// available or not.
71//
72GLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mDxeCodeMemoryRangeUsageBitMap = NULL;
73
74typedef struct {
75 UINT16 MachineType;
76 CHAR16 *MachineTypeName;
78
80 { EFI_IMAGE_MACHINE_IA32, L"IA32" },
81 { EFI_IMAGE_MACHINE_IA64, L"IA64" },
82 { EFI_IMAGE_MACHINE_X64, L"X64" },
83 { EFI_IMAGE_MACHINE_AARCH64, L"AARCH64" },
84 { EFI_IMAGE_MACHINE_RISCV64, L"RISCV64" },
85 { EFI_IMAGE_MACHINE_LOONGARCH64, L"LOONGARCH64" },
86};
87
88UINT16 mDxeCoreImageMachineType = 0;
89
97CHAR16 *
99 UINT16 MachineType
100 )
101{
102 UINTN Index;
103
104 for (Index = 0; Index < sizeof (mMachineTypeInfo)/sizeof (mMachineTypeInfo[0]); Index++) {
105 if (mMachineTypeInfo[Index].MachineType == MachineType) {
106 return mMachineTypeInfo[Index].MachineTypeName;
107 }
108 }
109
110 return L"<Unknown>";
111}
112
121STATIC
122VOID
123EFIAPI
125 IN EFI_EVENT Event,
126 IN VOID *Context
127 )
128{
129 EFI_STATUS Status;
130 UINTN BufferSize;
131 EFI_HANDLE EmuHandle;
133 EMULATOR_ENTRY *Entry;
134
135 EmuHandle = NULL;
136 Emulator = NULL;
137
138 while (TRUE) {
139 BufferSize = sizeof (EmuHandle);
140 Status = CoreLocateHandle (
142 NULL,
143 mPeCoffEmuProtocolNotifyRegistration,
144 &BufferSize,
145 &EmuHandle
146 );
147 if (EFI_ERROR (Status)) {
148 //
149 // If no more notification events exit
150 //
151 return;
152 }
153
154 Status = CoreHandleProtocol (
155 EmuHandle,
156 &gEdkiiPeCoffImageEmulatorProtocolGuid,
157 (VOID **)&Emulator
158 );
159 if (EFI_ERROR (Status) || (Emulator == NULL)) {
160 continue;
161 }
162
163 Entry = AllocateZeroPool (sizeof (*Entry));
164 if (Entry == NULL) {
165 ASSERT (Entry != NULL);
166 break;
167 }
168
169 Entry->Emulator = Emulator;
170 Entry->MachineType = Entry->Emulator->MachineType;
171
172 InsertTailList (&mAvailableEmulators, &Entry->Link);
173 }
174}
175
187 IN VOID *HobStart
188 )
189{
190 EFI_STATUS Status;
192 EFI_PHYSICAL_ADDRESS DxeCoreImageBaseAddress;
193 UINT64 DxeCoreImageLength;
194 VOID *DxeCoreEntryPoint;
195 EFI_PEI_HOB_POINTERS DxeCoreHob;
196
197 //
198 // Searching for image hob
199 //
200 DxeCoreHob.Raw = HobStart;
201 while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) {
202 if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
203 //
204 // Find Dxe Core HOB
205 //
206 if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->ModuleName, &gEfiCallerIdGuid)) {
207 break;
208 }
209 }
210
211 DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob);
212 }
213
214 ASSERT (DxeCoreHob.Raw != NULL);
215
216 DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
217 DxeCoreImageLength = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;
218 DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreHob.MemoryAllocationModule->EntryPoint;
219 gDxeCoreFileName = &DxeCoreHob.MemoryAllocationModule->ModuleName;
220
221 //
222 // Initialize the fields for an internal driver
223 //
224 Image = &mCorePrivateImage;
225
226 Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint;
227 Image->ImageBasePage = DxeCoreImageBaseAddress;
228 Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES ((UINTN)(DxeCoreImageLength)));
229 Image->Tpl = gEfiCurrentTpl;
230 Image->Info.ImageBase = (VOID *)(UINTN)DxeCoreImageBaseAddress;
231 Image->Info.ImageSize = DxeCoreImageLength;
232
233 //
234 // Install the protocol interfaces for this image
235 //
237 &Image->Handle,
238 &gEfiLoadedImageProtocolGuid,
240 &Image->Info
241 );
242 ASSERT_EFI_ERROR (Status);
243
244 mCurrentImage = Image;
245
246 //
247 // Fill in DXE globals
248 //
249 mDxeCoreImageMachineType = PeCoffLoaderGetMachineType (Image->Info.ImageBase);
250 gDxeCoreImageHandle = Image->Handle;
251 gDxeCoreLoadedImage = &Image->Info;
252
253 //
254 // Create the PE/COFF emulator protocol registration event
255 //
256 Status = CoreCreateEvent (
257 EVT_NOTIFY_SIGNAL,
258 TPL_CALLBACK,
260 NULL,
261 &mPeCoffEmuProtocolRegistrationEvent
262 );
263 ASSERT_EFI_ERROR (Status);
264
265 //
266 // Register for protocol notifications on this event
267 //
269 &gEdkiiPeCoffImageEmulatorProtocolGuid,
270 mPeCoffEmuProtocolRegistrationEvent,
271 &mPeCoffEmuProtocolNotifyRegistration
272 );
273 ASSERT_EFI_ERROR (Status);
274
275 InitializeListHead (&mAvailableEmulators);
276
278
279 return Status;
280}
281
297EFIAPI
299 IN VOID *UserHandle,
300 IN UINTN Offset,
301 IN OUT UINTN *ReadSize,
302 OUT VOID *Buffer
303 )
304{
305 UINTN EndPosition;
306 IMAGE_FILE_HANDLE *FHand;
307
308 if ((UserHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {
309 return EFI_INVALID_PARAMETER;
310 }
311
312 if (MAX_ADDRESS - Offset < *ReadSize) {
313 return EFI_INVALID_PARAMETER;
314 }
315
316 FHand = (IMAGE_FILE_HANDLE *)UserHandle;
317 ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
318
319 //
320 // Move data from our local copy of the file
321 //
322 EndPosition = Offset + *ReadSize;
323 if (EndPosition > FHand->SourceSize) {
324 *ReadSize = (UINT32)(FHand->SourceSize - Offset);
325 }
326
327 if (Offset >= FHand->SourceSize) {
328 *ReadSize = 0;
329 }
330
331 CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
332 return EFI_SUCCESS;
333}
334
348 IN EFI_PHYSICAL_ADDRESS ImageBase,
349 IN UINTN ImageSize
350 )
351{
352 UINT32 DxeCodePageNumber;
353 UINT64 DxeCodeSize;
354 EFI_PHYSICAL_ADDRESS DxeCodeBase;
355 UINTN BaseOffsetPageNumber;
356 UINTN TopOffsetPageNumber;
357 UINTN Index;
358
359 //
360 // The DXE code range includes RuntimeCodePage range and Boot time code range.
361 //
362 DxeCodePageNumber = PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber);
363 DxeCodePageNumber += PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber);
364 DxeCodeSize = EFI_PAGES_TO_SIZE (DxeCodePageNumber);
365 DxeCodeBase = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress - DxeCodeSize;
366
367 //
368 // If the memory usage bit map is not initialized, do it. Every bit in the array
369 // indicate the status of the corresponding memory page, available or not
370 //
371 if (mDxeCodeMemoryRangeUsageBitMap == NULL) {
372 mDxeCodeMemoryRangeUsageBitMap = AllocateZeroPool (((DxeCodePageNumber/64) + 1)*sizeof (UINT64));
373 }
374
375 //
376 // If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND
377 //
378 if (!gLoadFixedAddressCodeMemoryReady || (mDxeCodeMemoryRangeUsageBitMap == NULL)) {
379 return EFI_NOT_FOUND;
380 }
381
382 //
383 // Test the memory range for loading the image in the DXE code range.
384 //
385 if ((gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress < ImageBase + ImageSize) ||
386 (DxeCodeBase > ImageBase))
387 {
388 return EFI_NOT_FOUND;
389 }
390
391 //
392 // Test if the memory is avalaible or not.
393 //
394 BaseOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase - DxeCodeBase));
395 TopOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase + ImageSize - DxeCodeBase));
396 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
397 if ((mDxeCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64 (1, (Index % 64))) != 0) {
398 //
399 // This page is already used.
400 //
401 return EFI_NOT_FOUND;
402 }
403 }
404
405 //
406 // Being here means the memory range is available. So mark the bits for the memory range
407 //
408 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
409 mDxeCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64 (1, (Index % 64));
410 }
411
412 return EFI_SUCCESS;
413}
414
429 )
430{
431 UINTN SectionHeaderOffset;
432 EFI_STATUS Status;
433 EFI_IMAGE_SECTION_HEADER SectionHeader;
435 UINT16 Index;
436 UINTN Size;
437 UINT16 NumberOfSections;
438 IMAGE_FILE_HANDLE *Handle;
439 UINT64 ValueInSectionHeader;
440
441 Status = EFI_NOT_FOUND;
442
443 //
444 // Get PeHeader pointer
445 //
446 Handle = (IMAGE_FILE_HANDLE *)ImageContext->Handle;
447 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)Handle->Source + ImageContext->PeCoffHeaderOffset);
448 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
449 sizeof (UINT32) +
450 sizeof (EFI_IMAGE_FILE_HEADER) +
451 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
452 NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
453
454 //
455 // Get base address from the first section header that doesn't point to code section.
456 //
457 for (Index = 0; Index < NumberOfSections; Index++) {
458 //
459 // Read section header from file
460 //
461 Size = sizeof (EFI_IMAGE_SECTION_HEADER);
462 Status = ImageContext->ImageRead (
463 ImageContext->Handle,
464 SectionHeaderOffset,
465 &Size,
466 &SectionHeader
467 );
468 if (EFI_ERROR (Status)) {
469 return Status;
470 }
471
472 if (Size != sizeof (EFI_IMAGE_SECTION_HEADER)) {
473 return EFI_NOT_FOUND;
474 }
475
476 Status = EFI_NOT_FOUND;
477
478 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
479 //
480 // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
481 // that doesn't point to code section in image header, as well as ImageBase field of image header. And there is an
482 // assumption that when the feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations
483 // & PointerToLineNumbers fields should NOT be Zero, or else, these 2 fields should be set to Zero
484 //
485 ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
486 if (ValueInSectionHeader != 0) {
487 //
488 // When the feature is configured as load module at fixed absolute address, the ImageAddress field of ImageContext
489 // hold the specified address. If the feature is configured as load module at fixed offset, ImageAddress hold an offset
490 // relative to top address
491 //
492 if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) < 0) {
493 ImageContext->ImageAddress = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress + (INT64)(INTN)ImageContext->ImageAddress;
494 }
495
496 //
497 // Check if the memory range is available.
498 //
499 Status = CheckAndMarkFixLoadingMemoryUsageBitMap (ImageContext->ImageAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
500 }
501
502 break;
503 }
504
505 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
506 }
507
508 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)(ImageContext->ImageAddress), Status));
509 return Status;
510}
511
524STATIC
525BOOLEAN
528 )
529{
530 LIST_ENTRY *Link;
531 EMULATOR_ENTRY *Entry;
532
533 for (Link = GetFirstNode (&mAvailableEmulators);
534 !IsNull (&mAvailableEmulators, Link);
535 Link = GetNextNode (&mAvailableEmulators, Link))
536 {
537 Entry = BASE_CR (Link, EMULATOR_ENTRY, Link);
538 if (Entry->MachineType != Image->ImageContext.Machine) {
539 continue;
540 }
541
542 if (Entry->Emulator->IsImageSupported (
543 Entry->Emulator,
544 Image->ImageContext.ImageType,
545 Image->Info.FilePath
546 ))
547 {
548 Image->PeCoffEmu = Entry->Emulator;
549 return TRUE;
550 }
551 }
552
553 return EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine) ||
554 EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Image->ImageContext.Machine);
555}
556
580 IN BOOLEAN BootPolicy,
581 IN VOID *Pe32Handle,
583 IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
584 OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
585 IN UINT32 Attribute
586 )
587{
588 EFI_STATUS Status;
589 BOOLEAN DstBufAlocated;
590 UINTN Size;
591 UINTN Index;
592 UINTN StartIndex;
593 CHAR8 EfiFileName[512];
594
595 ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));
596
597 Image->ImageContext.Handle = Pe32Handle;
598 Image->ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)CoreReadImageFile;
599
600 //
601 // Get information about the image being loaded
602 //
603 Status = PeCoffLoaderGetImageInfo (&Image->ImageContext);
604 if (EFI_ERROR (Status)) {
605 return Status;
606 }
607
608 if (!CoreIsImageTypeSupported (Image)) {
609 //
610 // The PE/COFF loader can support loading image types that can be executed.
611 // If we loaded an image type that we can not execute return EFI_UNSUPPORTED.
612 //
613 DEBUG ((
614 DEBUG_ERROR,
615 "Image type %s can't be loaded on %s UEFI system.\n",
616 GetMachineTypeName (Image->ImageContext.Machine),
617 GetMachineTypeName (mDxeCoreImageMachineType)
618 ));
619 return EFI_UNSUPPORTED;
620 }
621
622 //
623 // Set EFI memory type based on ImageType
624 //
625 switch (Image->ImageContext.ImageType) {
626 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
627 Image->ImageContext.ImageCodeMemoryType = EfiLoaderCode;
628 Image->ImageContext.ImageDataMemoryType = EfiLoaderData;
629 break;
630 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
631 Image->ImageContext.ImageCodeMemoryType = EfiBootServicesCode;
632 Image->ImageContext.ImageDataMemoryType = EfiBootServicesData;
633 break;
634 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
635 Image->ImageContext.ImageCodeMemoryType = EfiRuntimeServicesCode;
636 Image->ImageContext.ImageDataMemoryType = EfiRuntimeServicesData;
637 break;
638 default:
639 Image->ImageContext.ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
640 return EFI_UNSUPPORTED;
641 }
642
643 //
644 // Allocate memory of the correct memory type aligned on the required image boundary
645 //
646 DstBufAlocated = FALSE;
647 if (DstBuffer == 0) {
648 //
649 // Allocate Destination Buffer as caller did not pass it in
650 //
651
652 if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
653 Size = (UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment;
654 } else {
655 Size = (UINTN)Image->ImageContext.ImageSize;
656 }
657
658 Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size);
659
660 //
661 // If the image relocations have not been stripped, then load at any address.
662 // Otherwise load at the address at which it was linked.
663 //
664 // Memory below 1MB should be treated reserved for CSM and there should be
665 // no modules whose preferred load addresses are below 1MB.
666 //
667 Status = EFI_OUT_OF_RESOURCES;
668 //
669 // If Loading Module At Fixed Address feature is enabled, the module should be loaded to
670 // a specified address.
671 //
672 if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0 ) {
673 Status = GetPeCoffImageFixLoadingAssignedAddress (&(Image->ImageContext));
674
675 if (EFI_ERROR (Status)) {
676 //
677 // If the code memory is not ready, invoke CoreAllocatePage with AllocateAnyPages to load the driver.
678 //
679 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since specified memory is not available.\n"));
680
681 Status = CoreAllocatePages (
683 (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType),
684 Image->NumberOfPages,
685 &Image->ImageContext.ImageAddress
686 );
687 }
688 } else {
689 if ((PcdGetBool (PcdImageLargeAddressLoad) && ((Image->ImageContext.ImageAddress) >= 0x100000)) ||
690 Image->ImageContext.RelocationsStripped)
691 {
692 Status = CoreAllocatePages (
694 (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType),
695 Image->NumberOfPages,
696 &Image->ImageContext.ImageAddress
697 );
698 }
699
700 if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) {
701 Status = CoreAllocatePages (
703 (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType),
704 Image->NumberOfPages,
705 &Image->ImageContext.ImageAddress
706 );
707 }
708 }
709
710 if (EFI_ERROR (Status)) {
711 return Status;
712 }
713
714 DstBufAlocated = TRUE;
715 } else {
716 //
717 // Caller provided the destination buffer
718 //
719
720 if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) {
721 //
722 // If the image relocations were stripped, and the caller provided a
723 // destination buffer address that does not match the address that the
724 // image is linked at, then the image cannot be loaded.
725 //
726 return EFI_INVALID_PARAMETER;
727 }
728
729 if ((Image->NumberOfPages != 0) &&
730 (Image->NumberOfPages <
731 (EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment))))
732 {
733 Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
734 return EFI_BUFFER_TOO_SMALL;
735 }
736
737 Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
738 Image->ImageContext.ImageAddress = DstBuffer;
739 }
740
741 Image->ImageBasePage = Image->ImageContext.ImageAddress;
742 if (!Image->ImageContext.IsTeImage) {
743 Image->ImageContext.ImageAddress =
744 (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &
745 ~((EFI_PHYSICAL_ADDRESS)Image->ImageContext.SectionAlignment - 1);
746 }
747
748 //
749 // Load the image from the file into the allocated memory
750 //
751 Status = PeCoffLoaderLoadImage (&Image->ImageContext);
752 if (EFI_ERROR (Status)) {
753 goto Done;
754 }
755
756 //
757 // If this is a Runtime Driver, then allocate memory for the FixupData that
758 // is used to relocate the image when SetVirtualAddressMap() is called. The
759 // relocation is done by the Runtime AP.
760 //
761 if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) {
762 if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
763 Image->ImageContext.FixupData = AllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));
764 if (Image->ImageContext.FixupData == NULL) {
765 Status = EFI_OUT_OF_RESOURCES;
766 goto Done;
767 }
768 }
769 }
770
771 //
772 // Relocate the image in memory
773 //
774 Status = PeCoffLoaderRelocateImage (&Image->ImageContext);
775 if (EFI_ERROR (Status)) {
776 goto Done;
777 }
778
779 //
780 // Flush the Instruction Cache
781 //
782 InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize);
783
784 //
785 // Copy the machine type from the context to the image private data.
786 //
787 Image->Machine = Image->ImageContext.Machine;
788
789 //
790 // Get the image entry point.
791 //
792 Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)Image->ImageContext.EntryPoint;
793
794 //
795 // Fill in the image information for the Loaded Image Protocol
796 //
797 Image->Type = Image->ImageContext.ImageType;
798 Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageContext.ImageAddress;
799 Image->Info.ImageSize = Image->ImageContext.ImageSize;
800 Image->Info.ImageCodeType = (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType);
801 Image->Info.ImageDataType = (EFI_MEMORY_TYPE)(Image->ImageContext.ImageDataMemoryType);
802 if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) {
803 if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
804 //
805 // Make a list off all the RT images so we can let the RT AP know about them.
806 //
807 Image->RuntimeData = AllocateRuntimePool (sizeof (EFI_RUNTIME_IMAGE_ENTRY));
808 if (Image->RuntimeData == NULL) {
809 goto Done;
810 }
811
812 Image->RuntimeData->ImageBase = Image->Info.ImageBase;
813 Image->RuntimeData->ImageSize = (UINT64)(Image->Info.ImageSize);
814 Image->RuntimeData->RelocationData = Image->ImageContext.FixupData;
815 Image->RuntimeData->Handle = Image->Handle;
816 InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link);
817 InsertImageRecord (Image->RuntimeData);
818 }
819 }
820
821 //
822 // Fill in the entry point of the image if it is available
823 //
824 if (EntryPoint != NULL) {
825 *EntryPoint = Image->ImageContext.EntryPoint;
826 }
827
828 //
829 // Print the load address and the PDB file name if it is available
830 //
831
832 DEBUG ((
833 DEBUG_INFO | DEBUG_LOAD,
834 "Loading driver at 0x%11p EntryPoint=0x%11p ",
835 (VOID *)(UINTN)Image->ImageContext.ImageAddress,
836 FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint)
837 ));
838
839 //
840 // Print Module Name by Pdb file path.
841 // Windows and Unix style file path are all trimmed correctly.
842 //
843 if (Image->ImageContext.PdbPointer != NULL) {
844 StartIndex = 0;
845 for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {
846 if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {
847 StartIndex = Index + 1;
848 }
849 }
850
851 //
852 // Copy the PDB file name to our temporary string, and replace .pdb with .efi
853 // The PDB file name is limited in the range of 0~255.
854 // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.
855 //
856 for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
857 EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];
858 if (EfiFileName[Index] == 0) {
859 EfiFileName[Index] = '.';
860 }
861
862 if (EfiFileName[Index] == '.') {
863 EfiFileName[Index + 1] = 'e';
864 EfiFileName[Index + 2] = 'f';
865 EfiFileName[Index + 3] = 'i';
866 EfiFileName[Index + 4] = 0;
867 break;
868 }
869 }
870
871 if (Index == sizeof (EfiFileName) - 4) {
872 EfiFileName[Index] = 0;
873 }
874
875 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
876 }
877
878 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
879
880 return EFI_SUCCESS;
881
882Done:
883
884 //
885 // Free memory.
886 //
887
888 if (DstBufAlocated) {
889 CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages);
890 Image->ImageContext.ImageAddress = 0;
891 Image->ImageBasePage = 0;
892 }
893
894 if (Image->ImageContext.FixupData != NULL) {
895 CoreFreePool (Image->ImageContext.FixupData);
896 }
897
898 return Status;
899}
900
911 IN EFI_HANDLE ImageHandle
912 )
913{
914 EFI_STATUS Status;
915 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
917
918 Status = CoreHandleProtocol (
919 ImageHandle,
920 &gEfiLoadedImageProtocolGuid,
921 (VOID **)&LoadedImage
922 );
923 if (!EFI_ERROR (Status)) {
924 Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);
925 } else {
926 DEBUG ((DEBUG_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %p\n", ImageHandle));
927 Image = NULL;
928 }
929
930 return Image;
931}
932
940VOID
943 IN BOOLEAN FreePage
944 )
945{
946 EFI_STATUS Status;
947 UINTN HandleCount;
948 EFI_HANDLE *HandleBuffer;
949 UINTN HandleIndex;
950 EFI_GUID **ProtocolGuidArray;
951 UINTN ArrayCount;
952 UINTN ProtocolIndex;
954 UINTN OpenInfoCount;
955 UINTN OpenInfoIndex;
956
957 HandleBuffer = NULL;
958 ProtocolGuidArray = NULL;
959
960 if (Image->Started) {
962 }
963
964 UnprotectUefiImage (&Image->Info, Image->LoadedImageDevicePath);
965
966 if (Image->PeCoffEmu != NULL) {
967 //
968 // If the PE/COFF Emulator protocol exists we must unregister the image.
969 //
970 Image->PeCoffEmu->UnregisterImage (Image->PeCoffEmu, Image->ImageBasePage);
971 }
972
973 //
974 // Unload image, free Image->ImageContext->ModHandle
975 //
976 PeCoffLoaderUnloadImage (&Image->ImageContext);
977
978 //
979 // Free our references to the image handle
980 //
981 if (Image->Handle != NULL) {
982 Status = CoreLocateHandleBuffer (
984 NULL,
985 NULL,
986 &HandleCount,
987 &HandleBuffer
988 );
989 if (!EFI_ERROR (Status)) {
990 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
991 Status = CoreProtocolsPerHandle (
992 HandleBuffer[HandleIndex],
993 &ProtocolGuidArray,
994 &ArrayCount
995 );
996 if (!EFI_ERROR (Status)) {
997 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
999 HandleBuffer[HandleIndex],
1000 ProtocolGuidArray[ProtocolIndex],
1001 &OpenInfo,
1002 &OpenInfoCount
1003 );
1004 if (!EFI_ERROR (Status)) {
1005 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
1006 if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {
1007 Status = CoreCloseProtocol (
1008 HandleBuffer[HandleIndex],
1009 ProtocolGuidArray[ProtocolIndex],
1010 Image->Handle,
1011 OpenInfo[OpenInfoIndex].ControllerHandle
1012 );
1013 }
1014 }
1015
1016 if (OpenInfo != NULL) {
1017 CoreFreePool (OpenInfo);
1018 }
1019 }
1020 }
1021
1022 if (ProtocolGuidArray != NULL) {
1023 CoreFreePool (ProtocolGuidArray);
1024 }
1025 }
1026 }
1027
1028 if (HandleBuffer != NULL) {
1029 CoreFreePool (HandleBuffer);
1030 }
1031 }
1032
1033 CoreRemoveDebugImageInfoEntry (Image->Handle);
1034
1036 Image->Handle,
1037 &gEfiLoadedImageDevicePathProtocolGuid,
1038 Image->LoadedImageDevicePath
1039 );
1040
1042 Image->Handle,
1043 &gEfiLoadedImageProtocolGuid,
1044 &Image->Info
1045 );
1046
1047 if (Image->ImageContext.HiiResourceData != 0) {
1049 Image->Handle,
1050 &gEfiHiiPackageListProtocolGuid,
1051 (VOID *)(UINTN)Image->ImageContext.HiiResourceData
1052 );
1053 }
1054 }
1055
1056 if (Image->RuntimeData != NULL) {
1057 if (Image->RuntimeData->Link.ForwardLink != NULL) {
1058 //
1059 // Remove the Image from the Runtime Image list as we are about to Free it!
1060 //
1061 RemoveEntryList (&Image->RuntimeData->Link);
1062 RemoveImageRecord (Image->RuntimeData);
1063 }
1064
1065 CoreFreePool (Image->RuntimeData);
1066 }
1067
1068 //
1069 // Free the Image from memory
1070 //
1071 if ((Image->ImageBasePage != 0) && FreePage) {
1072 CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);
1073 }
1074
1075 //
1076 // Done with the Image structure
1077 //
1078 if (Image->Info.FilePath != NULL) {
1079 CoreFreePool (Image->Info.FilePath);
1080 }
1081
1082 if (Image->LoadedImageDevicePath != NULL) {
1083 CoreFreePool (Image->LoadedImageDevicePath);
1084 }
1085
1086 if (Image->FixupData != NULL) {
1087 CoreFreePool (Image->FixupData);
1088 }
1089
1090 CoreFreePool (Image);
1091}
1092
1139 IN BOOLEAN BootPolicy,
1140 IN EFI_HANDLE ParentImageHandle,
1141 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1142 IN VOID *SourceBuffer OPTIONAL,
1143 IN UINTN SourceSize,
1144 IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
1145 IN OUT UINTN *NumberOfPages OPTIONAL,
1146 OUT EFI_HANDLE *ImageHandle,
1147 OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
1148 IN UINT32 Attribute
1149 )
1150{
1152 LOADED_IMAGE_PRIVATE_DATA *ParentImage;
1153 IMAGE_FILE_HANDLE FHand;
1154 EFI_STATUS Status;
1155 EFI_STATUS SecurityStatus;
1156 EFI_HANDLE DeviceHandle;
1157 UINT32 AuthenticationStatus;
1158 EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
1159 EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
1160 EFI_DEVICE_PATH_PROTOCOL *InputFilePath;
1162 UINTN FilePathSize;
1163 BOOLEAN ImageIsFromFv;
1164 BOOLEAN ImageIsFromLoadFile;
1165
1166 SecurityStatus = EFI_SUCCESS;
1167
1168 ASSERT (gEfiCurrentTpl < TPL_NOTIFY);
1169 ParentImage = NULL;
1170
1171 //
1172 // The caller must pass in a valid ParentImageHandle
1173 //
1174 if ((ImageHandle == NULL) || (ParentImageHandle == NULL)) {
1175 return EFI_INVALID_PARAMETER;
1176 }
1177
1178 ParentImage = CoreLoadedImageInfo (ParentImageHandle);
1179 if (ParentImage == NULL) {
1180 DEBUG ((DEBUG_LOAD|DEBUG_ERROR, "LoadImageEx: Parent handle not an image handle\n"));
1181 return EFI_INVALID_PARAMETER;
1182 }
1183
1184 ZeroMem (&FHand, sizeof (IMAGE_FILE_HANDLE));
1185 FHand.Signature = IMAGE_FILE_HANDLE_SIGNATURE;
1186 OriginalFilePath = FilePath;
1187 InputFilePath = FilePath;
1188 HandleFilePath = FilePath;
1189 DeviceHandle = NULL;
1190 Status = EFI_SUCCESS;
1191 AuthenticationStatus = 0;
1192 ImageIsFromFv = FALSE;
1193 ImageIsFromLoadFile = FALSE;
1194
1195 //
1196 // If the caller passed a copy of the file, then just use it
1197 //
1198 if (SourceBuffer != NULL) {
1199 FHand.Source = SourceBuffer;
1200 FHand.SourceSize = SourceSize;
1201 Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle);
1202 if (EFI_ERROR (Status)) {
1203 DeviceHandle = NULL;
1204 }
1205
1206 if (SourceSize > 0) {
1207 Status = EFI_SUCCESS;
1208 } else {
1209 Status = EFI_LOAD_ERROR;
1210 }
1211 } else {
1212 if (FilePath == NULL) {
1213 return EFI_INVALID_PARAMETER;
1214 }
1215
1216 //
1217 // Try to get the image device handle by checking the match protocol.
1218 //
1219 Node = NULL;
1220 Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);
1221 if (!EFI_ERROR (Status)) {
1222 ImageIsFromFv = TRUE;
1223 } else {
1224 HandleFilePath = FilePath;
1225 Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle);
1226 if (EFI_ERROR (Status)) {
1227 if (!BootPolicy) {
1228 HandleFilePath = FilePath;
1229 Status = CoreLocateDevicePath (&gEfiLoadFile2ProtocolGuid, &HandleFilePath, &DeviceHandle);
1230 }
1231
1232 if (EFI_ERROR (Status)) {
1233 HandleFilePath = FilePath;
1234 Status = CoreLocateDevicePath (&gEfiLoadFileProtocolGuid, &HandleFilePath, &DeviceHandle);
1235 if (!EFI_ERROR (Status)) {
1236 ImageIsFromLoadFile = TRUE;
1237 Node = HandleFilePath;
1238 }
1239 }
1240 }
1241 }
1242
1243 //
1244 // Get the source file buffer by its device path.
1245 //
1246 FHand.Source = GetFileBufferByFilePath (
1247 BootPolicy,
1248 FilePath,
1249 &FHand.SourceSize,
1250 &AuthenticationStatus
1251 );
1252 if (FHand.Source == NULL) {
1253 Status = EFI_NOT_FOUND;
1254 } else {
1255 FHand.FreeBuffer = TRUE;
1256 if (ImageIsFromLoadFile) {
1257 //
1258 // LoadFile () may cause the device path of the Handle be updated.
1259 //
1260 OriginalFilePath = AppendDevicePath (DevicePathFromHandle (DeviceHandle), Node);
1261 if (OriginalFilePath == NULL) {
1262 Image = NULL;
1263 Status = EFI_OUT_OF_RESOURCES;
1264 goto Done;
1265 }
1266 }
1267 }
1268 }
1269
1270 if (EFI_ERROR (Status)) {
1271 Image = NULL;
1272 goto Done;
1273 }
1274
1275 if (gSecurity2 != NULL) {
1276 //
1277 // Verify File Authentication through the Security2 Architectural Protocol
1278 //
1279 SecurityStatus = gSecurity2->FileAuthentication (
1280 gSecurity2,
1281 OriginalFilePath,
1282 FHand.Source,
1283 FHand.SourceSize,
1284 BootPolicy
1285 );
1286 if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) {
1287 //
1288 // When Security2 is installed, Security Architectural Protocol must be published.
1289 //
1290 ASSERT (gSecurity != NULL);
1291
1292 //
1293 // Verify the Authentication Status through the Security Architectural Protocol
1294 // Only on images that have been read using Firmware Volume protocol.
1295 //
1296 SecurityStatus = gSecurity->FileAuthenticationState (
1297 gSecurity,
1298 AuthenticationStatus,
1299 OriginalFilePath
1300 );
1301 }
1302 } else if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {
1303 //
1304 // Verify the Authentication Status through the Security Architectural Protocol
1305 //
1306 SecurityStatus = gSecurity->FileAuthenticationState (
1307 gSecurity,
1308 AuthenticationStatus,
1309 OriginalFilePath
1310 );
1311 }
1312
1313 //
1314 // Check Security Status.
1315 //
1316 if (EFI_ERROR (SecurityStatus) && (SecurityStatus != EFI_SECURITY_VIOLATION)) {
1317 if (SecurityStatus == EFI_ACCESS_DENIED) {
1318 //
1319 // Image was not loaded because the platform policy prohibits the image from being loaded.
1320 // It's the only place we could meet EFI_ACCESS_DENIED.
1321 //
1322 *ImageHandle = NULL;
1323 }
1324
1325 Status = SecurityStatus;
1326 Image = NULL;
1327 goto Done;
1328 }
1329
1330 //
1331 // Allocate a new image structure
1332 //
1334 if (Image == NULL) {
1335 Status = EFI_OUT_OF_RESOURCES;
1336 goto Done;
1337 }
1338
1339 //
1340 // Pull out just the file portion of the DevicePath for the LoadedImage FilePath
1341 //
1342 FilePath = OriginalFilePath;
1343 if (DeviceHandle != NULL) {
1344 Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
1345 if (!EFI_ERROR (Status)) {
1346 FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
1347 FilePath = (EFI_DEVICE_PATH_PROTOCOL *)(((UINT8 *)FilePath) + FilePathSize);
1348 }
1349 }
1350
1351 //
1352 // Initialize the fields for an internal driver
1353 //
1354 Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE;
1355 Image->Info.SystemTable = gDxeCoreST;
1356 Image->Info.DeviceHandle = DeviceHandle;
1358 Image->Info.FilePath = DuplicateDevicePath (FilePath);
1359 Image->Info.ParentHandle = ParentImageHandle;
1360
1361 if (NumberOfPages != NULL) {
1362 Image->NumberOfPages = *NumberOfPages;
1363 } else {
1364 Image->NumberOfPages = 0;
1365 }
1366
1367 //
1368 // Install the protocol interfaces for this image
1369 // don't fire notifications yet
1370 //
1372 &Image->Handle,
1373 &gEfiLoadedImageProtocolGuid,
1375 &Image->Info,
1376 FALSE
1377 );
1378 if (EFI_ERROR (Status)) {
1379 goto Done;
1380 }
1381
1382 //
1383 // Load the image. If EntryPoint is Null, it will not be set.
1384 //
1385 Status = CoreLoadPeImage (BootPolicy, &FHand, Image, DstBuffer, EntryPoint, Attribute);
1386 if (EFI_ERROR (Status)) {
1387 if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) {
1388 if (NumberOfPages != NULL) {
1389 *NumberOfPages = Image->NumberOfPages;
1390 }
1391 }
1392
1393 goto Done;
1394 }
1395
1396 if (NumberOfPages != NULL) {
1397 *NumberOfPages = Image->NumberOfPages;
1398 }
1399
1400 //
1401 // Register the image in the Debug Image Info Table if the attribute is set
1402 //
1403 if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) != 0) {
1404 CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle);
1405 }
1406
1407 //
1408 // Check whether we are loading a runtime image that lacks support for
1409 // IBT/BTI landing pads.
1410 //
1412 ((Image->ImageContext.DllCharacteristicsEx & EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT) == 0))
1413 {
1414 gMemoryAttributesTableForwardCfi = FALSE;
1415 }
1416
1417 //
1418 // Reinstall loaded image protocol to fire any notifications
1419 //
1421 Image->Handle,
1422 &gEfiLoadedImageProtocolGuid,
1423 &Image->Info,
1424 &Image->Info
1425 );
1426 if (EFI_ERROR (Status)) {
1427 goto Done;
1428 }
1429
1430 //
1431 // If DevicePath parameter to the LoadImage() is not NULL, then make a copy of DevicePath,
1432 // otherwise Loaded Image Device Path Protocol is installed with a NULL interface pointer.
1433 //
1434 if (OriginalFilePath != NULL) {
1435 Image->LoadedImageDevicePath = DuplicateDevicePath (OriginalFilePath);
1436 }
1437
1438 //
1439 // Install Loaded Image Device Path Protocol onto the image handle of a PE/COFE image
1440 //
1442 &Image->Handle,
1443 &gEfiLoadedImageDevicePathProtocolGuid,
1446 );
1447 if (EFI_ERROR (Status)) {
1448 goto Done;
1449 }
1450
1451 //
1452 // Install HII Package List Protocol onto the image handle
1453 //
1454 if (Image->ImageContext.HiiResourceData != 0) {
1456 &Image->Handle,
1457 &gEfiHiiPackageListProtocolGuid,
1460 );
1461 if (EFI_ERROR (Status)) {
1462 goto Done;
1463 }
1464 }
1465
1467
1468 //
1469 // Success. Return the image handle
1470 //
1471 *ImageHandle = Image->Handle;
1472
1473Done:
1474 //
1475 // All done accessing the source file
1476 // If we allocated the Source buffer, free it
1477 //
1478 if (FHand.FreeBuffer) {
1479 CoreFreePool (FHand.Source);
1480 }
1481
1482 if (OriginalFilePath != InputFilePath) {
1483 CoreFreePool (OriginalFilePath);
1484 }
1485
1486 //
1487 // There was an error. If there's an Image structure, free it
1488 //
1489 if (EFI_ERROR (Status)) {
1490 if (Image != NULL) {
1491 CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));
1492 Image = NULL;
1493 }
1494 } else if (EFI_ERROR (SecurityStatus)) {
1495 Status = SecurityStatus;
1496 }
1497
1498 //
1499 // Track the return status from LoadImage.
1500 //
1501 if (Image != NULL) {
1502 Image->LoadImageStatus = Status;
1503 }
1504
1505 return Status;
1506}
1507
1543EFIAPI
1545 IN BOOLEAN BootPolicy,
1546 IN EFI_HANDLE ParentImageHandle,
1547 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1548 IN VOID *SourceBuffer OPTIONAL,
1549 IN UINTN SourceSize,
1550 OUT EFI_HANDLE *ImageHandle
1551 )
1552{
1553 EFI_STATUS Status;
1554 EFI_HANDLE Handle;
1555
1557
1558 Status = CoreLoadImageCommon (
1559 BootPolicy,
1560 ParentImageHandle,
1561 FilePath,
1562 SourceBuffer,
1563 SourceSize,
1565 NULL,
1566 ImageHandle,
1567 NULL,
1568 EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION
1569 );
1570
1571 Handle = NULL;
1572 if (!EFI_ERROR (Status)) {
1573 //
1574 // ImageHandle will be valid only Status is success.
1575 //
1576 Handle = *ImageHandle;
1577 }
1578
1579 PERF_LOAD_IMAGE_END (Handle);
1580
1581 return Status;
1582}
1583
1604EFIAPI
1606 IN EFI_HANDLE ImageHandle,
1607 OUT UINTN *ExitDataSize,
1608 OUT CHAR16 **ExitData OPTIONAL
1609 )
1610{
1611 EFI_STATUS Status;
1613 LOADED_IMAGE_PRIVATE_DATA *LastImage;
1614 UINT64 HandleDatabaseKey;
1615 UINTN SetJumpFlag;
1616 EFI_HANDLE Handle;
1617
1618 Handle = ImageHandle;
1619
1620 Image = CoreLoadedImageInfo (ImageHandle);
1621 if ((Image == NULL) || Image->Started) {
1622 return EFI_INVALID_PARAMETER;
1623 }
1624
1625 if (EFI_ERROR (Image->LoadImageStatus)) {
1626 return Image->LoadImageStatus;
1627 }
1628
1629 //
1630 // The image to be started must have the machine type supported by DxeCore.
1631 //
1632 if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->Machine) &&
1633 (Image->PeCoffEmu == NULL))
1634 {
1635 //
1636 // Do not ASSERT here, because image might be loaded via EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED
1637 // But it can not be started.
1638 //
1639 DEBUG ((DEBUG_ERROR, "Image type %s can't be started ", GetMachineTypeName (Image->Machine)));
1640 DEBUG ((DEBUG_ERROR, "on %s UEFI system.\n", GetMachineTypeName (mDxeCoreImageMachineType)));
1641 return EFI_UNSUPPORTED;
1642 }
1643
1644 if (Image->PeCoffEmu != NULL) {
1645 Status = Image->PeCoffEmu->RegisterImage (
1646 Image->PeCoffEmu,
1647 Image->ImageBasePage,
1649 &Image->EntryPoint
1650 );
1651 if (EFI_ERROR (Status)) {
1652 DEBUG ((
1653 DEBUG_LOAD | DEBUG_ERROR,
1654 "CoreLoadPeImage: Failed to register foreign image with emulator - %r\n",
1655 Status
1656 ));
1657 return Status;
1658 }
1659 }
1660
1661 PERF_START_IMAGE_BEGIN (Handle);
1662
1663 //
1664 // Push the current start image context, and
1665 // link the current image to the head. This is the
1666 // only image that can call Exit()
1667 //
1668 HandleDatabaseKey = CoreGetHandleDatabaseKey ();
1669 LastImage = mCurrentImage;
1670 mCurrentImage = Image;
1671 Image->Tpl = gEfiCurrentTpl;
1672
1673 //
1674 // Set long jump for Exit() support
1675 // JumpContext must be aligned on a CPU specific boundary.
1676 // Overallocate the buffer and force the required alignment
1677 //
1678 Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);
1679 if (Image->JumpBuffer == NULL) {
1680 //
1681 // Image may be unloaded after return with failure,
1682 // then ImageHandle may be invalid, so use NULL handle to record perf log.
1683 //
1685
1686 //
1687 // Pop the current start image context
1688 //
1689 mCurrentImage = LastImage;
1690
1691 return EFI_OUT_OF_RESOURCES;
1692 }
1693
1694 Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);
1695
1696 SetJumpFlag = SetJump (Image->JumpContext);
1697 //
1698 // The initial call to SetJump() must always return 0.
1699 // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
1700 //
1701 if (SetJumpFlag == 0) {
1702 RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));
1703 //
1704 // Call the image's entry point
1705 //
1706 Image->Started = TRUE;
1707 Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
1708
1709 //
1710 // Add some debug information if the image returned with error.
1711 // This make the user aware and check if the driver image have already released
1712 // all the resource in this situation.
1713 //
1715 if (EFI_ERROR (Image->Status)) {
1716 DEBUG ((DEBUG_ERROR, "Error: Image at %11p start failed: %r\n", Image->Info.ImageBase, Image->Status));
1717 }
1718
1719 DEBUG_CODE_END ();
1720
1721 //
1722 // If the image returns, exit it through Exit()
1723 //
1724 CoreExit (ImageHandle, Image->Status, 0, NULL);
1725 }
1726
1727 //
1728 // Image has completed. Verify the tpl is the same
1729 //
1730 ASSERT (Image->Tpl == gEfiCurrentTpl);
1731 if (Image->Tpl != gEfiCurrentTpl) {
1732 CoreRestoreTpl (Image->Tpl);
1733 }
1734
1735 CoreFreePool (Image->JumpBuffer);
1736
1737 //
1738 // Pop the current start image context
1739 //
1740 mCurrentImage = LastImage;
1741
1742 //
1743 // UEFI Specification - StartImage() - EFI 1.10 Extension
1744 // To maintain compatibility with UEFI drivers that are written to the EFI
1745 // 1.02 Specification, StartImage() must monitor the handle database before
1746 // and after each image is started. If any handles are created or modified
1747 // when an image is started, then EFI_BOOT_SERVICES.ConnectController() must
1748 // be called with the Recursive parameter set to TRUE for each of the newly
1749 // created or modified handles before StartImage() returns.
1750 //
1751 if (Image->Type != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
1752 CoreConnectHandlesByKey (HandleDatabaseKey);
1753 }
1754
1755 //
1756 // Handle the image's returned ExitData
1757 //
1759 if ((Image->ExitDataSize != 0) || (Image->ExitData != NULL)) {
1760 DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %p", (UINT32)Image->ExitDataSize, Image->ExitData));
1761 if (Image->ExitData != NULL) {
1762 DEBUG ((DEBUG_LOAD, " (%s)", Image->ExitData));
1763 }
1764
1765 DEBUG ((DEBUG_LOAD, "\n"));
1766 }
1767
1768 DEBUG_CODE_END ();
1769
1770 //
1771 // Return the exit data to the caller
1772 //
1773 if ((ExitData != NULL) && (ExitDataSize != NULL)) {
1774 *ExitDataSize = Image->ExitDataSize;
1775 *ExitData = Image->ExitData;
1776 } else {
1777 //
1778 // Caller doesn't want the exit data, free it
1779 //
1780 CoreFreePool (Image->ExitData);
1781 Image->ExitData = NULL;
1782 }
1783
1784 //
1785 // Save the Status because Image will get destroyed if it is unloaded.
1786 //
1787 Status = Image->Status;
1788
1789 //
1790 // If the image returned an error, or if the image is an application
1791 // unload it
1792 //
1793 if (EFI_ERROR (Image->Status) || (Image->Type == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {
1795 //
1796 // ImageHandle may be invalid after the image is unloaded, so use NULL handle to record perf log.
1797 //
1798 Handle = NULL;
1799 }
1800
1801 //
1802 // Done
1803 //
1804 PERF_START_IMAGE_END (Handle);
1805 return Status;
1806}
1807
1832EFIAPI
1834 IN EFI_HANDLE ImageHandle,
1835 IN EFI_STATUS Status,
1836 IN UINTN ExitDataSize,
1837 IN CHAR16 *ExitData OPTIONAL
1838 )
1839{
1841 EFI_TPL OldTpl;
1842
1843 //
1844 // Prevent possible reentrance to this function
1845 // for the same ImageHandle
1846 //
1847 OldTpl = CoreRaiseTpl (TPL_NOTIFY);
1848
1849 Image = CoreLoadedImageInfo (ImageHandle);
1850 if (Image == NULL) {
1851 Status = EFI_INVALID_PARAMETER;
1852 goto Done;
1853 }
1854
1855 if (!Image->Started) {
1856 //
1857 // The image has not been started so just free its resources
1858 //
1860 Status = EFI_SUCCESS;
1861 goto Done;
1862 }
1863
1864 //
1865 // Image has been started, verify this image can exit
1866 //
1867 if (Image != mCurrentImage) {
1868 DEBUG ((DEBUG_LOAD|DEBUG_ERROR, "Exit: Image is not exitable image\n"));
1869 Status = EFI_INVALID_PARAMETER;
1870 goto Done;
1871 }
1872
1873 //
1874 // Set status
1875 //
1876 Image->Status = Status;
1877
1878 //
1879 // If there's ExitData info, move it
1880 //
1881 if (ExitData != NULL) {
1882 Image->ExitDataSize = ExitDataSize;
1883 Image->ExitData = AllocatePool (Image->ExitDataSize);
1884 if (Image->ExitData == NULL) {
1885 Status = EFI_OUT_OF_RESOURCES;
1886 goto Done;
1887 }
1888
1889 CopyMem (Image->ExitData, ExitData, Image->ExitDataSize);
1890 }
1891
1892 CoreRestoreTpl (OldTpl);
1893 //
1894 // return to StartImage
1895 //
1896 LongJump (Image->JumpContext, (UINTN)-1);
1897
1898 //
1899 // If we return from LongJump, then it is an error
1900 //
1901 ASSERT (FALSE);
1902 Status = EFI_ACCESS_DENIED;
1903Done:
1904 CoreRestoreTpl (OldTpl);
1905 return Status;
1906}
1907
1921EFIAPI
1923 IN EFI_HANDLE ImageHandle
1924 )
1925{
1926 EFI_STATUS Status;
1928
1929 Image = CoreLoadedImageInfo (ImageHandle);
1930 if (Image == NULL ) {
1931 //
1932 // The image handle is not valid
1933 //
1934 Status = EFI_INVALID_PARAMETER;
1935 goto Done;
1936 }
1937
1938 if (Image->Started) {
1939 //
1940 // The image has been started, request it to unload.
1941 //
1942 Status = EFI_UNSUPPORTED;
1943 if (Image->Info.Unload != NULL) {
1944 Status = Image->Info.Unload (ImageHandle);
1945 }
1946 } else {
1947 //
1948 // This Image hasn't been started, thus it can be unloaded
1949 //
1950 Status = EFI_SUCCESS;
1951 }
1952
1953 if (!EFI_ERROR (Status)) {
1954 //
1955 // if the Image was not started or Unloaded O.K. then clean up
1956 //
1958 }
1959
1960Done:
1961 return Status;
1962}
UINT64 UINTN
#define FUNCTION_ENTRY_POINT(FunctionPointer)
INT64 INTN
#define MAX_ADDRESS
VOID *EFIAPI InvalidateInstructionCacheRange(IN VOID *Address, IN UINTN Length)
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
Definition: Unaligned.c:191
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
RETURNS_TWICE UINTN EFIAPI SetJump(OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID EFIAPI LongJump(IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, IN UINTN Value)
Definition: LongJump.c:29
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
LOADED_IMAGE_PRIVATE_DATA * CoreLoadedImageInfo(IN EFI_HANDLE ImageHandle)
Definition: Image.c:910
EFI_STATUS CoreLoadPeImage(IN BOOLEAN BootPolicy, IN VOID *Pe32Handle, IN LOADED_IMAGE_PRIVATE_DATA *Image, IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, IN UINT32 Attribute)
Definition: Image.c:579
EFI_STATUS CoreLoadImageCommon(IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN VOID *SourceBuffer OPTIONAL, IN UINTN SourceSize, IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, IN OUT UINTN *NumberOfPages OPTIONAL, OUT EFI_HANDLE *ImageHandle, OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, IN UINT32 Attribute)
Definition: Image.c:1138
VOID CoreUnloadAndCloseImage(IN LOADED_IMAGE_PRIVATE_DATA *Image, IN BOOLEAN FreePage)
Definition: Image.c:941
EFI_STATUS GetPeCoffImageFixLoadingAssignedAddress(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: Image.c:427
EFI_STATUS EFIAPI CoreReadImageFile(IN VOID *UserHandle, IN UINTN Offset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: Image.c:298
EFI_STATUS EFIAPI CoreStartImage(IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, OUT CHAR16 **ExitData OPTIONAL)
Definition: Image.c:1605
EFI_STATUS EFIAPI CoreExit(IN EFI_HANDLE ImageHandle, IN EFI_STATUS Status, IN UINTN ExitDataSize, IN CHAR16 *ExitData OPTIONAL)
Definition: Image.c:1833
EFI_STATUS CheckAndMarkFixLoadingMemoryUsageBitMap(IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINTN ImageSize)
Definition: Image.c:347
EFI_STATUS CoreInitializeImageServices(IN VOID *HobStart)
Definition: Image.c:186
STATIC VOID EFIAPI PeCoffEmuProtocolNotify(IN EFI_EVENT Event, IN VOID *Context)
Definition: Image.c:124
CHAR16 * GetMachineTypeName(UINT16 MachineType)
Definition: Image.c:98
EFI_STATUS EFIAPI CoreLoadImage(IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN VOID *SourceBuffer OPTIONAL, IN UINTN SourceSize, OUT EFI_HANDLE *ImageHandle)
Definition: Image.c:1544
EFI_STATUS EFIAPI CoreUnloadImage(IN EFI_HANDLE ImageHandle)
Definition: Image.c:1922
STATIC BOOLEAN CoreIsImageTypeSupported(IN OUT LOADED_IMAGE_PRIVATE_DATA *Image)
Definition: Image.c:526
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS EFIAPI CoreUninstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Handle.c:805
EFI_STATUS EFIAPI CoreAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, IN OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS EFIAPI CoreHandleProtocol(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface)
Definition: Handle.c:1040
VOID CoreNewDebugImageInfoEntry(IN UINT32 ImageInfoType, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_HANDLE ImageHandle)
VOID CoreRemoveDebugImageInfoEntry(EFI_HANDLE ImageHandle)
EFI_STATUS EFIAPI CoreFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
Definition: Page.c:1808
VOID InsertImageRecord(IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage)
EFI_STATUS UnregisterMemoryProfileImage(IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry)
EFI_STATUS EFIAPI CoreProtocolsPerHandle(IN EFI_HANDLE UserHandle, OUT EFI_GUID ***ProtocolBuffer, OUT UINTN *ProtocolBufferCount)
Definition: Handle.c:1552
VOID ProtectUefiImage(IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath)
EFI_STATUS EFIAPI CoreReinstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *OldInterface, IN VOID *NewInterface)
Definition: Notify.c:173
EFI_TPL EFIAPI CoreRaiseTpl(IN EFI_TPL NewTpl)
Definition: Tpl.c:57
EFI_STATUS EFIAPI CoreLocateHandleBuffer(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
Definition: Locate.c:667
EFI_STATUS EFIAPI CoreLocateDevicePath(IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT EFI_HANDLE *Device)
Definition: Locate.c:448
EFI_TPL gEfiCurrentTpl
Definition: Event.c:17
EFI_STATUS EFIAPI CoreInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
Definition: Handle.c:398
EFI_STATUS CoreInstallProtocolInterfaceNotify(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface, IN BOOLEAN Notify)
Definition: Handle.c:432
EFI_STATUS RegisterMemoryProfileImage(IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, IN EFI_FV_FILETYPE FileType)
VOID CoreConnectHandlesByKey(UINT64 Key)
Definition: Handle.c:1645
EFI_STATUS EFIAPI CoreCloseProtocol(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle)
Definition: Handle.c:1347
EFI_STATUS EFIAPI CoreRegisterProtocolNotify(IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration)
Definition: Notify.c:99
EFI_STATUS EFIAPI CoreLocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *BufferSize, OUT EFI_HANDLE *Buffer)
Definition: Locate.c:269
UINT64 CoreGetHandleDatabaseKey(VOID)
Definition: Handle.c:1630
VOID RemoveImageRecord(IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage)
EFI_STATUS EFIAPI CoreOpenProtocolInformation(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, OUT UINTN *EntryCount)
Definition: Handle.c:1438
VOID EFIAPI CoreRestoreTpl(IN EFI_TPL NewTpl)
Definition: Tpl.c:95
EFI_STATUS EFIAPI CoreCreateEvent(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *Event)
Definition: Event.c:287
EFI_STATUS EFIAPI CoreFreePool(IN VOID *Buffer)
Definition: Pool.c:595
VOID UnprotectUefiImage(IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath)
VOID *EFIAPI GetFileBufferByFilePath(IN BOOLEAN BootPolicy, IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT UINTN *FileSize, OUT UINT32 *AuthenticationStatus)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateRuntimePool(IN UINTN AllocationSize)
#define EFI_LOADED_IMAGE_INFORMATION_REVISION
Definition: LoadedImage.h:38
#define EFI_LOADED_IMAGE_PROTOCOL_REVISION
Definition: LoadedImage.h:33
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#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 GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define BASE_CR(Record, TYPE, Field)
Definition: Base.h:891
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:565
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define DEBUG_CODE_END()
Definition: DebugLib.h:579
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
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 PeCoffLoaderUnloadImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:2033
RETURN_STATUS(EFIAPI * PE_COFF_LOADER_READ_FILE)(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: PeCoffLib.h:65
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 PERF_LOAD_IMAGE_END(ModuleHandle)
#define PERF_START_IMAGE_END(ModuleHandle)
#define PERF_START_IMAGE_BEGIN(ModuleHandle)
#define PERF_LOAD_IMAGE_BEGIN(ModuleHandle)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define EFI_IMAGE_MACHINE_AARCH64
Definition: UefiBaseType.h:238
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
#define EFI_IMAGE_MACHINE_IA32
Definition: UefiBaseType.h:218
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_IMAGE_MACHINE_IA64
Definition: UefiBaseType.h:223
#define EFI_IMAGE_MACHINE_X64
Definition: UefiBaseType.h:233
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiBootServicesCode
@ EfiLoaderData
@ EfiLoaderCode
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1203
EFI_STATUS(EFIAPI * EFI_IMAGE_ENTRY_POINT)(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UefiSpec.h:2121
@ ByRegisterNotify
Definition: UefiSpec.h:1523
@ AllHandles
Definition: UefiSpec.h:1519
@ AllocateAddress
Definition: UefiSpec.h:42
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_LIST_ENTRY ImageHead
A list of type EFI_RUNTIME_IMAGE_ENTRY.
Definition: Runtime.h:108
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_PHYSICAL_ADDRESS EntryPoint
Definition: PiHob.h:217
EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader
Definition: PiHob.h:207
EFI_PHYSICAL_ADDRESS DxeCodeTopAddress
The top address below which the Dxe runtime code and below which the Dxe runtime/boot code and PEI co...
EFI_DEVICE_PATH_PROTOCOL * FilePath
Definition: LoadedImage.h:54
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:53
UINT64 ImageSize
The size in bytes of the loaded image.
Definition: LoadedImage.h:68
EFI_SYSTEM_TABLE * SystemTable
the image's EFI system table pointer.
Definition: LoadedImage.h:48
VOID * ImageBase
The base address at which the image was loaded.
Definition: LoadedImage.h:67
Definition: Base.h:213
EFI_DEVICE_PATH_PROTOCOL * LoadedImageDevicePath
Pointer to Loaded Image Device Path Protocol.
Definition: DxeMain.h:223
EFI_IMAGE_ENTRY_POINT EntryPoint
The image's entry point.
Definition: DxeMain.h:195
EFI_TPL Tpl
Tpl of started image.
Definition: DxeMain.h:205
EFI_HANDLE Handle
Image handle.
Definition: DxeMain.h:189
BASE_LIBRARY_JUMP_BUFFER * JumpContext
Pointer to buffer for context save/restore.
Definition: DxeMain.h:215
VOID * ExitData
Pointer to exit data from started image.
Definition: DxeMain.h:211
UINT16 Machine
Machine type from PE image.
Definition: DxeMain.h:217
UINTN Type
Image type.
Definition: DxeMain.h:191
EFI_PHYSICAL_ADDRESS ImageBasePage
Location in memory.
Definition: DxeMain.h:199
EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL * PeCoffEmu
PE/COFF Image Emulator Protocol pointer.
Definition: DxeMain.h:219
BOOLEAN Started
If entrypoint has been called.
Definition: DxeMain.h:193
VOID * JumpBuffer
Pointer to pool allocation for context save/restore.
Definition: DxeMain.h:213
UINTN NumberOfPages
Number of pages.
Definition: DxeMain.h:201
UINTN ExitDataSize
Size of ExitData from started image.
Definition: DxeMain.h:209
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
PeCoffLoader ImageContext.
Definition: DxeMain.h:225
EFI_STATUS Status
Status returned by started image.
Definition: DxeMain.h:207
EFI_STATUS LoadImageStatus
Status returned by LoadImage() service.
Definition: DxeMain.h:227
EFI_LOADED_IMAGE_PROTOCOL Info
loaded image protocol
Definition: DxeMain.h:197
PHYSICAL_ADDRESS HiiResourceData
Definition: PeCoffLib.h:195