From nobody Thu Nov 14 07:01:56 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+110656+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+110656+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1699031844; cv=none; d=zohomail.com; s=zohoarc; b=M+1VpuikBOSJBcvOKP2lM9xz66PRViuhEqPRXKdtM85ol/WXeNb1oQLFQhn7YxenkorUE1+jO+ifuyKx+jgIV906gX2u4Gu1iksRPIdPAdssNLNYGwHlu+FL8ORJCV9g+35k+bo7UmmlG/R5UTxAnsb9eQPsctXB9LNApOTPrtU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1699031844; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=UmoLBGQifQCULHjPqQQ+MV9laAotImiuj4gWcTo6ytg=; b=SWAhZrs1lsTDT+QSTwrqRgRP9SbUYO1z1iVlvEMMddvJlz5HrSyB3E0NkDM+k+tYu3ebFe7W1RY0jCQGFDGedEcyepvnsesL57yLSuQ69zQz/gDbtQbRi8q9TR3t8L0CA//owYi3Gd1oa+WNrm4zg4vqAyGUQDeH7mmekFm8SOg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+110656+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16990318446621020.9135215788376; Fri, 3 Nov 2023 10:17:24 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=o/gzatjtgU7XTGdMp6uKxwWJFnYwqVRdDxD8jeZaWNI=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1699031844; v=1; b=he0nc4bLU87qpu2HOYqqMnv4o7K5Psi+ezLLezuJrEnti1wMrNYughD+OKZsFtxddu9MurET fDq7Vm6a1SoUu3GQ4JqvjDdsmDAnxxqQY6h/GZQ6t80pygl45XoTbmNzN0Y5VMqr4jzrVF+zLy5 LZwm9hyM16V+EENYWgiCZ4Ro= X-Received: by 127.0.0.2 with SMTP id C8b1YY1788612xTBBSLnldtf; Fri, 03 Nov 2023 10:17:24 -0700 X-Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.web11.59067.1699031843315517319 for ; Fri, 03 Nov 2023 10:17:23 -0700 X-Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1cc394f4cdfso18311125ad.0 for ; Fri, 03 Nov 2023 10:17:23 -0700 (PDT) X-Gm-Message-State: EHNpit3Zv2Zjw2QQMZyK1LxMx1787277AA= X-Google-Smtp-Source: AGHT+IGajkFJ6dPx/qZqPfsuq0xHp14aOTCKvshGPa3Fz0TkYUyCCFW5gESiYnqwTBy95vxz+4O0KA== X-Received: by 2002:a17:903:2808:b0:1cc:31c4:377b with SMTP id kp8-20020a170903280800b001cc31c4377bmr14430704plb.63.1699031842434; Fri, 03 Nov 2023 10:17:22 -0700 (PDT) X-Received: from localhost.localdomain ([50.46.253.1]) by smtp.gmail.com with ESMTPSA id b8-20020a170903228800b001bf5e24b2a8sm1625152plh.174.2023.11.03.10.17.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Nov 2023 10:17:22 -0700 (PDT) From: "Taylor Beebe" To: devel@edk2.groups.io Cc: Jian J Wang , Liming Gao , Dandan Bi Subject: [edk2-devel] [PATCH v4 08/14] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Date: Fri, 3 Nov 2023 10:17:00 -0700 Message-ID: <20231103171706.148-9-taylor.d.beebe@gmail.com> In-Reply-To: <20231103171706.148-1-taylor.d.beebe@gmail.com> References: <20231103171706.148-1-taylor.d.beebe@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,taylor.d.beebe@gmail.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1699031844921100026 Content-Type: text/plain; charset="utf-8" Create a host-based unit test for the ImagePropertiesRecordLib SplitTable() logic. This test has 4 cases which tests different potential image and memory map layouts. 3/4 of these tests fail with the logic in its current state to provide proof of the bugs in the current MAT logic. Cc: Jian J Wang Cc: Liming Gao Cc: Dandan Bi Signed-off-by: Taylor Beebe Reviewed-by: Liming Gao --- MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesReco= rdLibUnitTestHost.c | 938 ++++++++++++++++++++ MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesReco= rdLibUnitTestHost.inf | 35 + MdeModulePkg/Test/MdeModulePkgHostTest.dsc = | 5 + 3 files changed, 978 insertions(+) diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePr= opertiesRecordLibUnitTestHost.c b/MdeModulePkg/Library/ImagePropertiesRecor= dLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c new file mode 100644 index 000000000000..8b0a55685ce3 --- /dev/null +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertie= sRecordLibUnitTestHost.c @@ -0,0 +1,938 @@ +/** @file + Unit tests the SplitTable() ImagePropertiesRecordLib Logic + + Copyright (C) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_APP_NAME "Image Properties Record Lib Unit Test" +#define UNIT_TEST_APP_VERSION "1.0" + +#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) + +// The starting memory map will contain 6 entries +#define NUMBER_OF_MEMORY_MAP_DESCRIPTORS 6 + +// Each memory map descriptor will be the sizeof(EFI_MEMORY_DESCRIPTOR) in= stead of a nonstandard size +// to catch pointer math issues +#define DESCRIPTOR_SIZE sizeof(EFI_MEMORY_DESCRIPTOR) + +// Each memory map descriptor will describe 12 pages +#define BASE_DESCRIPTOR_NUMBER_OF_PAGES 0x0C + +// The size, in bytes, of each memory map descriptor range +#define BASE_DESCRIPTOR_ENTRY_SIZE (EFI_PAGES_TO_SIZE(BASE_DESCRIPTOR_NUM= BER_OF_PAGES)) + +// MACRO to get the starting address of a descriptor's described range bas= ed on the index of that descriptor +#define BASE_DESCRIPTOR_START_ADDRESS(DescriptorNumber) (DescriptorNumber= * BASE_DESCRIPTOR_ENTRY_SIZE) + +// Virtual start must be zero +#define BASE_DESCRIPTOR_VIRTUAL_START 0x0 + +// Size of the default memory map +#define BASE_MEMORY_MAP_SIZE (NUMBER_OF_MEMORY_MAP_DESCRIPTORS * DESCRIPT= OR_SIZE) + +// Number of images in each test case +#define NUMBER_OF_IMAGES_TO_SPLIT 3 + +// Maximum number of descriptors required for each image (None->Data->Code= ->Data->Code->Data->None) +#define MAX_DESCRIPTORS_PER_IMAGE 7 + +// Number of unused additional descriptors in the starting memory map buff= er which is used by the +// SplitTable() logic +#define NUMBER_OF_ADDITIONAL_DESCRIPTORS (NUMBER_OF_IMAGES_TO_SPLIT * MAX= _DESCRIPTORS_PER_IMAGE) + +// Size of the memory map with enough space for the starting descriptors a= nd the split descriptors +#define SPLIT_MEMORY_MAP_SIZE (BASE_MEMORY_MAP_SIZE + (NUMBER_OF_ADDITION= AL_DESCRIPTORS * DESCRIPTOR_SIZE)) + +typedef enum { + SectionTypeCode, + SectionTypeData, + SectionTypeNotFound +} SECTION_TYPE; + +typedef struct { + EFI_MEMORY_DESCRIPTOR *MemoryMap; + LIST_ENTRY ImageList; +} IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT; + +EFI_MEMORY_DESCRIPTOR BaseMemoryMap[] =3D { + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (0), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + }, + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (1), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + }, + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (2), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + }, + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (3), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + }, + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (4), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + }, + { + EfiConventionalMemory, // Type + BASE_DESCRIPTOR_START_ADDRESS (5), // PhysicalStart + BASE_DESCRIPTOR_VIRTUAL_START, // VirtualStart + BASE_DESCRIPTOR_NUMBER_OF_PAGES, // Number of Pages + 0 // Attribute + } +}; + +/** + Returns a bitmap where one bit is set for each section in the image list= . For example, if + there are 3 images and each image 3 sections the returned bitmap will be= 111111111. + + @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries + + @retval A bitmap such that the most significant bit is the number of sec= tions + in all images and every bit between 0 -> MSB is set + +**/ +STATIC +UINT64 +GetImageSectionBitmap ( + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordCodeSectionLink; + EFI_PHYSICAL_ADDRESS SectionBase; + UINT64 ReturnBitmap; + UINT64 Shift; + + if (ImageRecordList =3D=3D NULL) { + return 0; + } + + ReturnBitmap =3D 0; + Shift =3D 0; + + // Walk through each image record + for (ImageRecordLink =3D ImageRecordList->ForwardLink; + ImageRecordLink !=3D ImageRecordList; + ImageRecordLink =3D ImageRecordLink->ForwardLink) + { + ImageRecord =3D CR ( + ImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + + SectionBase =3D ImageRecord->ImageBase; + + // Walk through each code entry + for (ImageRecordCodeSectionLink =3D ImageRecord->CodeSegmentList.Forwa= rdLink; + ImageRecordCodeSectionLink !=3D &ImageRecord->CodeSegmentList; + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forwar= dLink) + { + ImageRecordCodeSection =3D CR ( + ImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGN= ATURE + ); + + // Check for data region before the code section base + if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) { + ReturnBitmap |=3D LShiftU64 (1, Shift++); + } + + // Code section + ReturnBitmap |=3D LShiftU64 (1, Shift++); + SectionBase =3D ImageRecordCodeSection->CodeSegmentBase + ImageRec= ordCodeSection->CodeSegmentSize; + } + + // Check for data region after the previous code section + if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) { + ReturnBitmap |=3D LShiftU64 (1, Shift++); + } + } + + return ReturnBitmap; +} + +/** + Searches the input image list for a section which exactly matches the me= mory range Buffer -> Buffer + Length. + + @param[in] Buffer Start Address to check + @param[in] Length Length to check + @param[out] Type The type of the section which corresponds w= ith the memory + range Buffer -> Buffer + Length (Code or Dat= a) or SectionTypeNotFound + if no image section matches the memory range + @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries to= check against + the memory range Buffer -> Buffer + Length + + @retval A bitmap with a single bit set (1 << Shift) where Shift correspo= nds with the number of sections inspected + in the image list before arriving at the section matching the me= mory range Buffer -> Buffer + Length +**/ +STATIC +UINT64 +MatchDescriptorToImageSection ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length, + OUT SECTION_TYPE *Type, + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordCodeSectionLink; + EFI_PHYSICAL_ADDRESS SectionBase; + UINT8 Shift; + + Shift =3D 0; + + if (ImageRecordList =3D=3D NULL) { + return 1; + } + + // Walk through each image record + for (ImageRecordLink =3D ImageRecordList->ForwardLink; + ImageRecordLink !=3D ImageRecordList; + ImageRecordLink =3D ImageRecordLink->ForwardLink) + { + ImageRecord =3D CR ( + ImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + + SectionBase =3D ImageRecord->ImageBase; + + // Walk through each code entry + for (ImageRecordCodeSectionLink =3D ImageRecord->CodeSegmentList.Forwa= rdLink; + ImageRecordCodeSectionLink !=3D &ImageRecord->CodeSegmentList; + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forwar= dLink) + { + ImageRecordCodeSection =3D CR ( + ImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGN= ATURE + ); + + if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) { + // Check the data region before the code section base + if ((Buffer =3D=3D SectionBase) && + (Length =3D=3D ImageRecordCodeSection->CodeSegmentBase - Secti= onBase)) + { + *Type =3D SectionTypeData; + return LShiftU64 (1, Shift); + } + + Shift++; + } + + // Check the code region + if ((Buffer =3D=3D ImageRecordCodeSection->CodeSegmentBase) && + (Length =3D=3D ImageRecordCodeSection->CodeSegmentSize)) + { + *Type =3D SectionTypeCode; + return LShiftU64 (1, Shift); + } + + Shift++; + SectionBase =3D ImageRecordCodeSection->CodeSegmentBase + ImageRecor= dCodeSection->CodeSegmentSize; + } + + // Check the data region after the code section + if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) { + if ((Buffer =3D=3D SectionBase) && + (Length =3D=3D (ImageRecord->ImageBase + ImageRecord->ImageSize)= - SectionBase)) + { + *Type =3D SectionTypeData; + return LShiftU64 (1, Shift); + } + + Shift++; + } + } + + // No image sections match + *Type =3D SectionTypeNotFound; + return 0; +} + +/** + Walks through the input memory map and checks that every memory descript= or with an attribute matches + an image in ImageRecordList. + + @param[in] MemoryMapSize The size, in bytes, of t= he memory map + @param[in] MemoryMap A pointer to the buffer = containing the memory map + @param[in] ImageRecordList A list of IMAGE_PROPERTI= ES_RECORD entries + + @retval TRUE if all memory descriptors with attributes match an image se= ction and have the correct attributes + +**/ +STATIC +BOOLEAN +IsMemoryMapValid ( + IN UINTN MemoryMapSize, + IN EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN LIST_ENTRY *ImageRecordList + ) +{ + UINT64 ImageSectionsBitmap; + UINT64 ReturnSectionBitmask; + UINT64 NumberOfDescriptors; + UINT8 Index; + SECTION_TYPE Type; + + Index =3D 0; + NumberOfDescriptors =3D MemoryMapSize / DESCRIPTOR_SIZE; + + UT_ASSERT_EQUAL (MemoryMapSize % DESCRIPTOR_SIZE, 0); + UT_ASSERT_NOT_NULL (MemoryMap); + UT_ASSERT_NOT_NULL (ImageRecordList); + + // The returned bitmap will have one bit is set for each section in the = image list. + // If there are 3 images and 3 sections each image, the resulting bitmap= will + // be 0000000000000000000000000000000000000000000000000000000111111111. = Flipping that bitmap + // results in 1111111111111111111111111111111111111111111111111111111000= 000000. The return value + // of each iteration through MatchDescriptorToImageSection() is one set = bit corrosponding to the number + // of sections before finding the section which matched the descriptor m= emory range which we + // OR with ImageSectionsBitmap. If, at the end of the loop, every bit in= ImageSectionsBitmap is set, + // we must have matched every image in ImageRecordList with a descriptor= in the memory map which has + // nonzero attributes. + ImageSectionsBitmap =3D ~GetImageSectionBitmap (ImageRecordList); + + // For each descriptor in the memory map + for ( ; Index < NumberOfDescriptors; Index++) { + if (MemoryMap[Index].Attribute !=3D 0) { + ReturnSectionBitmask =3D MatchDescriptorToImageSection ( + MemoryMap[Index].PhysicalStart, + EFI_PAGES_TO_SIZE (MemoryMap[Index].NumberO= fPages), + &Type, + ImageRecordList + ); + + // Make sure the attributes of the descriptor match the returned sec= tion type. + // DATA sections should have execution protection and CODE sections = should have + // write protection. + if ((Type =3D=3D SectionTypeNotFound) || + ((Type =3D=3D SectionTypeData) && (MemoryMap[Index].Attribute = =3D=3D EFI_MEMORY_RP)) || + ((Type =3D=3D SectionTypeCode) && (MemoryMap[Index].Attribute = =3D=3D EFI_MEMORY_XP))) + { + return FALSE; + } + + // If the bit associated with image found has already been set, then= there must be a duplicate + // in the memory map meaning it is invalid. + UT_ASSERT_EQUAL (ImageSectionsBitmap & ReturnSectionBitmask, 0); + + ImageSectionsBitmap |=3D ReturnSectionBitmask; + } + } + + // If every bit in ImageSectionsBitmap is set, the return value will be = TRUE + return !(~ImageSectionsBitmap); +} + +/** + Separate the image sections in the memory map and run a check to ensure = the output is valid. + + @param[in] Context Context containing the memory map and image record= pointers + + @retval TRUE if the memory map is split correctly +**/ +STATIC +BOOLEAN +SeparateAndCheck ( + IN IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *Context + ) +{ + UINTN MemoryMapSize; + + MemoryMapSize =3D BASE_MEMORY_MAP_SIZE; + + // Separate the memory map so each image section has its own descriptor + SplitTable ( + &MemoryMapSize, + Context->MemoryMap, + DESCRIPTOR_SIZE, + &Context->ImageList, + NUMBER_OF_ADDITIONAL_DESCRIPTORS + ); + + // Ensure the updated memory map is valid + return IsMemoryMapValid (MemoryMapSize, Context->MemoryMap, &Context->Im= ageList); +} + +/** + Test the case where the image range contains multiple code sections and = does not perfectly align with + the existing memory descriptor. + + @param[in] Context Context containing the memory map and image record= pointers + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +MaxOutAdditionalDescriptors ( + IN UNIT_TEST_CONTEXT Context + ) +{ + IMAGE_PROPERTIES_RECORD *Image1; + IMAGE_PROPERTIES_RECORD *Image2; + IMAGE_PROPERTIES_RECORD *Image3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *AddCodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *AddCodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *AddCodeSectionInImage3; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext; + + TestContext =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context; + + Image1 =3D CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECO= RD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image2 =3D CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image3 =3D CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + + CodeSectionInImage1 =3D CR (Image1->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage2 =3D CR (Image2->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage3 =3D CR (Image3->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + + /////////////// + // Descriptor 1 + /////////////// + // | | | | | | | | + // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 | + // | | | | | | | | + + Image1->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 1) + EFI_PAGE_SIZE; + Image1->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE - EFI_PAGE_SIZE; + Image1->CodeSegmentCount =3D 2; + CodeSectionInImage1->CodeSegmentBase =3D Image1->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage1->CodeSegmentSize =3D EFI_PAGE_SIZE; + TestContext->MemoryMap[1].Type =3D EfiBootServicesCode; + + AddCodeSectionInImage1 =3D AllocateZeroPool (sizeof (IM= AGE_PROPERTIES_RECORD_CODE_SECTION)); + AddCodeSectionInImage1->Signature =3D IMAGE_PROPERTIES_RECORD_CODE= _SECTION_SIGNATURE; + AddCodeSectionInImage1->CodeSegmentBase =3D CodeSectionInImage1->CodeSeg= mentBase + CodeSectionInImage1->CodeSegmentSize + EFI_PAGE_SIZE; + AddCodeSectionInImage1->CodeSegmentSize =3D EFI_PAGE_SIZE; + + InsertTailList (&Image1->CodeSegmentList, &AddCodeSectionInImage1->Link); + + /////////////// + // Descriptor 2 + /////////////// + // | | | | | | | | + // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 | + // | | | | | | | | + + Image2->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 2) + EFI_PAGE_SIZE; + Image2->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE - EFI_PAGE_SIZE; + Image2->CodeSegmentCount =3D 2; + CodeSectionInImage2->CodeSegmentBase =3D Image2->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage2->CodeSegmentSize =3D EFI_PAGE_SIZE; + TestContext->MemoryMap[2].Type =3D EfiLoaderCode; + + AddCodeSectionInImage2 =3D AllocateZeroPool (sizeof (IM= AGE_PROPERTIES_RECORD_CODE_SECTION)); + AddCodeSectionInImage2->Signature =3D IMAGE_PROPERTIES_RECORD_CODE= _SECTION_SIGNATURE; + AddCodeSectionInImage2->CodeSegmentBase =3D CodeSectionInImage2->CodeSeg= mentBase + CodeSectionInImage2->CodeSegmentSize + EFI_PAGE_SIZE; + AddCodeSectionInImage2->CodeSegmentSize =3D EFI_PAGE_SIZE; + + InsertTailList (&Image2->CodeSegmentList, &AddCodeSectionInImage2->Link); + + /////////////// + // Descriptor 3 + /////////////// + // | | | | | | | | + // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 | + // | | | | | | | | + + Image3->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 3) + EFI_PAGE_SIZE; + Image3->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE - EFI_PAGE_SIZE; + Image3->CodeSegmentCount =3D 2; + CodeSectionInImage3->CodeSegmentBase =3D Image3->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage3->CodeSegmentSize =3D EFI_PAGE_SIZE; + TestContext->MemoryMap[3].Type =3D EfiRuntimeServicesCode; + + AddCodeSectionInImage3 =3D AllocateZeroPool (sizeof (IM= AGE_PROPERTIES_RECORD_CODE_SECTION)); + AddCodeSectionInImage3->Signature =3D IMAGE_PROPERTIES_RECORD_CODE= _SECTION_SIGNATURE; + AddCodeSectionInImage3->CodeSegmentBase =3D CodeSectionInImage3->CodeSeg= mentBase + CodeSectionInImage3->CodeSegmentSize + EFI_PAGE_SIZE; + AddCodeSectionInImage3->CodeSegmentSize =3D EFI_PAGE_SIZE; + + InsertTailList (&Image3->CodeSegmentList, &AddCodeSectionInImage3->Link); + + UT_ASSERT_TRUE (SeparateAndCheck (TestContext)); + + return UNIT_TEST_PASSED; +} + +/** + Test the case where multiple image ranges lie within an existing memory = descriptor. + + @param[in] Context Context containing the memory map and image record= pointers + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +MultipleImagesInOneDescriptor ( + IN UNIT_TEST_CONTEXT Context + ) +{ + IMAGE_PROPERTIES_RECORD *Image1; + IMAGE_PROPERTIES_RECORD *Image2; + IMAGE_PROPERTIES_RECORD *Image3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage3; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext; + + TestContext =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context; + + Image1 =3D CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECO= RD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image2 =3D CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image3 =3D CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + + CodeSectionInImage1 =3D CR (Image1->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage2 =3D CR (Image2->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage3 =3D CR (Image3->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + + /////////////// + // Descriptor 1 + /////////////// + // | | | | | | | | | = | | | | + // | 4K PAGE | DATA | CODE | DATA | 4K PAGE | DATA | CODE | DATA | DATA = | CODE | DATA | 4K PAGE | + // | | | | | | | | | = | | | | + + Image1->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 1) + EFI_PAGE_SIZE; + Image1->ImageSize =3D EFI_PAGES_TO_SIZE (3); + Image1->CodeSegmentCount =3D 1; + CodeSectionInImage1->CodeSegmentBase =3D Image1->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage1->CodeSegmentSize =3D EFI_PAGE_SIZE; + TestContext->MemoryMap[1].Type =3D EfiBootServicesCode; + + Image2->ImageBase =3D Image1->ImageBase + Image1->Ima= geSize + EFI_PAGE_SIZE; + Image2->ImageSize =3D EFI_PAGES_TO_SIZE (3); + Image2->CodeSegmentCount =3D 1; + CodeSectionInImage2->CodeSegmentBase =3D Image2->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage2->CodeSegmentSize =3D EFI_PAGE_SIZE; + + Image3->ImageBase =3D Image2->ImageBase + Image2->Ima= geSize; + Image3->ImageSize =3D EFI_PAGES_TO_SIZE (3); + Image3->CodeSegmentCount =3D 1; + CodeSectionInImage3->CodeSegmentBase =3D Image3->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage3->CodeSegmentSize =3D EFI_PAGE_SIZE; + + UT_ASSERT_TRUE (SeparateAndCheck (TestContext)); + + return UNIT_TEST_PASSED; +} + +/** + Test the case where all image ranges do not fit perfectly within an exis= ting memory descriptor. + + @param[in] Context Context containing the memory map and image record= pointers + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +ImagesDontFitDescriptors ( + IN UNIT_TEST_CONTEXT Context + ) +{ + IMAGE_PROPERTIES_RECORD *Image1; + IMAGE_PROPERTIES_RECORD *Image2; + IMAGE_PROPERTIES_RECORD *Image3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage3; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext; + + TestContext =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context; + + Image1 =3D CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECO= RD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image2 =3D CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image3 =3D CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + + CodeSectionInImage1 =3D CR (Image1->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage2 =3D CR (Image2->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage3 =3D CR (Image3->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + + /////////////// + // Descriptor 1 + /////////////// + // | | | | | + // | 4K PAGE | DATA | CODE * 2 | DATA * 8 | + // | | | | | + + Image1->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 1) + EFI_PAGE_SIZE; + Image1->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE; + Image1->CodeSegmentCount =3D 1; + CodeSectionInImage1->CodeSegmentBase =3D Image1->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage1->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (2); + TestContext->MemoryMap[1].Type =3D EfiBootServicesCode; + + /////////////// + // Descriptor 3 + /////////////// + // | | | | | + // | DATA | CODE * 3 | DATA * 7 | 4K PAGE | + // | | | | | + + Image2->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 3); + Image2->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE; + Image2->CodeSegmentCount =3D 1; + CodeSectionInImage2->CodeSegmentBase =3D Image2->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage2->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (3); + TestContext->MemoryMap[3].Type =3D EfiLoaderCode; + + /////////////// + // Descriptor 4 + /////////////// + // | | | | | | + // | 4K PAGE | DATA | CODE * 2 | DATA * 7 | 4K PAGE | + // | | | | | | + + Image3->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 4) + EFI_PAGE_SIZE; + Image3->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE - EF= I_PAGE_SIZE - EFI_PAGE_SIZE; + Image3->CodeSegmentCount =3D 1; + CodeSectionInImage3->CodeSegmentBase =3D Image3->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage3->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (2); + TestContext->MemoryMap[4].Type =3D EfiRuntimeServicesCode; + + UT_ASSERT_TRUE (SeparateAndCheck (TestContext)); + + return UNIT_TEST_PASSED; +} + +/** + Test the case where all image ranges fit perfectly within an existing me= mory descriptor. + + @param[in] Context Context containing the memory map and image record= pointers + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +ImagesFitDescriptors ( + IN UNIT_TEST_CONTEXT Context + ) +{ + IMAGE_PROPERTIES_RECORD *Image1; + IMAGE_PROPERTIES_RECORD *Image2; + IMAGE_PROPERTIES_RECORD *Image3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage3; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext; + + TestContext =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context; + + Image1 =3D CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECO= RD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image2 =3D CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + Image3 =3D CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, = IMAGE_PROPERTIES_RECORD_SIGNATURE); + + CodeSectionInImage1 =3D CR (Image1->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage2 =3D CR (Image2->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + CodeSectionInImage3 =3D CR (Image3->CodeSegmentList.ForwardLink, IMAGE_P= ROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_S= IGNATURE); + + /////////////// + // Descriptor 1 + /////////////// + // | | | | + // | DATA | CODE * 3 | DATA * 8 | + // | | | | + + Image1->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 1); + Image1->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE; + Image1->CodeSegmentCount =3D 1; + CodeSectionInImage1->CodeSegmentBase =3D Image1->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage1->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (3); + TestContext->MemoryMap[1].Type =3D EfiBootServicesCode; + + /////////////// + // Descriptor 2 + /////////////// + // | | | | + // | DATA | CODE * 4 | DATA * 7 | + // | | | | + + Image2->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 2); + Image2->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE; + Image2->CodeSegmentCount =3D 1; + CodeSectionInImage2->CodeSegmentBase =3D Image2->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage2->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (4); + TestContext->MemoryMap[2].Type =3D EfiLoaderCode; + + /////////////// + // Descriptor 3 + /////////////// + // | | | | + // | DATA | CODE * 3 | DATA * 8 | + // | | | | + + Image3->ImageBase =3D BASE_DESCRIPTOR_START_ADDRESS (= 3); + Image3->ImageSize =3D BASE_DESCRIPTOR_ENTRY_SIZE; + Image3->CodeSegmentCount =3D 1; + CodeSectionInImage3->CodeSegmentBase =3D Image3->ImageBase + EFI_PAGE_SI= ZE; + CodeSectionInImage3->CodeSegmentSize =3D EFI_PAGES_TO_SIZE (3); + TestContext->MemoryMap[3].Type =3D EfiRuntimeServicesCode; + + UT_ASSERT_TRUE (SeparateAndCheck (TestContext)); + + return UNIT_TEST_PASSED; +} + +/** + Free all allocated memory. + + @param[in] Context Context containing the memory map and image record= pointers +**/ +VOID +EFIAPI +TestCleanup ( + IN UNIT_TEST_CONTEXT Context + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *CodeSegmentListHead; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext; + + TestContext =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context; + ImageRecordLink =3D &TestContext->ImageList; + + while (!IsListEmpty (ImageRecordLink)) { + ImageRecord =3D CR ( + ImageRecordLink->ForwardLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + + CodeSegmentListHead =3D &ImageRecord->CodeSegmentList; + while (!IsListEmpty (CodeSegmentListHead)) { + ImageRecordCodeSection =3D CR ( + CodeSegmentListHead->ForwardLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGN= ATURE + ); + RemoveEntryList (&ImageRecordCodeSection->Link); + FreePool (ImageRecordCodeSection); + } + + RemoveEntryList (&ImageRecord->Link); + FreePool (ImageRecord); + } + + if (TestContext->MemoryMap !=3D NULL) { + FreePool (TestContext->MemoryMap); + } +} + +/** + Create a generic image list with the proper signatures which will be cus= tomized for each test + and allocate the default memory map. + + @param[out] TestContext Context which will be passed to the test cases +**/ +STATIC +VOID +CreateBaseContextEntry ( + OUT IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *TestContext + ) +{ + IMAGE_PROPERTIES_RECORD *Image1; + IMAGE_PROPERTIES_RECORD *Image2; + IMAGE_PROPERTIES_RECORD *Image3; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage1; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage2; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *CodeSectionInImage3; + + InitializeListHead (&TestContext->ImageList); + + Image1 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D)); + CodeSectionInImage1 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D_CODE_SECTION)); + + Image1->Signature =3D IMAGE_PROPERTIES_RECORD_SIGNATURE; + CodeSectionInImage1->Signature =3D IMAGE_PROPERTIES_RECORD_CODE_SECTION_= SIGNATURE; + InitializeListHead (&Image1->CodeSegmentList); + + InsertTailList (&TestContext->ImageList, &Image1->Link); + InsertTailList (&Image1->CodeSegmentList, &CodeSectionInImage1->Link); + + Image2 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D)); + CodeSectionInImage2 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D_CODE_SECTION)); + + Image2->Signature =3D IMAGE_PROPERTIES_RECORD_SIGNATURE; + CodeSectionInImage2->Signature =3D IMAGE_PROPERTIES_RECORD_CODE_SECTION_= SIGNATURE; + InitializeListHead (&Image2->CodeSegmentList); + + InsertTailList (&TestContext->ImageList, &Image2->Link); + InsertTailList (&Image2->CodeSegmentList, &CodeSectionInImage2->Link); + + Image3 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D)); + CodeSectionInImage3 =3D AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECOR= D_CODE_SECTION)); + + Image3->Signature =3D IMAGE_PROPERTIES_RECORD_SIGNATURE; + CodeSectionInImage3->Signature =3D IMAGE_PROPERTIES_RECORD_CODE_SECTION_= SIGNATURE; + InitializeListHead (&Image3->CodeSegmentList); + + InsertTailList (&TestContext->ImageList, &Image3->Link); + InsertTailList (&Image3->CodeSegmentList, &CodeSectionInImage3->Link); + + TestContext->MemoryMap =3D AllocateZeroPool (SPLIT_MEMORY_MAP_SIZE); + CopyMem (TestContext->MemoryMap, &BaseMemoryMap, BASE_MEMORY_MAP_SIZE); + + return; +} + +/** + Initialze the unit test framework, suite, and unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available = to + initialize the unit tests. +**/ +STATIC +EFI_STATUS +EFIAPI +UnitTestingEntry ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE ImagePropertiesRecordTests; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *Context1; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *Context2; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *Context3; + IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *Context4; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSIO= N)); + + Framework =3D NULL; + + Context1 =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPo= ol (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT)); + Context2 =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPo= ol (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT)); + Context3 =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPo= ol (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT)); + Context4 =3D (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPo= ol (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT)); + + CreateBaseContextEntry (Context1); + CreateBaseContextEntry (Context2); + CreateBaseContextEntry (Context3); + CreateBaseContextEntry (Context4); + + // + // Start setting up the test framework for running the tests. + // + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCa= llerBaseName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r\n= ", Status)); + goto EXIT; + } + + // + // Populate the Unit Test Suite. + // + Status =3D CreateUnitTestSuite (&ImagePropertiesRecordTests, Framework, = "Image Properties Record Tests", "ImagePropertiesRecordLib.SplitTable", NUL= L, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Image Prop= erties Record Tests\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // + // --------------Suite-----------Description--------------Name----------= Function--------Pre---Post-------------------Context----------- + // + AddTestCase (ImagePropertiesRecordTests, "All images fit perfectly into = existing descriptors", "ImagesFitDescriptors", ImagesFitDescriptors, NULL, = TestCleanup, Context1); + AddTestCase (ImagePropertiesRecordTests, "All images don't fit perfectly= into existing descriptors", "ImagesDontFitDescriptors", ImagesDontFitDescr= iptors, NULL, TestCleanup, Context2); + AddTestCase (ImagePropertiesRecordTests, "All Images are contined In sin= gle descriptor", "MultipleImagesInOneDescriptor", MultipleImagesInOneDescri= ptor, NULL, TestCleanup, Context3); + AddTestCase (ImagePropertiesRecordTests, "Multiple code sections each im= age", "MaxOutAdditionalDescriptors", MaxOutAdditionalDescriptors, NULL, Tes= tCleanup, Context4); + + // + // Execute the tests. + // + Status =3D RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/// +/// Avoid ECC error for function name that starts with lower case letter +/// +#define ImagePropertiesRecordLibUnitTestMain main + +/** + Standard POSIX C entry point for host based unit test execution. + + @param[in] Argc Number of arguments + @param[in] Argv Array of pointers to arguments + + @retval 0 Success + @retval other Error +**/ +INT32 +ImagePropertiesRecordLibUnitTestMain ( + IN INT32 Argc, + IN CHAR8 *Argv[] + ) +{ + return UnitTestingEntry (); +} diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePr= opertiesRecordLibUnitTestHost.inf b/MdeModulePkg/Library/ImagePropertiesRec= ordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf new file mode 100644 index 000000000000..cbc64a14bde7 --- /dev/null +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertie= sRecordLibUnitTestHost.inf @@ -0,0 +1,35 @@ +## @file +# Unit tests the SplitTable() ImagePropertiesRecordLib Logic +# +# Copyright (C) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D ImagePropertiesRecordLibUnitTestHost + FILE_GUID =3D 45B39FAA-E25D-4724-A6F4-93C0C8588A80 + MODULE_TYPE =3D HOST_APPLICATION + VERSION_STRING =3D 1.0 + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64 +# + +[Sources] + ImagePropertiesRecordLibUnitTestHost.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UnitTestLib + ImagePropertiesRecordLib diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test= /MdeModulePkgHostTest.dsc index 8fb982a2703d..2b8cbb867a73 100644 --- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc @@ -54,6 +54,11 @@ [Components] DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf } =20 + MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRe= cordLibUnitTestHost.inf { + + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordL= ib/ImagePropertiesRecordLib.inf + } + # # Build HOST_APPLICATION Libraries # --=20 2.42.0.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#110656): https://edk2.groups.io/g/devel/message/110656 Mute This Topic: https://groups.io/mt/102368848/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-