+/**\r
+ Get Allocate summary information structure by caller address.\r
+\r
+ @param[in] CallerAddress Caller address.\r
+ @param[in] DriverSummaryInfoData Driver summary information data structure.\r
+\r
+ @return Allocate summary information structure by caller address.\r
+\r
+**/\r
+MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *\r
+GetAllocSummaryInfoByCallerAddress (\r
+ IN PHYSICAL_ADDRESS CallerAddress,\r
+ IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData\r
+ )\r
+{\r
+ LIST_ENTRY *AllocSummaryInfoList;\r
+ LIST_ENTRY *AllocSummaryLink;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
+\r
+ AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
+\r
+ for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
+ AllocSummaryLink != AllocSummaryInfoList;\r
+ AllocSummaryLink = AllocSummaryLink->ForwardLink) {\r
+ AllocSummaryInfoData = CR (\r
+ AllocSummaryLink,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
+ Link,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
+ );\r
+ AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
+ if (AllocSummaryInfo->CallerAddress == CallerAddress) {\r
+ return AllocSummaryInfoData;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Create Allocate summary information structure and\r
+ link to Driver summary information data structure.\r
+\r
+ @param[in, out] DriverSummaryInfoData Driver summary information data structure.\r
+ @param[in] AllocInfo Pointer to memory profile alloc info.\r
+\r
+ @return Pointer to next memory profile alloc info.\r
+\r
+**/\r
+MEMORY_PROFILE_ALLOC_INFO *\r
+CreateAllocSummaryInfo (\r
+ IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData,\r
+ IN MEMORY_PROFILE_ALLOC_INFO *AllocInfo\r
+ )\r
+{\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
+\r
+ if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {\r
+ return NULL;\r
+ }\r
+\r
+ AllocSummaryInfoData = GetAllocSummaryInfoByCallerAddress (AllocInfo->CallerAddress, DriverSummaryInfoData);\r
+ if (AllocSummaryInfoData == NULL) {\r
+ AllocSummaryInfoData = AllocatePool (sizeof (*AllocSummaryInfoData));\r
+ if (AllocSummaryInfoData == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ AllocSummaryInfoData->Signature = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;\r
+ AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
+ AllocSummaryInfo->Header.Signature = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;\r
+ AllocSummaryInfo->Header.Length = sizeof (*AllocSummaryInfo);\r
+ AllocSummaryInfo->Header.Revision = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION;\r
+ AllocSummaryInfo->CallerAddress = AllocInfo->CallerAddress;\r
+ AllocSummaryInfo->Action = AllocInfo->Action;\r
+ if (AllocInfo->ActionStringOffset != 0) {\r
+ AllocSummaryInfo->ActionString = (CHAR8 *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset);\r
+ } else {\r
+ AllocSummaryInfo->ActionString = NULL;\r
+ }\r
+ AllocSummaryInfo->AllocateCount = 0;\r
+ AllocSummaryInfo->TotalSize = 0;\r
+ InsertTailList (DriverSummaryInfoData->AllocSummaryInfoList, &AllocSummaryInfoData->Link);\r
+ }\r
+ AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
+ AllocSummaryInfo->AllocateCount ++;\r
+ AllocSummaryInfo->TotalSize += AllocInfo->Size;\r
+\r
+ return (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length);\r
+}\r
+\r
+/**\r
+ Create Driver summary information structure and\r
+ link to Context summary information data structure.\r
+\r
+ @param[in, out] ContextSummaryData Context summary information data structure.\r
+ @param[in] DriverInfo Pointer to memory profile driver info.\r
+\r
+ @return Pointer to next memory profile driver info.\r
+\r
+**/\r
+MEMORY_PROFILE_DRIVER_INFO *\r
+CreateDriverSummaryInfo (\r
+ IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData,\r
+ IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo\r
+ )\r
+{\r
+ MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
+ MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
+ UINTN AllocIndex;\r
+\r
+ if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {\r
+ return NULL;\r
+ }\r
+\r
+ DriverSummaryInfoData = AllocatePool (sizeof (*DriverSummaryInfoData) + sizeof (LIST_ENTRY));\r
+ if (DriverSummaryInfoData == NULL) {\r
+ return NULL;\r
+ }\r
+ DriverSummaryInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
+ DriverSummaryInfoData->DriverInfo = DriverInfo;\r
+ DriverSummaryInfoData->AllocSummaryInfoList = (LIST_ENTRY *) (DriverSummaryInfoData + 1);\r
+ InitializeListHead (DriverSummaryInfoData->AllocSummaryInfoList);\r
+ InsertTailList (ContextSummaryData->DriverSummaryInfoList, &DriverSummaryInfoData->Link);\r
+\r
+ AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length);\r
+ for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {\r
+ AllocInfo = CreateAllocSummaryInfo (DriverSummaryInfoData, AllocInfo);\r
+ if (AllocInfo == NULL) {\r
+ return NULL;\r
+ }\r
+ }\r
+ return (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo;\r
+}\r
+\r
+/**\r
+ Create Context summary information structure.\r
+\r
+ @param[in] ProfileBuffer Memory profile base address.\r
+ @param[in] ProfileSize Memory profile size.\r
+\r
+ @return Context summary information structure.\r
+\r
+**/\r
+MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *\r
+CreateContextSummaryData (\r
+ IN PHYSICAL_ADDRESS ProfileBuffer,\r
+ IN UINT64 ProfileSize\r
+ )\r
+{\r
+ MEMORY_PROFILE_CONTEXT *Context;\r
+ MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
+ UINTN DriverIndex;\r
+\r
+ Context = (MEMORY_PROFILE_CONTEXT *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);\r
+ if (Context == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ mMemoryProfileContextSummary.Signature = MEMORY_PROFILE_CONTEXT_SIGNATURE;\r
+ mMemoryProfileContextSummary.Context = Context;\r
+ mMemoryProfileContextSummary.DriverSummaryInfoList = &mImageSummaryQueue;\r
+\r
+ DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) Context + Context->Header.Length);\r
+ for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {\r
+ DriverInfo = CreateDriverSummaryInfo (&mMemoryProfileContextSummary, DriverInfo);\r
+ if (DriverInfo == NULL) {\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ return &mMemoryProfileContextSummary;\r
+}\r
+\r
+/**\r
+ Dump Context summary information.\r
+\r
+ @param[in] ContextSummaryData Context summary information data.\r
+ @param[in] IsForSmm TRUE - SMRAM profile.\r
+ FALSE - UEFI memory profile.\r
+\r
+**/\r
+VOID\r
+DumpContextSummaryData (\r
+ IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData,\r
+ IN BOOLEAN IsForSmm\r
+ )\r
+{\r
+ MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
+ LIST_ENTRY *DriverSummaryInfoList;\r
+ LIST_ENTRY *DriverSummaryLink;\r
+ LIST_ENTRY *AllocSummaryInfoList;\r
+ LIST_ENTRY *AllocSummaryLink;\r
+ MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
+ CHAR8 *NameString;\r
+\r
+ if (ContextSummaryData == NULL) {\r
+ return ;\r
+ }\r
+\r
+ Print (L"\nSummary Data:\n");\r
+\r
+ DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;\r
+ for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;\r
+ DriverSummaryLink != DriverSummaryInfoList;\r
+ DriverSummaryLink = DriverSummaryLink->ForwardLink) {\r
+ DriverSummaryInfoData = CR (\r
+ DriverSummaryLink,\r
+ MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,\r
+ Link,\r
+ MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
+ );\r
+ DriverInfo = DriverSummaryInfoData->DriverInfo;\r
+\r
+ NameString = GetDriverNameString (DriverInfo);\r
+ Print (L"\nDriver - %a (Usage - 0x%08x)", NameString, DriverInfo->CurrentUsage);\r
+ if (DriverInfo->CurrentUsage == 0) {\r
+ Print (L"\n");\r
+ continue;\r
+ }\r
+\r
+ if (DriverInfo->PdbStringOffset != 0) {\r
+ Print (L" (Pdb - %a)\n", (CHAR8 *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset));\r
+ } else {\r
+ Print (L"\n");\r
+ }\r
+ Print (L"Caller List:\n");\r
+ Print(L" Count Size RVA Action\n");\r
+ Print(L"========== ================== ================== (================================)\n");\r
+ AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
+ for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
+ AllocSummaryLink != AllocSummaryInfoList;\r
+ AllocSummaryLink = AllocSummaryLink->ForwardLink) {\r
+ AllocSummaryInfoData = CR (\r
+ AllocSummaryLink,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
+ Link,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
+ );\r
+ AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
+\r
+ Print(L"0x%08x 0x%016lx <== 0x%016lx",\r
+ AllocSummaryInfo->AllocateCount,\r
+ AllocSummaryInfo->TotalSize,\r
+ AllocSummaryInfo->CallerAddress - DriverInfo->ImageBase\r
+ );\r
+ Print (L" (%a)\n", ProfileActionToStr (AllocSummaryInfo->Action, AllocSummaryInfo->ActionString, IsForSmm));\r
+ }\r
+ }\r
+ return ;\r
+}\r
+\r
+/**\r
+ Destroy Context summary information.\r
+\r
+ @param[in, out] ContextSummaryData Context summary information data.\r
+\r
+**/\r
+VOID\r
+DestroyContextSummaryData (\r
+ IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData\r
+ )\r
+{\r
+ MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
+ LIST_ENTRY *DriverSummaryInfoList;\r
+ LIST_ENTRY *DriverSummaryLink;\r
+ LIST_ENTRY *AllocSummaryInfoList;\r
+ LIST_ENTRY *AllocSummaryLink;\r
+\r
+ if (ContextSummaryData == NULL) {\r
+ return ;\r
+ }\r
+\r
+ DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;\r
+ for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;\r
+ DriverSummaryLink != DriverSummaryInfoList;\r
+ ) {\r
+ DriverSummaryInfoData = CR (\r
+ DriverSummaryLink,\r
+ MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,\r
+ Link,\r
+ MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
+ );\r
+ DriverSummaryLink = DriverSummaryLink->ForwardLink;\r
+\r
+ AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
+ for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
+ AllocSummaryLink != AllocSummaryInfoList;\r
+ ) {\r
+ AllocSummaryInfoData = CR (\r
+ AllocSummaryLink,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
+ Link,\r
+ MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
+ );\r
+ AllocSummaryLink = AllocSummaryLink->ForwardLink;\r
+\r
+ RemoveEntryList (&AllocSummaryInfoData->Link);\r
+ FreePool (AllocSummaryInfoData);\r
+ }\r
+\r
+ RemoveEntryList (&DriverSummaryInfoData->Link);\r
+ FreePool (DriverSummaryInfoData);\r
+ }\r
+ return ;\r
+}\r
+\r