2 Support routines for UEFI memory profile.
4 Copyright (c) 2014 - 2016, 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.
18 #define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)
22 MEMORY_PROFILE_CONTEXT Context
;
23 LIST_ENTRY
*DriverInfoList
;
24 } MEMORY_PROFILE_CONTEXT_DATA
;
28 MEMORY_PROFILE_DRIVER_INFO DriverInfo
;
29 LIST_ENTRY
*AllocInfoList
;
31 } MEMORY_PROFILE_DRIVER_INFO_DATA
;
35 MEMORY_PROFILE_ALLOC_INFO AllocInfo
;
37 } MEMORY_PROFILE_ALLOC_INFO_DATA
;
40 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue
);
41 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mMemoryProfileContext
= {
42 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
45 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
46 sizeof (MEMORY_PROFILE_CONTEXT
),
47 MEMORY_PROFILE_CONTEXT_REVISION
59 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA
*mMemoryProfileContextPtr
= NULL
;
61 BOOLEAN mMemoryProfileRecordingStatus
= FALSE
;
64 Get memory profile data.
66 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
67 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
68 On return, points to the size of the data returned in ProfileBuffer.
69 @param[out] ProfileBuffer Profile buffer.
71 @return EFI_SUCCESS Get the memory profile data successfully.
72 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
73 ProfileSize is updated with the size required.
78 ProfileProtocolGetData (
79 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
80 IN OUT UINT64
*ProfileSize
,
81 OUT VOID
*ProfileBuffer
85 Register image to memory profile.
87 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
88 @param[in] FilePath File path of the image.
89 @param[in] ImageBase Image base address.
90 @param[in] ImageSize Image size.
91 @param[in] FileType File type of the image.
93 @return EFI_SUCCESS Register success.
94 @return EFI_OUT_OF_RESOURCE No enough resource for this register.
99 ProfileProtocolRegisterImage (
100 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
101 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
102 IN PHYSICAL_ADDRESS ImageBase
,
104 IN EFI_FV_FILETYPE FileType
108 Unregister image from memory profile.
110 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
111 @param[in] FilePath File path of the image.
112 @param[in] ImageBase Image base address.
113 @param[in] ImageSize Image size.
115 @return EFI_SUCCESS Unregister success.
116 @return EFI_NOT_FOUND The image is not found.
121 ProfileProtocolUnregisterImage (
122 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
123 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
124 IN PHYSICAL_ADDRESS ImageBase
,
128 EDKII_MEMORY_PROFILE_PROTOCOL mProfileProtocol
= {
129 ProfileProtocolGetData
,
130 ProfileProtocolRegisterImage
,
131 ProfileProtocolUnregisterImage
135 Return memory profile context.
137 @return Memory profile context.
140 MEMORY_PROFILE_CONTEXT_DATA
*
141 GetMemoryProfileContext (
145 return mMemoryProfileContextPtr
;
149 Retrieves the magic value from the PE/COFF header.
151 @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
153 @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
154 @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
158 InternalPeCoffGetPeHeaderMagicValue (
159 IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
163 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
164 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
165 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
166 // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
168 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
169 return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
172 // Return the magic value from the PC/COFF Optional Header
174 return Hdr
.Pe32
->OptionalHeader
.Magic
;
178 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
179 If Pe32Data is NULL, then ASSERT().
181 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
183 @return The Subsystem of the PE/COFF image.
187 InternalPeCoffGetSubsystem (
191 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
192 EFI_IMAGE_DOS_HEADER
*DosHdr
;
195 ASSERT (Pe32Data
!= NULL
);
197 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
198 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
200 // DOS image header is present, so read the PE header after the DOS image header.
202 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
205 // DOS image header is not present, so PE header is at the image base.
207 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
210 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
211 return Hdr
.Te
->Subsystem
;
212 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
213 Magic
= InternalPeCoffGetPeHeaderMagicValue (Hdr
);
214 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
215 return Hdr
.Pe32
->OptionalHeader
.Subsystem
;
216 } else if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
217 return Hdr
.Pe32Plus
->OptionalHeader
.Subsystem
;
225 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
226 into system memory with the PE/COFF Loader Library functions.
228 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
229 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
230 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
231 If Pe32Data is NULL, then ASSERT().
232 If EntryPoint is NULL, then ASSERT().
234 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
235 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
237 @retval RETURN_SUCCESS EntryPoint was returned.
238 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
242 InternalPeCoffGetEntryPoint (
244 OUT VOID
**EntryPoint
247 EFI_IMAGE_DOS_HEADER
*DosHdr
;
248 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
250 ASSERT (Pe32Data
!= NULL
);
251 ASSERT (EntryPoint
!= NULL
);
253 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
254 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
256 // DOS image header is present, so read the PE header after the DOS image header.
258 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
261 // DOS image header is not present, so PE header is at the image base.
263 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
267 // Calculate the entry point relative to the start of the image.
268 // AddressOfEntryPoint is common for PE32 & PE32+
270 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
271 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Te
->AddressOfEntryPoint
& 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
);
272 return RETURN_SUCCESS
;
273 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
274 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
& 0x0ffffffff));
275 return RETURN_SUCCESS
;
278 return RETURN_UNSUPPORTED
;
284 @param ContextData Memory profile context.
285 @param FileName File name of the image.
286 @param ImageBase Image base address.
287 @param ImageSize Image size.
288 @param EntryPoint Entry point of the image.
289 @param ImageSubsystem Image subsystem of the image.
290 @param FileType File type of the image.
292 @return Pointer to memory profile driver info.
295 MEMORY_PROFILE_DRIVER_INFO_DATA
*
297 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
298 IN EFI_GUID
*FileName
,
299 IN PHYSICAL_ADDRESS ImageBase
,
301 IN PHYSICAL_ADDRESS EntryPoint
,
302 IN UINT16 ImageSubsystem
,
303 IN EFI_FV_FILETYPE FileType
307 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
308 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
309 VOID
*EntryPointInImage
;
312 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
314 Status
= CoreInternalAllocatePool (
316 sizeof (*DriverInfoData
) + sizeof (LIST_ENTRY
),
317 (VOID
**) &DriverInfoData
319 if (EFI_ERROR (Status
)) {
323 ZeroMem (DriverInfoData
, sizeof (*DriverInfoData
));
325 DriverInfo
= &DriverInfoData
->DriverInfo
;
326 DriverInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
327 DriverInfo
->Header
.Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
328 DriverInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_DRIVER_INFO
);
329 DriverInfo
->Header
.Revision
= MEMORY_PROFILE_DRIVER_INFO_REVISION
;
330 if (FileName
!= NULL
) {
331 CopyMem (&DriverInfo
->FileName
, FileName
, sizeof (EFI_GUID
));
333 DriverInfo
->ImageBase
= ImageBase
;
334 DriverInfo
->ImageSize
= ImageSize
;
335 DriverInfo
->EntryPoint
= EntryPoint
;
336 DriverInfo
->ImageSubsystem
= ImageSubsystem
;
337 if ((EntryPoint
!= 0) && ((EntryPoint
< ImageBase
) || (EntryPoint
>= (ImageBase
+ ImageSize
)))) {
339 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
340 // So patch ImageBuffer here to align the EntryPoint.
342 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
343 ASSERT_EFI_ERROR (Status
);
344 DriverInfo
->ImageBase
= ImageBase
+ EntryPoint
- (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
346 DriverInfo
->FileType
= FileType
;
347 DriverInfoData
->AllocInfoList
= (LIST_ENTRY
*) (DriverInfoData
+ 1);
348 InitializeListHead (DriverInfoData
->AllocInfoList
);
349 DriverInfo
->CurrentUsage
= 0;
350 DriverInfo
->PeakUsage
= 0;
351 DriverInfo
->AllocRecordCount
= 0;
353 InsertTailList (ContextData
->DriverInfoList
, &DriverInfoData
->Link
);
354 ContextData
->Context
.ImageCount
++;
355 ContextData
->Context
.TotalImageSize
+= DriverInfo
->ImageSize
;
357 return DriverInfoData
;
361 Register DXE Core to memory profile.
363 @param HobStart The start address of the HOB.
364 @param ContextData Memory profile context.
366 @retval TRUE Register success.
367 @retval FALSE Register fail.
373 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
376 EFI_PEI_HOB_POINTERS DxeCoreHob
;
377 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
378 PHYSICAL_ADDRESS ImageBase
;
380 ASSERT (ContextData
!= NULL
);
383 // Searching for image hob
385 DxeCoreHob
.Raw
= HobStart
;
386 while ((DxeCoreHob
.Raw
= GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
, DxeCoreHob
.Raw
)) != NULL
) {
387 if (CompareGuid (&DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.Name
, &gEfiHobMemoryAllocModuleGuid
)) {
393 DxeCoreHob
.Raw
= GET_NEXT_HOB (DxeCoreHob
);
395 ASSERT (DxeCoreHob
.Raw
!= NULL
);
397 ImageBase
= DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.MemoryBaseAddress
;
398 DriverInfoData
= BuildDriverInfo (
400 &DxeCoreHob
.MemoryAllocationModule
->ModuleName
,
402 DxeCoreHob
.MemoryAllocationModule
->MemoryAllocationHeader
.MemoryLength
,
403 DxeCoreHob
.MemoryAllocationModule
->EntryPoint
,
404 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
),
405 EFI_FV_FILETYPE_DXE_CORE
407 if (DriverInfoData
== NULL
) {
415 Initialize memory profile.
417 @param HobStart The start address of the HOB.
425 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
427 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
431 ContextData
= GetMemoryProfileContext ();
432 if (ContextData
!= NULL
) {
436 mMemoryProfileRecordingStatus
= TRUE
;
437 mMemoryProfileContextPtr
= &mMemoryProfileContext
;
439 RegisterDxeCore (HobStart
, &mMemoryProfileContext
);
441 DEBUG ((EFI_D_INFO
, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext
));
445 Install memory profile protocol.
449 MemoryProfileInstallProtocol (
456 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
461 Status
= CoreInstallMultipleProtocolInterfaces (
463 &gEdkiiMemoryProfileGuid
,
467 ASSERT_EFI_ERROR (Status
);
471 Get the GUID file name from the file path.
473 @param FilePath File path.
475 @return The GUID file name from the file path.
479 GetFileNameFromFilePath (
480 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
483 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*ThisFilePath
;
487 if (FilePath
!= NULL
) {
488 ThisFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) FilePath
;
489 while (!IsDevicePathEnd (ThisFilePath
)) {
490 FileName
= EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath
);
491 if (FileName
!= NULL
) {
494 ThisFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) NextDevicePathNode (ThisFilePath
);
502 Register image to memory profile.
504 @param DriverEntry Image info.
505 @param FileType Image file type.
507 @retval TRUE Register success.
508 @retval FALSE Register fail.
512 RegisterMemoryProfileImage (
513 IN LOADED_IMAGE_PRIVATE_DATA
*DriverEntry
,
514 IN EFI_FV_FILETYPE FileType
517 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
518 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
520 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
524 ContextData
= GetMemoryProfileContext ();
525 if (ContextData
== NULL
) {
529 DriverInfoData
= BuildDriverInfo (
531 GetFileNameFromFilePath (DriverEntry
->Info
.FilePath
),
532 DriverEntry
->ImageContext
.ImageAddress
,
533 DriverEntry
->ImageContext
.ImageSize
,
534 DriverEntry
->ImageContext
.EntryPoint
,
535 DriverEntry
->ImageContext
.ImageType
,
538 if (DriverInfoData
== NULL
) {
546 Search image from memory profile.
548 @param ContextData Memory profile context.
549 @param FileName Image file name.
550 @param Address Image Address.
552 @return Pointer to memory profile driver info.
555 MEMORY_PROFILE_DRIVER_INFO_DATA
*
556 GetMemoryProfileDriverInfoByFileNameAndAddress (
557 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
558 IN EFI_GUID
*FileName
,
559 IN PHYSICAL_ADDRESS Address
562 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
563 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
564 LIST_ENTRY
*DriverLink
;
565 LIST_ENTRY
*DriverInfoList
;
567 DriverInfoList
= ContextData
->DriverInfoList
;
569 for (DriverLink
= DriverInfoList
->ForwardLink
;
570 DriverLink
!= DriverInfoList
;
571 DriverLink
= DriverLink
->ForwardLink
) {
572 DriverInfoData
= CR (
574 MEMORY_PROFILE_DRIVER_INFO_DATA
,
576 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
578 DriverInfo
= &DriverInfoData
->DriverInfo
;
579 if ((CompareGuid (&DriverInfo
->FileName
, FileName
)) &&
580 (Address
>= DriverInfo
->ImageBase
) &&
581 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
582 return DriverInfoData
;
590 Search dummy image from memory profile.
592 @param ContextData Memory profile context.
594 @return Pointer to memory profile driver info.
597 MEMORY_PROFILE_DRIVER_INFO_DATA
*
599 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
602 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
603 LIST_ENTRY
*DriverLink
;
604 LIST_ENTRY
*DriverInfoList
;
606 DriverInfoList
= ContextData
->DriverInfoList
;
608 for (DriverLink
= DriverInfoList
->ForwardLink
;
609 DriverLink
!= DriverInfoList
;
610 DriverLink
= DriverLink
->ForwardLink
) {
611 DriverInfoData
= CR (
613 MEMORY_PROFILE_DRIVER_INFO_DATA
,
615 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
617 if (CompareGuid (&gZeroGuid
, &DriverInfoData
->DriverInfo
.FileName
)) {
618 return DriverInfoData
;
622 return BuildDriverInfo (ContextData
, &gZeroGuid
, 0, 0, 0, 0, 0);
626 Search image from memory profile.
627 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)
629 @param ContextData Memory profile context.
630 @param Address Image or Function address.
632 @return Pointer to memory profile driver info.
635 MEMORY_PROFILE_DRIVER_INFO_DATA
*
636 GetMemoryProfileDriverInfoFromAddress (
637 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
638 IN PHYSICAL_ADDRESS Address
641 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
642 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
643 LIST_ENTRY
*DriverLink
;
644 LIST_ENTRY
*DriverInfoList
;
646 DriverInfoList
= ContextData
->DriverInfoList
;
648 for (DriverLink
= DriverInfoList
->ForwardLink
;
649 DriverLink
!= DriverInfoList
;
650 DriverLink
= DriverLink
->ForwardLink
) {
651 DriverInfoData
= CR (
653 MEMORY_PROFILE_DRIVER_INFO_DATA
,
655 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
657 DriverInfo
= &DriverInfoData
->DriverInfo
;
658 if ((Address
>= DriverInfo
->ImageBase
) &&
659 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
660 return DriverInfoData
;
665 // Should never come here.
667 return FindDummyImage (ContextData
);
671 Unregister image from memory profile.
673 @param DriverEntry Image info.
675 @retval TRUE Unregister success.
676 @retval FALSE Unregister fail.
680 UnregisterMemoryProfileImage (
681 IN LOADED_IMAGE_PRIVATE_DATA
*DriverEntry
685 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
686 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
688 PHYSICAL_ADDRESS ImageAddress
;
689 VOID
*EntryPointInImage
;
691 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
695 ContextData
= GetMemoryProfileContext ();
696 if (ContextData
== NULL
) {
700 DriverInfoData
= NULL
;
701 FileName
= GetFileNameFromFilePath (DriverEntry
->Info
.FilePath
);
702 ImageAddress
= DriverEntry
->ImageContext
.ImageAddress
;
703 if ((DriverEntry
->ImageContext
.EntryPoint
< ImageAddress
) || (DriverEntry
->ImageContext
.EntryPoint
>= (ImageAddress
+ DriverEntry
->ImageContext
.ImageSize
))) {
705 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
706 // So patch ImageAddress here to align the EntryPoint.
708 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageAddress
, &EntryPointInImage
);
709 ASSERT_EFI_ERROR (Status
);
710 ImageAddress
= ImageAddress
+ (UINTN
) DriverEntry
->ImageContext
.EntryPoint
- (UINTN
) EntryPointInImage
;
712 if (FileName
!= NULL
) {
713 DriverInfoData
= GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData
, FileName
, ImageAddress
);
715 if (DriverInfoData
== NULL
) {
716 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, ImageAddress
);
718 if (DriverInfoData
== NULL
) {
722 ContextData
->Context
.TotalImageSize
-= DriverInfoData
->DriverInfo
.ImageSize
;
724 DriverInfoData
->DriverInfo
.ImageBase
= 0;
725 DriverInfoData
->DriverInfo
.ImageSize
= 0;
727 if (DriverInfoData
->DriverInfo
.PeakUsage
== 0) {
728 ContextData
->Context
.ImageCount
--;
729 RemoveEntryList (&DriverInfoData
->Link
);
731 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
733 CoreInternalFreePool (DriverInfoData
, NULL
);
740 Return if this memory type needs to be recorded into memory profile.
741 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), it checks bit (1 << MemoryType).
742 If OS memory type (0x80000000 ~ 0xFFFFFFFF), it checks bit63 - 0x8000000000000000.
743 If OEM memory type (0x70000000 ~ 0x7FFFFFFF), it checks bit62 - 0x4000000000000000.
745 @param MemoryType Memory type.
747 @retval TRUE This memory type need to be recorded.
748 @retval FALSE This memory type need not to be recorded.
752 CoreNeedRecordProfile (
753 IN EFI_MEMORY_TYPE MemoryType
758 if ((UINT32
) MemoryType
>= MEMORY_TYPE_OS_RESERVED_MIN
) {
760 } else if ((UINT32
) MemoryType
>= MEMORY_TYPE_OEM_RESERVED_MIN
) {
763 TestBit
= LShiftU64 (1, MemoryType
);
766 if ((PcdGet64 (PcdMemoryProfileMemoryType
) & TestBit
) != 0) {
774 Convert EFI memory type to profile memory index. The rule is:
775 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType.
776 If OS memory type (0x80000000 ~ 0xFFFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType.
777 If OEM memory type (0x70000000 ~ 0x7FFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType + 1.
779 @param MemoryType Memory type.
781 @return Profile memory index.
785 GetProfileMemoryIndex (
786 IN EFI_MEMORY_TYPE MemoryType
789 if ((UINT32
) MemoryType
>= MEMORY_TYPE_OS_RESERVED_MIN
) {
790 return EfiMaxMemoryType
;
791 } else if ((UINT32
) MemoryType
>= MEMORY_TYPE_OEM_RESERVED_MIN
) {
792 return EfiMaxMemoryType
+ 1;
799 Update memory profile Allocate information.
801 @param CallerAddress Address of caller who call Allocate.
802 @param Action This Allocate action.
803 @param MemoryType Memory type.
804 @param Size Buffer size.
805 @param Buffer Buffer address.
807 @retval TRUE Profile udpate success.
808 @retval FALSE Profile update fail.
812 CoreUpdateProfileAllocate (
813 IN PHYSICAL_ADDRESS CallerAddress
,
814 IN MEMORY_PROFILE_ACTION Action
,
815 IN EFI_MEMORY_TYPE MemoryType
,
821 MEMORY_PROFILE_CONTEXT
*Context
;
822 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
823 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
824 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
825 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
826 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
827 UINTN ProfileMemoryIndex
;
829 AllocInfoData
= NULL
;
831 ContextData
= GetMemoryProfileContext ();
832 if (ContextData
== NULL
) {
836 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
837 ASSERT (DriverInfoData
!= NULL
);
840 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
842 Status
= CoreInternalAllocatePool (
844 sizeof (*AllocInfoData
),
845 (VOID
**) &AllocInfoData
847 if (EFI_ERROR (Status
)) {
850 ASSERT (AllocInfoData
!= NULL
);
851 AllocInfo
= &AllocInfoData
->AllocInfo
;
852 AllocInfoData
->Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
853 AllocInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
854 AllocInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_ALLOC_INFO
);
855 AllocInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_INFO_REVISION
;
856 AllocInfo
->CallerAddress
= CallerAddress
;
857 AllocInfo
->SequenceId
= ContextData
->Context
.SequenceCount
;
858 AllocInfo
->Action
= Action
;
859 AllocInfo
->MemoryType
= MemoryType
;
860 AllocInfo
->Buffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
861 AllocInfo
->Size
= Size
;
863 InsertTailList (DriverInfoData
->AllocInfoList
, &AllocInfoData
->Link
);
865 ProfileMemoryIndex
= GetProfileMemoryIndex (MemoryType
);
867 DriverInfo
= &DriverInfoData
->DriverInfo
;
868 DriverInfo
->CurrentUsage
+= Size
;
869 if (DriverInfo
->PeakUsage
< DriverInfo
->CurrentUsage
) {
870 DriverInfo
->PeakUsage
= DriverInfo
->CurrentUsage
;
872 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] += Size
;
873 if (DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] < DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
]) {
874 DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] = DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
];
876 DriverInfo
->AllocRecordCount
++;
878 Context
= &ContextData
->Context
;
879 Context
->CurrentTotalUsage
+= Size
;
880 if (Context
->PeakTotalUsage
< Context
->CurrentTotalUsage
) {
881 Context
->PeakTotalUsage
= Context
->CurrentTotalUsage
;
883 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] += Size
;
884 if (Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] < Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
]) {
885 Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] = Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
];
887 Context
->SequenceCount
++;
893 Get memory profile alloc info from memory profile
895 @param DriverInfoData Driver info
896 @param Action This Free action
897 @param Size Buffer size
898 @param Buffer Buffer address
900 @return Pointer to memory profile alloc info.
902 MEMORY_PROFILE_ALLOC_INFO_DATA
*
903 GetMemoryProfileAllocInfoFromAddress (
904 IN MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
,
905 IN MEMORY_PROFILE_ACTION Action
,
910 LIST_ENTRY
*AllocInfoList
;
911 LIST_ENTRY
*AllocLink
;
912 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
913 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
915 AllocInfoList
= DriverInfoData
->AllocInfoList
;
917 for (AllocLink
= AllocInfoList
->ForwardLink
;
918 AllocLink
!= AllocInfoList
;
919 AllocLink
= AllocLink
->ForwardLink
) {
922 MEMORY_PROFILE_ALLOC_INFO_DATA
,
924 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
926 AllocInfo
= &AllocInfoData
->AllocInfo
;
927 if (AllocInfo
->Action
!= Action
) {
931 case MemoryProfileActionAllocatePages
:
932 if ((AllocInfo
->Buffer
<= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) &&
933 ((AllocInfo
->Buffer
+ AllocInfo
->Size
) >= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
))) {
934 return AllocInfoData
;
937 case MemoryProfileActionAllocatePool
:
938 if (AllocInfo
->Buffer
== (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
939 return AllocInfoData
;
952 Update memory profile Free information.
954 @param CallerAddress Address of caller who call Free.
955 @param Action This Free action.
956 @param Size Buffer size.
957 @param Buffer Buffer address.
959 @retval TRUE Profile udpate success.
960 @retval FALSE Profile update fail.
964 CoreUpdateProfileFree (
965 IN PHYSICAL_ADDRESS CallerAddress
,
966 IN MEMORY_PROFILE_ACTION Action
,
971 MEMORY_PROFILE_CONTEXT
*Context
;
972 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
973 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
974 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
975 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
976 LIST_ENTRY
*DriverLink
;
977 LIST_ENTRY
*DriverInfoList
;
978 MEMORY_PROFILE_DRIVER_INFO_DATA
*ThisDriverInfoData
;
979 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
980 UINTN ProfileMemoryIndex
;
982 ContextData
= GetMemoryProfileContext ();
983 if (ContextData
== NULL
) {
987 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
988 ASSERT (DriverInfoData
!= NULL
);
991 case MemoryProfileActionFreePages
:
992 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
994 case MemoryProfileActionFreePool
:
995 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
999 AllocInfoData
= NULL
;
1002 if (AllocInfoData
== NULL
) {
1004 // Legal case, because driver A might free memory allocated by driver B, by some protocol.
1006 DriverInfoList
= ContextData
->DriverInfoList
;
1008 for (DriverLink
= DriverInfoList
->ForwardLink
;
1009 DriverLink
!= DriverInfoList
;
1010 DriverLink
= DriverLink
->ForwardLink
) {
1011 ThisDriverInfoData
= CR (
1013 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1015 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1018 case MemoryProfileActionFreePages
:
1019 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
1021 case MemoryProfileActionFreePool
:
1022 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
1026 AllocInfoData
= NULL
;
1029 if (AllocInfoData
!= NULL
) {
1030 DriverInfoData
= ThisDriverInfoData
;
1035 if (AllocInfoData
== NULL
) {
1037 // No matched allocate operation is found for this free operation.
1038 // It is because the specified memory type allocate operation has been
1039 // filtered by CoreNeedRecordProfile(), but free operations have no
1040 // memory type information, they can not be filtered by CoreNeedRecordProfile().
1041 // Then, they will be filtered here.
1047 Context
= &ContextData
->Context
;
1048 DriverInfo
= &DriverInfoData
->DriverInfo
;
1049 AllocInfo
= &AllocInfoData
->AllocInfo
;
1051 ProfileMemoryIndex
= GetProfileMemoryIndex (AllocInfo
->MemoryType
);
1053 Context
->CurrentTotalUsage
-= AllocInfo
->Size
;
1054 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1056 DriverInfo
->CurrentUsage
-= AllocInfo
->Size
;
1057 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1058 DriverInfo
->AllocRecordCount
--;
1060 RemoveEntryList (&AllocInfoData
->Link
);
1062 if (Action
== MemoryProfileActionFreePages
) {
1063 if (AllocInfo
->Buffer
!= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
1064 CoreUpdateProfileAllocate (
1065 AllocInfo
->CallerAddress
,
1066 MemoryProfileActionAllocatePages
,
1067 AllocInfo
->MemoryType
,
1068 (UINTN
) ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
- AllocInfo
->Buffer
),
1069 (VOID
*) (UINTN
) AllocInfo
->Buffer
1072 if (AllocInfo
->Buffer
+ AllocInfo
->Size
!= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)) {
1073 CoreUpdateProfileAllocate (
1074 AllocInfo
->CallerAddress
,
1075 MemoryProfileActionAllocatePages
,
1076 AllocInfo
->MemoryType
,
1077 (UINTN
) ((AllocInfo
->Buffer
+ AllocInfo
->Size
) - ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)),
1078 (VOID
*) ((UINTN
) Buffer
+ Size
)
1084 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
1086 CoreInternalFreePool (AllocInfoData
, NULL
);
1092 Update memory profile information.
1094 @param CallerAddress Address of caller who call Allocate or Free.
1095 @param Action This Allocate or Free action.
1096 @param MemoryType Memory type.
1097 @param Size Buffer size.
1098 @param Buffer Buffer address.
1100 @retval TRUE Profile udpate success.
1101 @retval FALSE Profile update fail.
1106 IN PHYSICAL_ADDRESS CallerAddress
,
1107 IN MEMORY_PROFILE_ACTION Action
,
1108 IN EFI_MEMORY_TYPE MemoryType
,
1109 IN UINTN Size
, // Valid for AllocatePages/FreePages/AllocatePool
1113 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1115 if (!IS_UEFI_MEMORY_PROFILE_ENABLED
) {
1119 if (!mMemoryProfileRecordingStatus
) {
1124 // Only record limited MemoryType.
1126 if (!CoreNeedRecordProfile (MemoryType
)) {
1130 ContextData
= GetMemoryProfileContext ();
1131 if (ContextData
== NULL
) {
1136 case MemoryProfileActionAllocatePages
:
1137 CoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1139 case MemoryProfileActionFreePages
:
1140 CoreUpdateProfileFree (CallerAddress
, Action
, Size
, Buffer
);
1142 case MemoryProfileActionAllocatePool
:
1143 CoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1145 case MemoryProfileActionFreePool
:
1146 CoreUpdateProfileFree (CallerAddress
, Action
, 0, Buffer
);
1155 ////////////////////
1158 Get memory profile data size.
1160 @return Memory profile data size.
1164 MemoryProfileGetDataSize (
1168 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1169 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1170 LIST_ENTRY
*DriverInfoList
;
1171 LIST_ENTRY
*DriverLink
;
1175 ContextData
= GetMemoryProfileContext ();
1176 if (ContextData
== NULL
) {
1180 TotalSize
= sizeof (MEMORY_PROFILE_CONTEXT
);
1181 TotalSize
+= sizeof (MEMORY_PROFILE_DRIVER_INFO
) * (UINTN
) ContextData
->Context
.ImageCount
;
1183 DriverInfoList
= ContextData
->DriverInfoList
;
1184 for (DriverLink
= DriverInfoList
->ForwardLink
;
1185 DriverLink
!= DriverInfoList
;
1186 DriverLink
= DriverLink
->ForwardLink
) {
1187 DriverInfoData
= CR (
1189 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1191 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1193 TotalSize
+= sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfoData
->DriverInfo
.AllocRecordCount
;
1200 Copy memory profile data.
1202 @param ProfileBuffer The buffer to hold memory profile data.
1206 MemoryProfileCopyData (
1207 IN VOID
*ProfileBuffer
1210 MEMORY_PROFILE_CONTEXT
*Context
;
1211 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1212 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1213 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1214 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1215 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1216 LIST_ENTRY
*DriverInfoList
;
1217 LIST_ENTRY
*DriverLink
;
1218 LIST_ENTRY
*AllocInfoList
;
1219 LIST_ENTRY
*AllocLink
;
1221 ContextData
= GetMemoryProfileContext ();
1222 if (ContextData
== NULL
) {
1226 Context
= ProfileBuffer
;
1227 CopyMem (Context
, &ContextData
->Context
, sizeof (MEMORY_PROFILE_CONTEXT
));
1228 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) (Context
+ 1);
1230 DriverInfoList
= ContextData
->DriverInfoList
;
1231 for (DriverLink
= DriverInfoList
->ForwardLink
;
1232 DriverLink
!= DriverInfoList
;
1233 DriverLink
= DriverLink
->ForwardLink
) {
1234 DriverInfoData
= CR (
1236 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1238 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1240 CopyMem (DriverInfo
, &DriverInfoData
->DriverInfo
, sizeof (MEMORY_PROFILE_DRIVER_INFO
));
1241 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) (DriverInfo
+ 1);
1243 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1244 for (AllocLink
= AllocInfoList
->ForwardLink
;
1245 AllocLink
!= AllocInfoList
;
1246 AllocLink
= AllocLink
->ForwardLink
) {
1247 AllocInfoData
= CR (
1249 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1251 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1253 CopyMem (AllocInfo
, &AllocInfoData
->AllocInfo
, sizeof (MEMORY_PROFILE_ALLOC_INFO
));
1257 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) (DriverInfo
+ 1) + sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfo
->AllocRecordCount
);
1262 Get memory profile data.
1264 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1265 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
1266 On return, points to the size of the data returned in ProfileBuffer.
1267 @param[out] ProfileBuffer Profile buffer.
1269 @return EFI_SUCCESS Get the memory profile data successfully.
1270 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
1271 ProfileSize is updated with the size required.
1276 ProfileProtocolGetData (
1277 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1278 IN OUT UINT64
*ProfileSize
,
1279 OUT VOID
*ProfileBuffer
1283 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1284 BOOLEAN MemoryProfileRecordingStatus
;
1286 ContextData
= GetMemoryProfileContext ();
1287 if (ContextData
== NULL
) {
1288 return EFI_UNSUPPORTED
;
1291 MemoryProfileRecordingStatus
= mMemoryProfileRecordingStatus
;
1292 mMemoryProfileRecordingStatus
= FALSE
;
1294 Size
= MemoryProfileGetDataSize ();
1296 if (*ProfileSize
< Size
) {
1297 *ProfileSize
= Size
;
1298 mMemoryProfileRecordingStatus
= MemoryProfileRecordingStatus
;
1299 return EFI_BUFFER_TOO_SMALL
;
1302 *ProfileSize
= Size
;
1303 MemoryProfileCopyData (ProfileBuffer
);
1305 mMemoryProfileRecordingStatus
= MemoryProfileRecordingStatus
;
1310 Register image to memory profile.
1312 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1313 @param[in] FilePath File path of the image.
1314 @param[in] ImageBase Image base address.
1315 @param[in] ImageSize Image size.
1316 @param[in] FileType File type of the image.
1318 @return EFI_SUCCESS Register success.
1319 @return EFI_OUT_OF_RESOURCE No enough resource for this register.
1324 ProfileProtocolRegisterImage (
1325 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1326 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
1327 IN PHYSICAL_ADDRESS ImageBase
,
1328 IN UINT64 ImageSize
,
1329 IN EFI_FV_FILETYPE FileType
1333 LOADED_IMAGE_PRIVATE_DATA DriverEntry
;
1334 VOID
*EntryPointInImage
;
1336 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1337 DriverEntry
.Info
.FilePath
= FilePath
;
1338 DriverEntry
.ImageContext
.ImageAddress
= ImageBase
;
1339 DriverEntry
.ImageContext
.ImageSize
= ImageSize
;
1340 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
1341 ASSERT_EFI_ERROR (Status
);
1342 DriverEntry
.ImageContext
.EntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1343 DriverEntry
.ImageContext
.ImageType
= InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
);
1345 return RegisterMemoryProfileImage (&DriverEntry
, FileType
) ? EFI_SUCCESS
: EFI_OUT_OF_RESOURCES
;
1349 Unregister image from memory profile.
1351 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1352 @param[in] FilePath File path of the image.
1353 @param[in] ImageBase Image base address.
1354 @param[in] ImageSize Image size.
1356 @return EFI_SUCCESS Unregister success.
1357 @return EFI_NOT_FOUND The image is not found.
1362 ProfileProtocolUnregisterImage (
1363 IN EDKII_MEMORY_PROFILE_PROTOCOL
*This
,
1364 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
1365 IN PHYSICAL_ADDRESS ImageBase
,
1370 LOADED_IMAGE_PRIVATE_DATA DriverEntry
;
1371 VOID
*EntryPointInImage
;
1373 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1374 DriverEntry
.Info
.FilePath
= FilePath
;
1375 DriverEntry
.ImageContext
.ImageAddress
= ImageBase
;
1376 DriverEntry
.ImageContext
.ImageSize
= ImageSize
;
1377 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
1378 ASSERT_EFI_ERROR (Status
);
1379 DriverEntry
.ImageContext
.EntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1381 return UnregisterMemoryProfileImage (&DriverEntry
) ? EFI_SUCCESS
: EFI_NOT_FOUND
;
1384 ////////////////////