From 602ca88a55162bf84c369d6924131f128a0ed356 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Thu, 5 Oct 2017 22:25:51 +0800 Subject: Clean up Checkpoint. 1) CheckPointLib interface to be feature based, instead of phase based. 2) Rename file from Dump to Check. 3) Add TestPointStub to help convert PEI/SMM info to DXE protocol. 4) Implement all check points. Cc: Michael A Kubacki Cc: Amy Chan Cc: Chasel Chiu Cc: Brett Wang Cc: Daocheng Bu Cc: Isaac W Oram Cc: Rangasai V Chaganty Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Reviewed-by: Amy Chan --- .../TestPointCheckLib/DxeCheckLoadedImage.c | 249 +++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 Platform/Intel/MinPlatformPkg/Test/Library/TestPointCheckLib/DxeCheckLoadedImage.c (limited to 'Platform/Intel/MinPlatformPkg/Test/Library/TestPointCheckLib/DxeCheckLoadedImage.c') diff --git a/Platform/Intel/MinPlatformPkg/Test/Library/TestPointCheckLib/DxeCheckLoadedImage.c b/Platform/Intel/MinPlatformPkg/Test/Library/TestPointCheckLib/DxeCheckLoadedImage.c new file mode 100644 index 0000000000..7aa93d0976 --- /dev/null +++ b/Platform/Intel/MinPlatformPkg/Test/Library/TestPointCheckLib/DxeCheckLoadedImage.c @@ -0,0 +1,249 @@ +/** @file + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN +IsRuntimeImage ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINT16 Magic; + UINT16 Subsystem; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + // + // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. + // It is due to backward-compatibility, for some system might + // generate PE32+ image with PE32 Magic. + // + switch (Hdr.Pe32->FileHeader.Machine) { + case IMAGE_FILE_MACHINE_I386: + // + // Assume PE32 image with IA32 Machine field. + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + case IMAGE_FILE_MACHINE_X64: + case IMAGE_FILE_MACHINE_IA64: + // + // Assume PE32+ image with x64 or IA64 Machine field + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + default: + // + // For unknow Machine field, use Magic in optional Header + // + Magic = Hdr.Pe32->OptionalHeader.Magic; + } + + if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + Subsystem = Hdr.Pe32->OptionalHeader.Subsystem; + } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + Subsystem = Hdr.Pe32Plus->OptionalHeader.Subsystem; + } + if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { + return TRUE; + } + } + + return FALSE; +} + +VOID +DumpLoadedImage ( + IN UINTN Index, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath + ) +{ + CHAR16 *Str; + CHAR8 *PdbPointer; + + DEBUG ((DEBUG_INFO, "[0x%04x]:", Index)); + if (IsRuntimeImage (LoadedImage->ImageBase)) { + DEBUG ((DEBUG_INFO, " (RT)")); + } else { + DEBUG ((DEBUG_INFO, " ")); + } + DEBUG ((DEBUG_INFO, " 0x%016lx-0x%016lx", (UINT64)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); + + if (LoadedImageDevicePath != NULL) { + Str = ConvertDevicePathToText(LoadedImageDevicePath, TRUE, TRUE); + DEBUG ((DEBUG_INFO, " LoadedImageDevicePath=%s", Str)); + if (Str != NULL) { + FreePool (Str); + } + } else { + if (LoadedImage->FilePath != NULL) { + Str = ConvertDevicePathToText(LoadedImage->FilePath, TRUE, TRUE); + DEBUG ((DEBUG_INFO, " FilePath=%s", Str)); + if (Str != NULL) { + FreePool (Str); + } + } + + if (DevicePath != NULL) { + Str = ConvertDevicePathToText(DevicePath, TRUE, TRUE); + DEBUG ((DEBUG_INFO, " DevicePath=%s", Str)); + if (Str != NULL) { + FreePool (Str); + } + } + } + + PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_INFO, " (pdb - %a)", PdbPointer)); + } + + DEBUG ((DEBUG_INFO, "\n")); +} + +EFI_STATUS +TestPointCheckNon3rdPartyImage ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath + ) +{ + if (LoadedImageDevicePath != NULL) { + // LoadedImageDevicePath should be Fv()/FvFile() + if (DevicePathType (LoadedImageDevicePath) == MEDIA_DEVICE_PATH && + DevicePathSubType (LoadedImageDevicePath) == MEDIA_PIWG_FW_VOL_DP) { + return EFI_SUCCESS; + } + } else { + if (LoadedImage->FilePath != NULL) { + // LoadedImage->FilePath should be FvFile() + if (DevicePathType (LoadedImage->FilePath) == MEDIA_DEVICE_PATH && + DevicePathSubType (LoadedImage->FilePath) == MEDIA_PIWG_FW_FILE_DP) { + return EFI_SUCCESS; + } + } + if (DevicePath != NULL) { + // DevicePath should be Fv() + if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH && + DevicePathSubType (DevicePath) == MEDIA_PIWG_FW_VOL_DP) { + return EFI_SUCCESS; + } + } + } + return EFI_INVALID_PARAMETER; +} + +EFI_STATUS +TestPointCheckLoadedImage ( + VOID + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + UINTN Index; + EFI_HANDLE *HandleBuf; + UINTN HandleCount; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; + EFI_STATUS ReturnStatus; + + ReturnStatus = EFI_SUCCESS; + DEBUG ((DEBUG_INFO, "==== TestPointCheckLoadedImage - Enter\n")); + HandleBuf = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiLoadedImageProtocolGuid, + NULL, + &HandleCount, + &HandleBuf + ); + if (EFI_ERROR (Status)) { + goto Done ; + } + + DEBUG ((DEBUG_INFO, "LoadedImage (%d):\n", HandleCount)); + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR(Status)) { + continue; + } + + Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) { + DevicePath = NULL; + } + + Status = gBS->HandleProtocol (HandleBuf[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&LoadedImageDevicePath); + if (EFI_ERROR(Status)) { + LoadedImageDevicePath = NULL; + } + + DumpLoadedImage (Index, LoadedImage, DevicePath, LoadedImageDevicePath); + + Status = TestPointCheckNon3rdPartyImage (LoadedImage, DevicePath, LoadedImageDevicePath); + if (EFI_ERROR(Status)) { + ReturnStatus = Status; + DEBUG ((DEBUG_ERROR, "3rd Party Image found - Index (%d)\n", Index)); + TestPointLibAppendErrorString ( + PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV, + NULL, + TEST_POINT_BYTE2_END_OF_DXE_NO_THIRD_PARTY_PCI_OPTION_ROM_ERROR_CODE \ + TEST_POINT_END_OF_DXE \ + TEST_POINT_BYTE2_END_OF_DXE_NO_THIRD_PARTY_PCI_OPTION_ROM_ERROR_STRING + ); + } + } + +Done: + + if (HandleBuf != NULL) { + FreePool (HandleBuf); + } + + DEBUG ((DEBUG_INFO, "==== TestPointCheckLoadedImage - Exit\n")); + + return ReturnStatus; +} -- cgit v1.2.3