2 Support routines for UEFI memory profile.
4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)
21 MEMORY_PROFILE_CONTEXT Context
;
22 LIST_ENTRY
*DriverInfoList
;
23 } MEMORY_PROFILE_CONTEXT_DATA
;
27 MEMORY_PROFILE_DRIVER_INFO DriverInfo
;
28 LIST_ENTRY
*AllocInfoList
;
30 } MEMORY_PROFILE_DRIVER_INFO_DATA
;
34 MEMORY_PROFILE_ALLOC_INFO AllocInfo
;
36 } MEMORY_PROFILE_ALLOC_INFO_DATA
;
39 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue
);
40 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mMemoryProfileContext
= {
41 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
44 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
45 sizeof (MEMORY_PROFILE_CONTEXT
),
46 MEMORY_PROFILE_CONTEXT_REVISION
58 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA
*mMemoryProfileContextPtr
= NULL
;
60 BOOLEAN mMemoryProfileRecordingStatus
= FALSE
;
63 Get memory profile data.
65 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
66 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
67 On return, points to the size of the data returned in ProfileBuffer.
68 @param[out] ProfileBuffer Profile buffer.
70 @return EFI_SUCCESS Get the memory profile data successfully.
71 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
72 ProfileSize is updated with the size required.
77 ProfileProtocolGetData (
78 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
79 IN OUT UINT64
*ProfileSize
,
80 OUT VOID
*ProfileBuffer
84 Register image to memory profile.
86 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
87 @param[in] FilePath File path of the image.
88 @param[in] ImageBase Image base address.
89 @param[in] ImageSize Image size.
90 @param[in] FileType File type of the image.
92 @return EFI_SUCCESS Register success.
93 @return EFI_OUT_OF_RESOURCE No enough resource for this register.
98 ProfileProtocolRegisterImage (
99 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
100 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
101 IN PHYSICAL_ADDRESS ImageBase
,
103 IN EFI_FV_FILETYPE FileType
107 Unregister image from memory profile.
109 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
110 @param[in] FilePath File path of the image.
111 @param[in] ImageBase Image base address.
112 @param[in] ImageSize Image size.
114 @return EFI_SUCCESS Unregister success.
115 @return EFI_NOT_FOUND The image is not found.
120 ProfileProtocolUnregisterImage (
121 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
122 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
123 IN PHYSICAL_ADDRESS ImageBase
,
127 EDKII_MEMORY_PROFILE_PROTOCOL mProfileProtocol
= {
128 ProfileProtocolGetData
,
129 ProfileProtocolRegisterImage
,
130 ProfileProtocolUnregisterImage
134 Return memory profile context.
136 @return Memory profile context.
139 MEMORY_PROFILE_CONTEXT_DATA
*
140 GetMemoryProfileContext (
144 return mMemoryProfileContextPtr
;
148 Retrieves the magic value from the PE/COFF header.
150 @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
152 @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
153 @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
157 InternalPeCoffGetPeHeaderMagicValue (
158 IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
162 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
163 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
164 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
165 // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
167 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
168 return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
171 // Return the magic value from the PC/COFF Optional Header
173 return Hdr
.Pe32
->OptionalHeader
.Magic
;
177 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
178 If Pe32Data is NULL, then ASSERT().
180 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
182 @return The Subsystem of the PE/COFF image.
186 InternalPeCoffGetSubsystem (
190 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
191 EFI_IMAGE_DOS_HEADER
*DosHdr
;
194 ASSERT (Pe32Data
!= NULL
);
196 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
197 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
199 // DOS image header is present, so read the PE header after the DOS image header.
201 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
204 // DOS image header is not present, so PE header is at the image base.
206 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
209 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
210 return Hdr
.Te
->Subsystem
;
211 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
212 Magic
= InternalPeCoffGetPeHeaderMagicValue (Hdr
);
213 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
214 return Hdr
.Pe32
->OptionalHeader
.Subsystem
;
215 } else if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
216 return Hdr
.Pe32Plus
->OptionalHeader
.Subsystem
;
224 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
225 into system memory with the PE/COFF Loader Library functions.
227 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
228 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
229 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
230 If Pe32Data is NULL, then ASSERT().
231 If EntryPoint is NULL, then ASSERT().
233 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
234 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
236 @retval RETURN_SUCCESS EntryPoint was returned.
237 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
241 InternalPeCoffGetEntryPoint (
243 OUT VOID
**EntryPoint
246 EFI_IMAGE_DOS_HEADER
*DosHdr
;
247 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
249 ASSERT (Pe32Data
!= NULL
);
250 ASSERT (EntryPoint
!= NULL
);
252 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
253 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
255 // DOS image header is present, so read the PE header after the DOS image header.
257 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
260 // DOS image header is not present, so PE header is at the image base.
262 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
266 // Calculate the entry point relative to the start of the image.
267 // AddressOfEntryPoint is common for PE32 & PE32+
269 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
270 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Te
->AddressOfEntryPoint
& 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
);
271 return RETURN_SUCCESS
;
272 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
273 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
& 0x0ffffffff));
274 return RETURN_SUCCESS
;
277 return RETURN_UNSUPPORTED
;
283 @param ContextData Memory profile context.
284 @param FileName File name of the image.
285 @param ImageBase Image base address.
286 @param ImageSize Image size.
287 @param EntryPoint Entry point of the image.
288 @param ImageSubsystem Image subsystem of the image.
289 @param FileType File type of the image.
291 @return Pointer to memory profile driver info.
294 MEMORY_PROFILE_DRIVER_INFO_DATA
*
296 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
297 IN EFI_GUID
*FileName
,
298 IN PHYSICAL_ADDRESS ImageBase
,
300 IN PHYSICAL_ADDRESS EntryPoint
,
301 IN UINT16 ImageSubsystem
,
302 IN EFI_FV_FILETYPE FileType
306 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
307 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
308 VOID
*EntryPointInImage
;
311 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
313 Status
= CoreInternalAllocatePool (
315 sizeof (*DriverInfoData
) + sizeof (LIST_ENTRY
),
316 (VOID
**) &DriverInfoData
318 if (EFI_ERROR (Status
)) {
322 ZeroMem (DriverInfoData
, sizeof (*DriverInfoData
));
324 DriverInfo
= &DriverInfoData
->DriverInfo
;
325 DriverInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
326 DriverInfo
->Header
.Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
327 DriverInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_DRIVER_INFO
);
328 DriverInfo
->Header
.Revision
= MEMORY_PROFILE_DRIVER_INFO_REVISION
;
329 if (FileName
!= NULL
) {
330 CopyMem (&DriverInfo
->FileName
, FileName
, sizeof (EFI_GUID
));
332 DriverInfo
->ImageBase
= ImageBase
;
333 DriverInfo
->ImageSize
= ImageSize
;
334 DriverInfo
->EntryPoint
= EntryPoint
;
335 DriverInfo
->ImageSubsystem
= ImageSubsystem
;
336 if ((EntryPoint
!= 0) && ((EntryPoint
< ImageBase
) || (EntryPoint
>= (ImageBase
+ ImageSize
)))) {
338 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
339 // So patch ImageBuffer here to align the EntryPoint.
341 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
342 ASSERT_EFI_ERROR (Status
);
343 DriverInfo
->ImageBase
= ImageBase
+ EntryPoint
- (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
345 DriverInfo
->FileType
= FileType
;
346 DriverInfoData
->AllocInfoList
= (LIST_ENTRY
*) (DriverInfoData
+ 1);
347 InitializeListHead (DriverInfoData
->AllocInfoList
);
348 DriverInfo
->CurrentUsage
= 0;
349 DriverInfo
->PeakUsage
= 0;
350 DriverInfo
->AllocRecordCount
= 0;
352 InsertTailList (ContextData
->DriverInfoList
, &DriverInfoData
->Link
);
353 ContextData
->Context
.ImageCount
++;
354 ContextData
->Context
.TotalImageSize
+= DriverInfo
->ImageSize
;
356 return DriverInfoData
;
360 Register DXE Core to memory profile.
362 @param HobStart The start address of the HOB.
363 @param ContextData Memory profile context.
365 @retval TRUE Register success.
366 @retval FALSE Register fail.
372 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
375 EFI_PEI_HOB_POINTERS DxeCoreHob
;
376 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
377 PHYSICAL_ADDRESS ImageBase
;
379 ASSERT (ContextData
!= NULL
);
382 // Searching for image hob
384 DxeCoreHob
.Raw
= HobStart
;
385 while ((DxeCoreHob
.Raw
= GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
, DxeCoreHob
.Raw
)) != NULL
) {
386 if (CompareGuid (&DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.Name
, &gEfiHobMemoryAllocModuleGuid
)) {
392 DxeCoreHob
.Raw
= GET_NEXT_HOB (DxeCoreHob
);
394 ASSERT (DxeCoreHob
.Raw
!= NULL
);
396 ImageBase
= DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.MemoryBaseAddress
;
397 DriverInfoData
= BuildDriverInfo (
399 &DxeCoreHob
.MemoryAllocationModule
->ModuleName
,
401 DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.MemoryLength
,
402 DxeCoreHob
.MemoryAllocationModule
->EntryPoint
,
403 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
),
404 EFI_FV_FILETYPE_DXE_CORE
406 if (DriverInfoData
== NULL
) {
414 Initialize memory profile.
416 @param HobStart The start address of the HOB.
424 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
426 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
430 ContextData
= GetMemoryProfileContext ();
431 if (ContextData
!= NULL
) {
435 mMemoryProfileRecordingStatus
= TRUE
;
436 mMemoryProfileContextPtr
= &mMemoryProfileContext
;
438 RegisterDxeCore (HobStart
, &mMemoryProfileContext
);
440 DEBUG ((EFI_D_INFO
, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext
));
444 Install memory profile protocol.
448 MemoryProfileInstallProtocol (
455 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
460 Status
= CoreInstallMultipleProtocolInterfaces (
462 &gEdkiiMemoryProfileGuid
,
466 ASSERT_EFI_ERROR (Status
);
470 Get the GUID file name from the file path.
472 @param FilePath File path.
474 @return The GUID file name from the file path.
478 GetFileNameFromFilePath (
479 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
482 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*ThisFilePath
;
486 if (FilePath
!= NULL
) {
487 ThisFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) FilePath
;
488 while (!IsDevicePathEnd (ThisFilePath
)) {
489 FileName
= EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath
);
490 if (FileName
!= NULL
) {
493 ThisFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) NextDevicePathNode (ThisFilePath
);
501 Register image to memory profile.
503 @param DriverEntry Image info.
504 @param FileType Image file type.
506 @retval TRUE Register success.
507 @retval FALSE Register fail.
511 RegisterMemoryProfileImage (
512 IN LOADED_IMAGE_PRIVATE_DATA
*DriverEntry
,
513 IN EFI_FV_FILETYPE FileType
516 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
517 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
519 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
523 ContextData
= GetMemoryProfileContext ();
524 if (ContextData
== NULL
) {
528 DriverInfoData
= BuildDriverInfo (
530 GetFileNameFromFilePath (DriverEntry
->Info
.FilePath
),
531 DriverEntry
->ImageContext
.ImageAddress
,
532 DriverEntry
->ImageContext
.ImageSize
,
533 DriverEntry
->ImageContext
.EntryPoint
,
534 DriverEntry
->ImageContext
.ImageType
,
537 if (DriverInfoData
== NULL
) {
545 Search image from memory profile.
547 @param ContextData Memory profile context.
548 @param FileName Image file name.
549 @param Address Image Address.
551 @return Pointer to memory profile driver info.
554 MEMORY_PROFILE_DRIVER_INFO_DATA
*
555 GetMemoryProfileDriverInfoByFileNameAndAddress (
556 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
557 IN EFI_GUID
*FileName
,
558 IN PHYSICAL_ADDRESS Address
561 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
562 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
563 LIST_ENTRY
*DriverLink
;
564 LIST_ENTRY
*DriverInfoList
;
566 DriverInfoList
= ContextData
->DriverInfoList
;
568 for (DriverLink
= DriverInfoList
->ForwardLink
;
569 DriverLink
!= DriverInfoList
;
570 DriverLink
= DriverLink
->ForwardLink
) {
571 DriverInfoData
= CR (
573 MEMORY_PROFILE_DRIVER_INFO_DATA
,
575 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
577 DriverInfo
= &DriverInfoData
->DriverInfo
;
578 if ((CompareGuid (&DriverInfo
->FileName
, FileName
)) &&
579 (Address
>= DriverInfo
->ImageBase
) &&
580 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
581 return DriverInfoData
;
589 Search dummy image from memory profile.
591 @param ContextData Memory profile context.
593 @return Pointer to memory profile driver info.
596 MEMORY_PROFILE_DRIVER_INFO_DATA
*
598 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
601 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
602 LIST_ENTRY
*DriverLink
;
603 LIST_ENTRY
*DriverInfoList
;
605 DriverInfoList
= ContextData
->DriverInfoList
;
607 for (DriverLink
= DriverInfoList
->ForwardLink
;
608 DriverLink
!= DriverInfoList
;
609 DriverLink
= DriverLink
->ForwardLink
) {
610 DriverInfoData
= CR (
612 MEMORY_PROFILE_DRIVER_INFO_DATA
,
614 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
616 if (CompareGuid (&gZeroGuid
, &DriverInfoData
->DriverInfo
.FileName
)) {
617 return DriverInfoData
;
621 return BuildDriverInfo (ContextData
, &gZeroGuid
, 0, 0, 0, 0, 0);
625 Search image from memory profile.
626 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)
628 @param ContextData Memory profile context.
629 @param Address Image or Function address.
631 @return Pointer to memory profile driver info.
634 MEMORY_PROFILE_DRIVER_INFO_DATA
*
635 GetMemoryProfileDriverInfoFromAddress (
636 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
637 IN PHYSICAL_ADDRESS Address
640 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
641 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
642 LIST_ENTRY
*DriverLink
;
643 LIST_ENTRY
*DriverInfoList
;
645 DriverInfoList
= ContextData
->DriverInfoList
;
647 for (DriverLink
= DriverInfoList
->ForwardLink
;
648 DriverLink
!= DriverInfoList
;
649 DriverLink
= DriverLink
->ForwardLink
) {
650 DriverInfoData
= CR (
652 MEMORY_PROFILE_DRIVER_INFO_DATA
,
654 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
656 DriverInfo
= &DriverInfoData
->DriverInfo
;
657 if ((Address
>= DriverInfo
->ImageBase
) &&
658 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
659 return DriverInfoData
;
664 // Should never come here.
666 return FindDummyImage (ContextData
);
670 Unregister image from memory profile.
672 @param DriverEntry Image info.
674 @retval TRUE Unregister success.
675 @retval FALSE Unregister fail.
679 UnregisterMemoryProfileImage (
680 IN LOADED_IMAGE_PRIVATE_DATA
*DriverEntry
684 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
685 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
687 PHYSICAL_ADDRESS ImageAddress
;
688 VOID
*EntryPointInImage
;
690 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
694 ContextData
= GetMemoryProfileContext ();
695 if (ContextData
== NULL
) {
699 DriverInfoData
= NULL
;
700 FileName
= GetFileNameFromFilePath (DriverEntry
->Info
.FilePath
);
701 ImageAddress
= DriverEntry
->ImageContext
.ImageAddress
;
702 if ((DriverEntry
->ImageContext
.EntryPoint
< ImageAddress
) || (DriverEntry
->ImageContext
.EntryPoint
>= (ImageAddress
+ DriverEntry
->ImageContext
.ImageSize
))) {
704 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
705 // So patch ImageAddress here to align the EntryPoint.
707 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageAddress
, &EntryPointInImage
);
708 ASSERT_EFI_ERROR (Status
);
709 ImageAddress
= ImageAddress
+ (UINTN
) DriverEntry
->ImageContext
.EntryPoint
- (UINTN
) EntryPointInImage
;
711 if (FileName
!= NULL
) {
712 DriverInfoData
= GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData
, FileName
, ImageAddress
);
714 if (DriverInfoData
== NULL
) {
715 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, ImageAddress
);
717 if (DriverInfoData
== NULL
) {
721 ContextData
->Context
.TotalImageSize
-= DriverInfoData
->DriverInfo
.ImageSize
;
723 DriverInfoData
->DriverInfo
.ImageBase
= 0;
724 DriverInfoData
->DriverInfo
.ImageSize
= 0;
726 if (DriverInfoData
->DriverInfo
.PeakUsage
== 0) {
727 ContextData
->Context
.ImageCount
--;
728 RemoveEntryList (&DriverInfoData
->Link
);
730 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
732 CoreInternalFreePool (DriverInfoData
);
739 Return if this memory type needs to be recorded into memory profile.
740 If BIOS memory type (0 ~ EfiMaxMemoryType), it checks bit (1 << MemoryType).
741 If OS memory type (0x80000000 ~ 0xFFFFFFFF), it checks bit63 - 0x8000000000000000.
743 @param MemoryType Memory type.
745 @retval TRUE This memory type need to be recorded.
746 @retval FALSE This memory type need not to be recorded.
750 CoreNeedRecordProfile (
751 IN EFI_MEMORY_TYPE MemoryType
756 if ((UINT32
) MemoryType
>= 0x80000000) {
759 TestBit
= LShiftU64 (1, MemoryType
);
762 if ((PcdGet64 (PcdMemoryProfileMemoryType
) & TestBit
) != 0) {
770 Convert EFI memory type to profile memory index. The rule is:
771 If BIOS memory type (0 ~ EfiMaxMemoryType), ProfileMemoryIndex = MemoryType.
772 If OS memory type (0x80000000 ~ 0xFFFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType.
774 @param MemoryType Memory type.
776 @return EFI memory type as profile memory index.
780 GetProfileMemoryIndex (
781 IN EFI_MEMORY_TYPE MemoryType
784 if ((UINT32
) MemoryType
>= 0x80000000) {
785 return EfiMaxMemoryType
;
792 Update memory profile Allocate information.
794 @param CallerAddress Address of caller who call Allocate.
795 @param Action This Allocate action.
796 @param MemoryType Memory type.
797 @param Size Buffer size.
798 @param Buffer Buffer address.
800 @retval TRUE Profile udpate success.
801 @retval FALSE Profile update fail.
805 CoreUpdateProfileAllocate (
806 IN PHYSICAL_ADDRESS CallerAddress
,
807 IN MEMORY_PROFILE_ACTION Action
,
808 IN EFI_MEMORY_TYPE MemoryType
,
814 MEMORY_PROFILE_CONTEXT
*Context
;
815 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
816 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
817 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
818 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
819 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
820 EFI_MEMORY_TYPE ProfileMemoryIndex
;
822 AllocInfoData
= NULL
;
824 ContextData
= GetMemoryProfileContext ();
825 if (ContextData
== NULL
) {
829 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
830 ASSERT (DriverInfoData
!= NULL
);
833 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
835 Status
= CoreInternalAllocatePool (
837 sizeof (*AllocInfoData
),
838 (VOID
**) &AllocInfoData
840 if (EFI_ERROR (Status
)) {
843 ASSERT (AllocInfoData
!= NULL
);
844 AllocInfo
= &AllocInfoData
->AllocInfo
;
845 AllocInfoData
->Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
846 AllocInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
847 AllocInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_ALLOC_INFO
);
848 AllocInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_INFO_REVISION
;
849 AllocInfo
->CallerAddress
= CallerAddress
;
850 AllocInfo
->SequenceId
= ContextData
->Context
.SequenceCount
;
851 AllocInfo
->Action
= Action
;
852 AllocInfo
->MemoryType
= MemoryType
;
853 AllocInfo
->Buffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
854 AllocInfo
->Size
= Size
;
856 InsertTailList (DriverInfoData
->AllocInfoList
, &AllocInfoData
->Link
);
858 ProfileMemoryIndex
= GetProfileMemoryIndex (MemoryType
);
860 DriverInfo
= &DriverInfoData
->DriverInfo
;
861 DriverInfo
->CurrentUsage
+= Size
;
862 if (DriverInfo
->PeakUsage
< DriverInfo
->CurrentUsage
) {
863 DriverInfo
->PeakUsage
= DriverInfo
->CurrentUsage
;
865 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] += Size
;
866 if (DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] < DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
]) {
867 DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] = DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
];
869 DriverInfo
->AllocRecordCount
++;
871 Context
= &ContextData
->Context
;
872 Context
->CurrentTotalUsage
+= Size
;
873 if (Context
->PeakTotalUsage
< Context
->CurrentTotalUsage
) {
874 Context
->PeakTotalUsage
= Context
->CurrentTotalUsage
;
876 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] += Size
;
877 if (Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] < Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
]) {
878 Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] = Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
];
880 Context
->SequenceCount
++;
886 Get memory profile alloc info from memory profile
888 @param DriverInfoData Driver info
889 @param Action This Free action
890 @param Size Buffer size
891 @param Buffer Buffer address
893 @return Pointer to memory profile alloc info.
895 MEMORY_PROFILE_ALLOC_INFO_DATA
*
896 GetMemoryProfileAllocInfoFromAddress (
897 IN MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
,
898 IN MEMORY_PROFILE_ACTION Action
,
903 LIST_ENTRY
*AllocInfoList
;
904 LIST_ENTRY
*AllocLink
;
905 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
906 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
908 AllocInfoList
= DriverInfoData
->AllocInfoList
;
910 for (AllocLink
= AllocInfoList
->ForwardLink
;
911 AllocLink
!= AllocInfoList
;
912 AllocLink
= AllocLink
->ForwardLink
) {
915 MEMORY_PROFILE_ALLOC_INFO_DATA
,
917 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
919 AllocInfo
= &AllocInfoData
->AllocInfo
;
920 if (AllocInfo
->Action
!= Action
) {
924 case MemoryProfileActionAllocatePages
:
925 if ((AllocInfo
->Buffer
<= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) &&
926 ((AllocInfo
->Buffer
+ AllocInfo
->Size
) >= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
))) {
927 return AllocInfoData
;
930 case MemoryProfileActionAllocatePool
:
931 if (AllocInfo
->Buffer
== (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
932 return AllocInfoData
;
945 Update memory profile Free information.
947 @param CallerAddress Address of caller who call Free.
948 @param Action This Free action.
949 @param Size Buffer size.
950 @param Buffer Buffer address.
952 @retval TRUE Profile udpate success.
953 @retval FALSE Profile update fail.
957 CoreUpdateProfileFree (
958 IN PHYSICAL_ADDRESS CallerAddress
,
959 IN MEMORY_PROFILE_ACTION Action
,
964 MEMORY_PROFILE_CONTEXT
*Context
;
965 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
966 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
967 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
968 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
969 LIST_ENTRY
*DriverLink
;
970 LIST_ENTRY
*DriverInfoList
;
971 MEMORY_PROFILE_DRIVER_INFO_DATA
*ThisDriverInfoData
;
972 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
973 EFI_MEMORY_TYPE ProfileMemoryIndex
;
975 ContextData
= GetMemoryProfileContext ();
976 if (ContextData
== NULL
) {
980 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
981 ASSERT (DriverInfoData
!= NULL
);
984 case MemoryProfileActionFreePages
:
985 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
987 case MemoryProfileActionFreePool
:
988 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
992 AllocInfoData
= NULL
;
995 if (AllocInfoData
== NULL
) {
997 // Legal case, because driver A might free memory allocated by driver B, by some protocol.
999 DriverInfoList
= ContextData
->DriverInfoList
;
1001 for (DriverLink
= DriverInfoList
->ForwardLink
;
1002 DriverLink
!= DriverInfoList
;
1003 DriverLink
= DriverLink
->ForwardLink
) {
1004 ThisDriverInfoData
= CR (
1006 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1008 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1011 case MemoryProfileActionFreePages
:
1012 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
1014 case MemoryProfileActionFreePool
:
1015 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
1019 AllocInfoData
= NULL
;
1022 if (AllocInfoData
!= NULL
) {
1023 DriverInfoData
= ThisDriverInfoData
;
1028 if (AllocInfoData
== NULL
) {
1030 // No matched allocate operation is found for this free operation.
1031 // It is because the specified memory type allocate operation has been
1032 // filtered by CoreNeedRecordProfile(), but free operations have no
1033 // memory type information, they can not be filtered by CoreNeedRecordProfile().
1034 // Then, they will be filtered here.
1040 Context
= &ContextData
->Context
;
1041 DriverInfo
= &DriverInfoData
->DriverInfo
;
1042 AllocInfo
= &AllocInfoData
->AllocInfo
;
1044 ProfileMemoryIndex
= GetProfileMemoryIndex (AllocInfo
->MemoryType
);
1046 Context
->CurrentTotalUsage
-= AllocInfo
->Size
;
1047 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1049 DriverInfo
->CurrentUsage
-= AllocInfo
->Size
;
1050 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1051 DriverInfo
->AllocRecordCount
--;
1053 RemoveEntryList (&AllocInfoData
->Link
);
1055 if (Action
== MemoryProfileActionFreePages
) {
1056 if (AllocInfo
->Buffer
!= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
1057 CoreUpdateProfileAllocate (
1058 AllocInfo
->CallerAddress
,
1059 MemoryProfileActionAllocatePages
,
1060 AllocInfo
->MemoryType
,
1061 (UINTN
) ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
- AllocInfo
->Buffer
),
1062 (VOID
*) (UINTN
) AllocInfo
->Buffer
1065 if (AllocInfo
->Buffer
+ AllocInfo
->Size
!= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)) {
1066 CoreUpdateProfileAllocate (
1067 AllocInfo
->CallerAddress
,
1068 MemoryProfileActionAllocatePages
,
1069 AllocInfo
->MemoryType
,
1070 (UINTN
) ((AllocInfo
->Buffer
+ AllocInfo
->Size
) - ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)),
1071 (VOID
*) ((UINTN
) Buffer
+ Size
)
1077 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
1079 CoreInternalFreePool (AllocInfoData
);
1085 Update memory profile information.
1087 @param CallerAddress Address of caller who call Allocate or Free.
1088 @param Action This Allocate or Free action.
1089 @param MemoryType Memory type.
1090 @param Size Buffer size.
1091 @param Buffer Buffer address.
1093 @retval TRUE Profile udpate success.
1094 @retval FALSE Profile update fail.
1099 IN PHYSICAL_ADDRESS CallerAddress
,
1100 IN MEMORY_PROFILE_ACTION Action
,
1101 IN EFI_MEMORY_TYPE MemoryType
, // Valid for AllocatePages/AllocatePool
1102 IN UINTN Size
, // Valid for AllocatePages/FreePages/AllocatePool
1106 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1108 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
1112 if (!mMemoryProfileRecordingStatus
) {
1117 // Free operations have no memory type information, so skip the check.
1119 if ((Action
== MemoryProfileActionAllocatePages
) || (Action
== MemoryProfileActionAllocatePool
)) {
1121 // Only record limited MemoryType.
1123 if (!CoreNeedRecordProfile (MemoryType
)) {
1128 ContextData
= GetMemoryProfileContext ();
1129 if (ContextData
== NULL
) {
1134 case MemoryProfileActionAllocatePages
:
1135 CoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1137 case MemoryProfileActionFreePages
:
1138 CoreUpdateProfileFree (CallerAddress
, Action
, Size
, Buffer
);
1140 case MemoryProfileActionAllocatePool
:
1141 CoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1143 case MemoryProfileActionFreePool
:
1144 CoreUpdateProfileFree (CallerAddress
, Action
, 0, Buffer
);
1153 ////////////////////
1156 Get memory profile data size.
1158 @return Memory profile data size.
1162 MemoryProfileGetDataSize (
1166 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1167 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1168 LIST_ENTRY
*DriverInfoList
;
1169 LIST_ENTRY
*DriverLink
;
1173 ContextData
= GetMemoryProfileContext ();
1174 if (ContextData
== NULL
) {
1178 TotalSize
= sizeof (MEMORY_PROFILE_CONTEXT
);
1179 TotalSize
+= sizeof (MEMORY_PROFILE_DRIVER_INFO
) * (UINTN
) ContextData
->Context
.ImageCount
;
1181 DriverInfoList
= ContextData
->DriverInfoList
;
1182 for (DriverLink
= DriverInfoList
->ForwardLink
;
1183 DriverLink
!= DriverInfoList
;
1184 DriverLink
= DriverLink
->ForwardLink
) {
1185 DriverInfoData
= CR (
1187 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1189 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1191 TotalSize
+= sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfoData
->DriverInfo
.AllocRecordCount
;
1198 Copy memory profile data.
1200 @param ProfileBuffer The buffer to hold memory profile data.
1204 MemoryProfileCopyData (
1205 IN VOID
*ProfileBuffer
1208 MEMORY_PROFILE_CONTEXT
*Context
;
1209 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1210 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1211 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1212 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1213 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1214 LIST_ENTRY
*DriverInfoList
;
1215 LIST_ENTRY
*DriverLink
;
1216 LIST_ENTRY
*AllocInfoList
;
1217 LIST_ENTRY
*AllocLink
;
1219 ContextData
= GetMemoryProfileContext ();
1220 if (ContextData
== NULL
) {
1224 Context
= ProfileBuffer
;
1225 CopyMem (Context
, &ContextData
->Context
, sizeof (MEMORY_PROFILE_CONTEXT
));
1226 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) (Context
+ 1);
1228 DriverInfoList
= ContextData
->DriverInfoList
;
1229 for (DriverLink
= DriverInfoList
->ForwardLink
;
1230 DriverLink
!= DriverInfoList
;
1231 DriverLink
= DriverLink
->ForwardLink
) {
1232 DriverInfoData
= CR (
1234 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1236 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1238 CopyMem (DriverInfo
, &DriverInfoData
->DriverInfo
, sizeof (MEMORY_PROFILE_DRIVER_INFO
));
1239 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) (DriverInfo
+ 1);
1241 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1242 for (AllocLink
= AllocInfoList
->ForwardLink
;
1243 AllocLink
!= AllocInfoList
;
1244 AllocLink
= AllocLink
->ForwardLink
) {
1245 AllocInfoData
= CR (
1247 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1249 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1251 CopyMem (AllocInfo
, &AllocInfoData
->AllocInfo
, sizeof (MEMORY_PROFILE_ALLOC_INFO
));
1255 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) (DriverInfo
+ 1) + sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfo
->AllocRecordCount
);
1260 Get memory profile data.
1262 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1263 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
1264 On return, points to the size of the data returned in ProfileBuffer.
1265 @param[out] ProfileBuffer Profile buffer.
1267 @return EFI_SUCCESS Get the memory profile data successfully.
1268 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
1269 ProfileSize is updated with the size required.
1274 ProfileProtocolGetData (
1275 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1276 IN OUT UINT64
*ProfileSize
,
1277 OUT VOID
*ProfileBuffer
1281 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1282 BOOLEAN MemoryProfileRecordingStatus
;
1284 ContextData
= GetMemoryProfileContext ();
1285 if (ContextData
== NULL
) {
1286 return EFI_UNSUPPORTED
;
1289 MemoryProfileRecordingStatus
= mMemoryProfileRecordingStatus
;
1290 mMemoryProfileRecordingStatus
= FALSE
;
1292 Size
= MemoryProfileGetDataSize ();
1294 if (*ProfileSize
< Size
) {
1295 *ProfileSize
= Size
;
1296 mMemoryProfileRecordingStatus
= MemoryProfileRecordingStatus
;
1297 return EFI_BUFFER_TOO_SMALL
;
1300 *ProfileSize
= Size
;
1301 MemoryProfileCopyData (ProfileBuffer
);
1303 mMemoryProfileRecordingStatus
= MemoryProfileRecordingStatus
;
1308 Register image to memory profile.
1310 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1311 @param[in] FilePath File path of the image.
1312 @param[in] ImageBase Image base address.
1313 @param[in] ImageSize Image size.
1314 @param[in] FileType File type of the image.
1316 @return EFI_SUCCESS Register success.
1317 @return EFI_OUT_OF_RESOURCE No enough resource for this register.
1322 ProfileProtocolRegisterImage (
1323 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1324 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
1325 IN PHYSICAL_ADDRESS ImageBase
,
1326 IN UINT64 ImageSize
,
1327 IN EFI_FV_FILETYPE FileType
1331 LOADED_IMAGE_PRIVATE_DATA DriverEntry
;
1332 VOID
*EntryPointInImage
;
1334 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1335 DriverEntry
.Info
.FilePath
= FilePath
;
1336 DriverEntry
.ImageContext
.ImageAddress
= ImageBase
;
1337 DriverEntry
.ImageContext
.ImageSize
= ImageSize
;
1338 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
1339 ASSERT_EFI_ERROR (Status
);
1340 DriverEntry
.ImageContext
.EntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1341 DriverEntry
.ImageContext
.ImageType
= InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
);
1343 return RegisterMemoryProfileImage (&DriverEntry
, FileType
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
1347 Unregister image from memory profile.
1349 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1350 @param[in] FilePath File path of the image.
1351 @param[in] ImageBase Image base address.
1352 @param[in] ImageSize Image size.
1354 @return EFI_SUCCESS Unregister success.
1355 @return EFI_NOT_FOUND The image is not found.
1360 ProfileProtocolUnregisterImage (
1361 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1362 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
1363 IN PHYSICAL_ADDRESS ImageBase
,
1368 LOADED_IMAGE_PRIVATE_DATA DriverEntry
;
1369 VOID
*EntryPointInImage
;
1371 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1372 DriverEntry
.Info
.FilePath
= FilePath
;
1373 DriverEntry
.ImageContext
.ImageAddress
= ImageBase
;
1374 DriverEntry
.ImageContext
.ImageSize
= ImageSize
;
1375 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
1376 ASSERT_EFI_ERROR (Status
);
1377 DriverEntry
.ImageContext
.EntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1379 return UnregisterMemoryProfileImage (&DriverEntry
) ? EFI_SUCCESS
: EFI_NOT_FOUND
;
1382 ////////////////////