From nobody Thu Nov 14 07:12:03 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+110655+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+110655+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=mijn4k/kCb2WWnrZYGfWxDeqAiCBqpFY+gPiU+sRfYzd066sc062A7lja6CpgI3dHl2pMl+OYyFl2VFk7fULsX30UE852cgEYYdWDDqC1VjkqbxkHAmk7sZD3HtvuQW+wnUeqMtXI5b0zsxLKaFW6zK2AT/gaAaIfkLwVg/rfXg= 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=GoYJQYWe6BBezx4sXtiRYtC/iYzvC5e7155cFlIq/KE=; b=Ch7FxcLTzDB5f0DsMQSsM4RKlMYf6NRC4Pt/lekODBmP92hMmrapcYAt8GE/7nbH41OrQgw3Ls4zUc8KQhJY5IrVBxF7v20fsk4jiw518LMoL2DuDSI3GUhFIU9N3hkd9DpUkymL0QjTJivnSLRkqGvSJ6xTnjzVi8poenXN9io= 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+110655+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 1699031844915411.2726164553708; Fri, 3 Nov 2023 10:17:24 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=hoFPsiaXIZdii2wNQvzTBvNVVcnZCGyuS+88weIJxAA=; 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=1699031843; v=1; b=tG8LC7LduA6+aOREw5OrG1cHpEIY17ZchdWWkqAMuP57TeHvgPCKB7cmRNENd02bWupejuJt 0KLQ0EnYxz1c2WT12p027TQtI1HFfczh81/fHVJg1IVwXSS5fiYTUzOvLCU/eTtEoVfbBWwLnPJ MEuyJ8F7eFHAQcJcYgK1xx8k= X-Received: by 127.0.0.2 with SMTP id JPTpYY1788612xhp4g2Ye0A5; Fri, 03 Nov 2023 10:17:23 -0700 X-Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mx.groups.io with SMTP id smtpd.web10.59753.1699031842827983024 for ; Fri, 03 Nov 2023 10:17:22 -0700 X-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1cc5b705769so20787635ad.0 for ; Fri, 03 Nov 2023 10:17:22 -0700 (PDT) X-Gm-Message-State: ZgD96XHA4ZuvXFWlPyAQ9tHUx1787277AA= X-Google-Smtp-Source: AGHT+IEpy+cnncXpxj4/q6vOMygd4zD5/GpZgUrUL0dAtNCdDlJkaG/9uNIKWh/LBNbVhYGiJdQ29Q== X-Received: by 2002:a17:902:dacc:b0:1cc:4677:2f0e with SMTP id q12-20020a170902dacc00b001cc46772f0emr20545979plx.45.1699031841844; Fri, 03 Nov 2023 10:17:21 -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.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Nov 2023 10:17:21 -0700 (PDT) From: "Taylor Beebe" To: devel@edk2.groups.io Cc: Jian J Wang , Liming Gao , Dandan Bi Subject: [edk2-devel] [PATCH v4 07/14] MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib Date: Fri, 3 Nov 2023 10:16:59 -0700 Message-ID: <20231103171706.148-8-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: 1699031847077100031 Content-Type: text/plain; charset="utf-8" Move some DXE MAT logic to ImagePropertiesRecordLib to consolidate code and enable unit testability. Cc: Jian J Wang Cc: Liming Gao Cc: Dandan Bi Signed-off-by: Taylor Beebe Reviewed-by: Liming Gao --- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c = | 774 +------------------- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c = | 24 +- MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c = | 770 +++++++++++++++++++ MdeModulePkg/Core/Dxe/DxeMain.h = | 20 - MdeModulePkg/Core/Dxe/DxeMain.inf = | 1 + MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h = | 159 ++++ MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf= | 4 + 7 files changed, 947 insertions(+), 805 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModule= Pkg/Core/Dxe/Misc/MemoryAttributesTable.c index 64b0aa1ff5e5..51630f504ea1 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -14,6 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include =20 #include =20 @@ -333,45 +334,6 @@ CoreInitializeMemoryAttributesTable ( // Below functions are for MemoryMap // =20 -/** - Converts a number of EFI_PAGEs to a size in bytes. - - NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only. - - @param Pages The number of EFI_PAGES. - - @return The number of bytes associated with the number of EFI_PAGEs spe= cified - by Pages. -**/ -STATIC -UINT64 -EfiPagesToSize ( - IN UINT64 Pages - ) -{ - return LShiftU64 (Pages, EFI_PAGE_SHIFT); -} - -/** - Converts a size, in bytes, to a number of EFI_PAGESs. - - NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only. - - @param Size A size in bytes. - - @return The number of EFI_PAGESs associated with the number of bytes sp= ecified - by Size. - -**/ -STATIC -UINT64 -EfiSizeToPages ( - IN UINT64 Size - ) -{ - return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MAS= K) ? 1 : 0); -} - /** Acquire memory lock on mMemoryAttributesTableLock. **/ @@ -396,48 +358,6 @@ CoreReleasemMemoryAttributesTableLock ( CoreReleaseLock (&mMemoryAttributesTableLock); } =20 -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param MemoryMap A pointer to the buffer in which firmware= places - the current memory map. - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMO= RY_DESCRIPTOR. -**/ -STATIC -VOID -SortMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR TempMemoryMap; - - MemoryMapEntry =3D MemoryMap; - NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descripto= rSize); - MemoryMapEnd =3D (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + Me= moryMapSize); - while (MemoryMapEntry < MemoryMapEnd) { - while (NextMemoryMapEntry < MemoryMapEnd) { - if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStar= t) { - CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRI= PTOR)); - CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DE= SCRIPTOR)); - CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DE= SCRIPTOR)); - } - - NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, D= escriptorSize); - } - - MemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descrip= torSize); - NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descrip= torSize); - } - - return; -} - /** Merge continous memory map entries whose have same attributes. =20 @@ -471,7 +391,7 @@ MergeMemoryMap ( =20 do { MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStar= t); - MemoryBlockLength =3D (UINT64)(EfiPagesToSize (NewMemoryMapEntry->Nu= mberOfPages)); + MemoryBlockLength =3D LShiftU64 (NewMemoryMapEntry->NumberOfPages, E= FI_PAGE_SHIFT); if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && (NewMemoryMapEntry->Type =3D=3D NextMemoryMapEntry->Type) && (NewMemoryMapEntry->Attribute =3D=3D NextMemoryMapEntry->Attribu= te) && @@ -538,434 +458,6 @@ EnforceMemoryMapAttribute ( return; } =20 -/** - Return the first image record, whose [ImageBase, ImageSize] covered by [= Buffer, Length]. - - @param Buffer Start Address - @param Length Address length - @param ImageRecordList Image record list - - @return first image record covered by [buffer, length] -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -GetImageRecordByAddress ( - IN EFI_PHYSICAL_ADDRESS Buffer, - IN UINT64 Length, - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - - for (ImageRecordLink =3D ImageRecordList->ForwardLink; - ImageRecordLink !=3D ImageRecordList; - ImageRecordLink =3D ImageRecordLink->ForwardLink) - { - ImageRecord =3D CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((Buffer <=3D ImageRecord->ImageBase) && - (Buffer + Length >=3D ImageRecord->ImageBase + ImageRecord->ImageS= ize)) - { - return ImageRecord; - } - } - - return NULL; -} - -/** - Set the memory map to new entries, according to one old entry, - based upon PE code section and data section in image record - - @param ImageRecord An image record whose [ImageBase, ImageSi= ze] covered - by old memory map entry. - @param NewRecord A pointer to several new memory map entri= es. - The caller gurantee the buffer size be 1 + - (SplitRecordCount * DescriptorSize) calcu= lated - below. - @param OldRecord A pointer to one old memory map entry. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMO= RY_DESCRIPTOR. -**/ -STATIC -UINTN -SetNewRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINTN NewRecordCount; - UINT64 PhysicalEnd; - UINT64 ImageEnd; - - CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); - PhysicalEnd =3D TempRecord.PhysicalStart + EfiPagesToSize (TempRecord= .NumberOfPages); - NewRecordCount =3D 0; - - ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLin= k; - ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection =3D CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE - ); - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLink; - - if (TempRecord.PhysicalStart <=3D ImageRecordCodeSection->CodeSegmentB= ase) { - // - // DATA - // - NewRecord->Type =3D TempRecord.Type; - NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; - NewRecord->VirtualStart =3D 0; - NewRecord->NumberOfPages =3D EfiSizeToPages (ImageRecordCodeSection-= >CodeSegmentBase - NewRecord->PhysicalStart); - NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_XP; - if (NewRecord->NumberOfPages !=3D 0) { - NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount++; - } - - // - // CODE - // - NewRecord->Type =3D TempRecord.Type; - NewRecord->PhysicalStart =3D ImageRecordCodeSection->CodeSegmentBase; - NewRecord->VirtualStart =3D 0; - NewRecord->NumberOfPages =3D EfiSizeToPages (ImageRecordCodeSection-= >CodeSegmentSize); - NewRecord->Attribute =3D (TempRecord.Attribute & (~EFI_MEMORY_XP= )) | EFI_MEMORY_RO; - if (NewRecord->NumberOfPages !=3D 0) { - NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount++; - } - - TempRecord.PhysicalStart =3D ImageRecordCodeSection->CodeSegmentBase= + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize)= ); - TempRecord.NumberOfPages =3D EfiSizeToPages (PhysicalEnd - TempRecor= d.PhysicalStart); - if (TempRecord.NumberOfPages =3D=3D 0) { - break; - } - } - } - - ImageEnd =3D ImageRecord->ImageBase + ImageRecord->ImageSize; - - // - // Final DATA - // - if (TempRecord.PhysicalStart < ImageEnd) { - NewRecord->Type =3D TempRecord.Type; - NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; - NewRecord->VirtualStart =3D 0; - NewRecord->NumberOfPages =3D EfiSizeToPages (ImageEnd - TempRecord.Phy= sicalStart); - NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_XP; - NewRecordCount++; - } - - return NewRecordCount; -} - -/** - Return the max number of new splitted entries, according to one old entr= y, - based upon PE code section and data section. - - @param OldRecord A pointer to one old memory map entry. - - @retval 0 no entry need to be splitted. - @return the max number of new splitted entries -**/ -STATIC -UINTN -GetMaxSplitRecordCount ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - UINTN SplitRecordCount; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - - SplitRecordCount =3D 0; - PhysicalStart =3D OldRecord->PhysicalStart; - PhysicalEnd =3D OldRecord->PhysicalStart + EfiPagesToSize (OldRecor= d->NumberOfPages); - - do { - ImageRecord =3D GetImageRecordByAddress (PhysicalStart, PhysicalEnd - = PhysicalStart, ImageRecordList); - if (ImageRecord =3D=3D NULL) { - break; - } - - SplitRecordCount +=3D (2 * ImageRecord->CodeSegmentCount + 1); - PhysicalStart =3D ImageRecord->ImageBase + ImageRecord->ImageSize; - } while ((ImageRecord !=3D NULL) && (PhysicalStart < PhysicalEnd)); - - if (SplitRecordCount !=3D 0) { - SplitRecordCount--; - } - - return SplitRecordCount; -} - -/** - Split the memory map to new entries, according to one old entry, - based upon PE code section and data section. - - @param OldRecord A pointer to one old memory map entr= y. - @param NewRecord A pointer to several new memory map = entries. - The caller gurantee the buffer size = be 1 + - (SplitRecordCount * DescriptorSize) = calculated - below. - @param MaxSplitRecordCount The max number of splitted entries - @param DescriptorSize Size, in bytes, of an individual EFI= _MEMORY_DESCRIPTOR. - @param ImageRecordList A list of IMAGE_PROPERTIES_RECORD en= tries used when searching - for an image record contained by the= memory range described in - the existing EFI memory map descript= or OldRecord - - @retval 0 no entry is splitted. - @return the real number of splitted record. -**/ -STATIC -UINTN -SplitRecord ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN UINTN MaxSplitRecordCount, - IN UINTN DescriptorSize, - IN LIST_ENTRY *ImageRecordList - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NewImageRecord; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - UINTN NewRecordCount; - UINTN TotalNewRecordCount; - BOOLEAN IsLastRecordData; - - if (MaxSplitRecordCount =3D=3D 0) { - CopyMem (NewRecord, OldRecord, DescriptorSize); - return 0; - } - - TotalNewRecordCount =3D 0; - - // - // Override previous record - // - CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); - PhysicalStart =3D TempRecord.PhysicalStart; - PhysicalEnd =3D TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.= NumberOfPages); - - ImageRecord =3D NULL; - do { - NewImageRecord =3D GetImageRecordByAddress (PhysicalStart, PhysicalEnd= - PhysicalStart, ImageRecordList); - if (NewImageRecord =3D=3D NULL) { - // - // No more image covered by this range, stop - // - if ((PhysicalEnd > PhysicalStart) && (ImageRecord !=3D NULL)) { - // - // If this is still address in this record, need record. - // - NewRecord =3D PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, Descri= ptorSize); - IsLastRecordData =3D FALSE; - if ((NewRecord->Attribute & EFI_MEMORY_XP) !=3D 0) { - IsLastRecordData =3D TRUE; - } - - if (IsLastRecordData) { - // - // Last record is DATA, just merge it. - // - NewRecord->NumberOfPages =3D EfiSizeToPages (PhysicalEnd - NewRe= cord->PhysicalStart); - } else { - // - // Last record is CODE, create a new DATA entry. - // - NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, = DescriptorSize); - NewRecord->Type =3D TempRecord.Type; - NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; - NewRecord->VirtualStart =3D 0; - NewRecord->NumberOfPages =3D TempRecord.NumberOfPages; - NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_X= P; - TotalNewRecordCount++; - } - } - - break; - } - - ImageRecord =3D NewImageRecord; - - // - // Set new record - // - NewRecordCount =3D SetNewRecord (ImageRecord, NewRecord, &TempRe= cord, DescriptorSize); - TotalNewRecordCount +=3D NewRecordCount; - NewRecord =3D (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord = + NewRecordCount * DescriptorSize); - - // - // Update PhysicalStart, in order to exclude the image buffer already = splitted. - // - PhysicalStart =3D ImageRecord->ImageBase + ImageRecord->Ima= geSize; - TempRecord.PhysicalStart =3D PhysicalStart; - TempRecord.NumberOfPages =3D EfiSizeToPages (PhysicalEnd - PhysicalSta= rt); - } while ((ImageRecord !=3D NULL) && (PhysicalStart < PhysicalEnd)); - - // - // The logic in function SplitTable() ensures that TotalNewRecordCount w= ill not be zero if the - // code reaches here. - // - ASSERT (TotalNewRecordCount !=3D 0); - return TotalNewRecordCount - 1; -} - -/** - Split the original memory map, and add more entries to describe PE code = section and data section. - This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. - This function will merge entries with same attributes finally. - - NOTE: It assumes PE code/data section are page aligned. - NOTE: It assumes enough entry is prepared for new memory map. - - Split table: - +---------------+ - | Record X | - +---------------+ - | Record RtCode | - +---------------+ - | Record Y | - +---------------+ - =3D=3D> - +---------------+ - | Record X | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF1 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF2 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record Y | - +---------------+ - - @param MemoryMapSize A pointer to the size, in bytes,= of the - MemoryMap buffer. On input, this= is the size of - old MemoryMap before split. The = actual buffer - size of MemoryMap is MemoryMapSi= ze + - (AdditionalRecordCount * Descrip= torSize) calculated - below. On output, it is the size= of new MemoryMap - after split. - @param MemoryMap A pointer to the buffer in which= firmware places - the current memory map. - @param DescriptorSize Size, in bytes, of an individual= EFI_MEMORY_DESCRIPTOR. - @param ImageRecordList A list of IMAGE_PROPERTIES_RECOR= D entries used when searching - for an image record contained by= the memory range described in - EFI memory map descriptors. - @param NumberOfAdditionalDescriptors The number of unused descriptors= at the end of the input MemoryMap. -**/ -STATIC -VOID -SplitTable ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize, - IN LIST_ENTRY *ImageRecordList, - IN UINTN NumberOfAdditionalDescriptors - ) -{ - INTN IndexOld; - INTN IndexNew; - UINTN MaxSplitRecordCount; - UINTN RealSplitRecordCount; - UINTN TotalSplitRecordCount; - - TotalSplitRecordCount =3D 0; - // - // Let old record point to end of valid MemoryMap buffer. - // - IndexOld =3D ((*MemoryMapSize) / DescriptorSize) - 1; - // - // Let new record point to end of full MemoryMap buffer. - // - IndexNew =3D ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditiona= lDescriptors; - for ( ; IndexOld >=3D 0; IndexOld--) { - MaxSplitRecordCount =3D GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR= *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList); - // - // Split this MemoryMap record - // - IndexNew -=3D MaxSplitRecordCount; - RealSplitRecordCount =3D SplitRecord ( - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap = + IndexOld * DescriptorSize), - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap = + IndexNew * DescriptorSize), - MaxSplitRecordCount, - DescriptorSize, - ImageRecordList - ); - // - // Adjust IndexNew according to real split. - // - CopyMem ( - ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRec= ordCount) * DescriptorSize), - ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - RealSplitRecordCount * DescriptorSize - ); - IndexNew =3D IndexNew + MaxSplitRecordCount - RealSplitR= ecordCount; - TotalSplitRecordCount +=3D RealSplitRecordCount; - IndexNew--; - } - - // - // Move all records to the beginning. - // - CopyMem ( - MemoryMap, - (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecord= Count) * DescriptorSize, - (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize - ); - - *MemoryMapSize =3D (*MemoryMapSize) + DescriptorSize * TotalSplitRecordC= ount; - - // - // Sort from low to high (Just in case) - // - SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Set RuntimeData to XP - // - EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Merge same type to save entry size - // - MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize); - - return; -} - /** This function for GetMemoryMap() with properties table capability. =20 @@ -1044,6 +536,16 @@ CoreGetMemoryMapWithSeparatedImageSection ( // Split PE code/data // SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImageProper= tiesPrivateData.ImageRecordList, AdditionalRecordCount); + + // + // Set RuntimeData to XP + // + EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSiz= e); + + // + // Merge same type to save entry size + // + MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize); } } =20 @@ -1074,217 +576,6 @@ SetMemoryAttributesTableSectionAlignment ( } } =20 -/** - Swap two code sections in image record. - - @param FirstImageRecordCodeSection first code section in image record - @param SecondImageRecordCodeSection second code section in image reco= rd -**/ -STATIC -VOID -SwapImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; - - TempImageRecordCodeSection.CodeSegmentBase =3D FirstImageRecordCodeSecti= on->CodeSegmentBase; - TempImageRecordCodeSection.CodeSegmentSize =3D FirstImageRecordCodeSecti= on->CodeSegmentSize; - - FirstImageRecordCodeSection->CodeSegmentBase =3D SecondImageRecordCodeSe= ction->CodeSegmentBase; - FirstImageRecordCodeSection->CodeSegmentSize =3D SecondImageRecordCodeSe= ction->CodeSegmentSize; - - SecondImageRecordCodeSection->CodeSegmentBase =3D TempImageRecordCodeSec= tion.CodeSegmentBase; - SecondImageRecordCodeSection->CodeSegmentSize =3D TempImageRecordCodeSec= tion.CodeSegmentSize; -} - -/** - Sort code section in image record, based upon CodeSegmentBase from low t= o high. - - @param ImageRecord image record to be sorted -**/ -VOID -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *NextImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLi= nk; - NextImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLi= nk; - ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection =3D CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE - ); - while (NextImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLi= nk) { - NextImageRecordCodeSection =3D CR ( - NextImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_= SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSec= tion->CodeSegmentBase) { - SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecor= dCodeSection); - } - - NextImageRecordCodeSectionLink =3D NextImageRecordCodeSectionLink->F= orwardLink; - } - - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forward= Link; - NextImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forward= Link; - } -} - -/** - Check if code section in image record is valid. - - @param ImageRecord image record to be checked - - @retval TRUE image record is valid - @retval FALSE image record is invalid -**/ -BOOLEAN -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->C= odeSegmentCount)); - - ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLin= k; - ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; - LastImageRecordCodeSection =3D NULL; - while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection =3D CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE - ); - if (ImageRecordCodeSection->CodeSegmentSize =3D=3D 0) { - return FALSE; - } - - if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) { - return FALSE; - } - - if (ImageRecordCodeSection->CodeSegmentBase >=3D MAX_ADDRESS - ImageRe= cordCodeSection->CodeSegmentSize) { - return FALSE; - } - - if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection-= >CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return FALSE; - } - - if (LastImageRecordCodeSection !=3D NULL) { - if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCo= deSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) { - return FALSE; - } - } - - LastImageRecordCodeSection =3D ImageRecordCodeSection; - ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLink; - } - - return TRUE; -} - -/** - Swap two image records. - - @param FirstImageRecord first image record. - @param SecondImageRecord second image record. -**/ -STATIC -VOID -SwapImageRecord ( - IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, - IN IMAGE_PROPERTIES_RECORD *SecondImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD TempImageRecord; - - TempImageRecord.ImageBase =3D FirstImageRecord->ImageBase; - TempImageRecord.ImageSize =3D FirstImageRecord->ImageSize; - TempImageRecord.CodeSegmentCount =3D FirstImageRecord->CodeSegmentCount; - - FirstImageRecord->ImageBase =3D SecondImageRecord->ImageBase; - FirstImageRecord->ImageSize =3D SecondImageRecord->ImageSize; - FirstImageRecord->CodeSegmentCount =3D SecondImageRecord->CodeSegmentCou= nt; - - SecondImageRecord->ImageBase =3D TempImageRecord.ImageBase; - SecondImageRecord->ImageSize =3D TempImageRecord.ImageSize; - SecondImageRecord->CodeSegmentCount =3D TempImageRecord.CodeSegmentCount; - - SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord-= >CodeSegmentList); -} - -/** - Sort image record based upon the ImageBase from low to high. - - @param ImageRecordList Image record list to be sorted -**/ -STATIC -VOID -SortImageRecord ( - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NextImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *NextImageRecordLink; - LIST_ENTRY *ImageRecordEndLink; - - ImageRecordLink =3D ImageRecordList->ForwardLink; - NextImageRecordLink =3D ImageRecordLink->ForwardLink; - ImageRecordEndLink =3D ImageRecordList; - while (ImageRecordLink !=3D ImageRecordEndLink) { - ImageRecord =3D CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - while (NextImageRecordLink !=3D ImageRecordEndLink) { - NextImageRecord =3D CR ( - NextImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { - SwapImageRecord (ImageRecord, NextImageRecord); - } - - NextImageRecordLink =3D NextImageRecordLink->ForwardLink; - } - - ImageRecordLink =3D ImageRecordLink->ForwardLink; - NextImageRecordLink =3D ImageRecordLink->ForwardLink; - } -} - /** Insert image record. =20 @@ -1469,47 +760,6 @@ Finish: return; } =20 -/** - Find image record according to image base and size. - - @param ImageBase Base of PE image - @param ImageSize Size of PE image - @param ImageRecordList Image record list to be searched - - @return image record -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -FindImageRecord ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - - for (ImageRecordLink =3D ImageRecordList->ForwardLink; - ImageRecordLink !=3D ImageRecordList; - ImageRecordLink =3D ImageRecordLink->ForwardLink) - { - ImageRecord =3D CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((ImageBase =3D=3D ImageRecord->ImageBase) && - (ImageSize =3D=3D ImageRecord->ImageSize)) - { - return ImageRecord; - } - } - - return NULL; -} - /** Remove Image record. =20 diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/C= ore/Dxe/Misc/MemoryProtection.c index 7cc829b17402..977239d08afc 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -32,6 +32,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include =20 #include #include @@ -66,29 +67,6 @@ extern LIST_ENTRY mGcdMemorySpaceMap; =20 STATIC LIST_ENTRY mProtectedImageRecordList; =20 -/** - Sort code section in image record, based upon CodeSegmentBase from low t= o high. - - @param ImageRecord image record to be sorted -**/ -VOID -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - -/** - Check if code section in image record is valid. - - @param ImageRecord image record to be checked - - @retval TRUE image record is valid - @retval FALSE image record is invalid -**/ -BOOLEAN -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - /** Get the image type. =20 diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesR= ecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesR= ecordLib.c index df7c54ebb793..9fb3b922038f 100644 --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi= b.c +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi= b.c @@ -7,3 +7,773 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ + +#include + +#include +#include +#include +#include + +#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) + +#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) + +/** + Converts a number of EFI_PAGEs to a size in bytes. + + NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only. + + @param Pages The number of EFI_PAGES. + + @return The number of bytes associated with the number of EFI_PAGEs spe= cified + by Pages. +**/ +STATIC +UINT64 +EfiPagesToSize ( + IN UINT64 Pages + ) +{ + return LShiftU64 (Pages, EFI_PAGE_SHIFT); +} + +/** + Converts a size, in bytes, to a number of EFI_PAGESs. + + NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only. + + @param Size A size in bytes. + + @return The number of EFI_PAGESs associated with the number of bytes sp= ecified + by Size. + +**/ +STATIC +UINT64 +EfiSizeToPages ( + IN UINT64 Size + ) +{ + return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MAS= K) ? 1 : 0); +} + +/** + Sort memory map entries based upon PhysicalStart, from low to high. + + @param MemoryMap A pointer to the buffer in which firmware= places + the current memory map. + @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. + @param DescriptorSize Size, in bytes, of an individual EFI_MEMO= RY_DESCRIPTOR. +**/ +STATIC +VOID +SortMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + EFI_MEMORY_DESCRIPTOR TempMemoryMap; + + MemoryMapEntry =3D MemoryMap; + NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descripto= rSize); + MemoryMapEnd =3D (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + Me= moryMapSize); + while (MemoryMapEntry < MemoryMapEnd) { + while (NextMemoryMapEntry < MemoryMapEnd) { + if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStar= t) { + CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRI= PTOR)); + CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DE= SCRIPTOR)); + CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DE= SCRIPTOR)); + } + + NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, D= escriptorSize); + } + + MemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descrip= torSize); + NextMemoryMapEntry =3D NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, Descrip= torSize); + } + + return; +} + +/** + Return the first image record, whose [ImageBase, ImageSize] covered by [= Buffer, Length]. + + @param Buffer Start Address + @param Length Address length + @param ImageRecordList Image record list + + @return first image record covered by [buffer, length] +**/ +STATIC +IMAGE_PROPERTIES_RECORD * +GetImageRecordByAddress ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length, + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + + for (ImageRecordLink =3D ImageRecordList->ForwardLink; + ImageRecordLink !=3D ImageRecordList; + ImageRecordLink =3D ImageRecordLink->ForwardLink) + { + ImageRecord =3D CR ( + ImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + + if ((Buffer <=3D ImageRecord->ImageBase) && + (Buffer + Length >=3D ImageRecord->ImageBase + ImageRecord->ImageS= ize)) + { + return ImageRecord; + } + } + + return NULL; +} + +/** + Set the memory map to new entries, according to one old entry, + based upon PE code section and data section in image record + + @param ImageRecord An image record whose [ImageBase, ImageSi= ze] covered + by old memory map entry. + @param NewRecord A pointer to several new memory map entri= es. + The caller gurantee the buffer size be 1 + + (SplitRecordCount * DescriptorSize) calcu= lated + below. + @param OldRecord A pointer to one old memory map entry. + @param DescriptorSize Size, in bytes, of an individual EFI_MEMO= RY_DESCRIPTOR. +**/ +STATIC +UINTN +SetNewRecord ( + IN IMAGE_PROPERTIES_RECORD *ImageRecord, + IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, + IN EFI_MEMORY_DESCRIPTOR *OldRecord, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR TempRecord; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + LIST_ENTRY *ImageRecordCodeSectionLink; + LIST_ENTRY *ImageRecordCodeSectionEndLink; + LIST_ENTRY *ImageRecordCodeSectionList; + UINTN NewRecordCount; + UINT64 PhysicalEnd; + UINT64 ImageEnd; + + CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); + PhysicalEnd =3D TempRecord.PhysicalStart + EfiPagesToSize (TempRecord= .NumberOfPages); + NewRecordCount =3D 0; + + ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; + + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLin= k; + ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; + while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { + ImageRecordCodeSection =3D CR ( + ImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE + ); + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLink; + + if (TempRecord.PhysicalStart <=3D ImageRecordCodeSection->CodeSegmentB= ase) { + // + // DATA + // + NewRecord->Type =3D TempRecord.Type; + NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; + NewRecord->VirtualStart =3D 0; + NewRecord->NumberOfPages =3D EfiSizeToPages (ImageRecordCodeSection-= >CodeSegmentBase - NewRecord->PhysicalStart); + NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_XP; + if (NewRecord->NumberOfPages !=3D 0) { + NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); + NewRecordCount++; + } + + // + // CODE + // + NewRecord->Type =3D TempRecord.Type; + NewRecord->PhysicalStart =3D ImageRecordCodeSection->CodeSegmentBase; + NewRecord->VirtualStart =3D 0; + NewRecord->NumberOfPages =3D EfiSizeToPages (ImageRecordCodeSection-= >CodeSegmentSize); + NewRecord->Attribute =3D (TempRecord.Attribute & (~EFI_MEMORY_XP= )) | EFI_MEMORY_RO; + if (NewRecord->NumberOfPages !=3D 0) { + NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); + NewRecordCount++; + } + + TempRecord.PhysicalStart =3D ImageRecordCodeSection->CodeSegmentBase= + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize)= ); + TempRecord.NumberOfPages =3D EfiSizeToPages (PhysicalEnd - TempRecor= d.PhysicalStart); + if (TempRecord.NumberOfPages =3D=3D 0) { + break; + } + } + } + + ImageEnd =3D ImageRecord->ImageBase + ImageRecord->ImageSize; + + // + // Final DATA + // + if (TempRecord.PhysicalStart < ImageEnd) { + NewRecord->Type =3D TempRecord.Type; + NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; + NewRecord->VirtualStart =3D 0; + NewRecord->NumberOfPages =3D EfiSizeToPages (ImageEnd - TempRecord.Phy= sicalStart); + NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_XP; + NewRecordCount++; + } + + return NewRecordCount; +} + +/** + Return the max number of new splitted entries, according to one old entr= y, + based upon PE code section and data section. + + @param OldRecord A pointer to one old memory map entry. + @param ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries= used when searching + for an image record contained by the memo= ry range described in + the existing EFI memory map descriptor Ol= dRecord + + @retval 0 no entry need to be splitted. + @return the max number of new splitted entries +**/ +STATIC +UINTN +GetMaxSplitRecordCount ( + IN EFI_MEMORY_DESCRIPTOR *OldRecord, + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + UINTN SplitRecordCount; + UINT64 PhysicalStart; + UINT64 PhysicalEnd; + + SplitRecordCount =3D 0; + PhysicalStart =3D OldRecord->PhysicalStart; + PhysicalEnd =3D OldRecord->PhysicalStart + EfiPagesToSize (OldRecor= d->NumberOfPages); + + do { + ImageRecord =3D GetImageRecordByAddress (PhysicalStart, PhysicalEnd - = PhysicalStart, ImageRecordList); + if (ImageRecord =3D=3D NULL) { + break; + } + + SplitRecordCount +=3D (2 * ImageRecord->CodeSegmentCount + 1); + PhysicalStart =3D ImageRecord->ImageBase + ImageRecord->ImageSize; + } while ((ImageRecord !=3D NULL) && (PhysicalStart < PhysicalEnd)); + + if (SplitRecordCount !=3D 0) { + SplitRecordCount--; + } + + return SplitRecordCount; +} + +/** + Split the memory map to new entries, according to one old entry, + based upon PE code section and data section. + + @param OldRecord A pointer to one old memory map entr= y. + @param NewRecord A pointer to several new memory map = entries. + The caller gurantee the buffer size = be 1 + + (SplitRecordCount * DescriptorSize) = calculated + below. + @param MaxSplitRecordCount The max number of splitted entries + @param DescriptorSize Size, in bytes, of an individual EFI= _MEMORY_DESCRIPTOR. + @param ImageRecordList A list of IMAGE_PROPERTIES_RECORD en= tries used when searching + for an image record contained by the= memory range described in + the existing EFI memory map descript= or OldRecord + + @retval 0 no entry is splitted. + @return the real number of splitted record. +**/ +STATIC +UINTN +SplitRecord ( + IN EFI_MEMORY_DESCRIPTOR *OldRecord, + IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, + IN UINTN MaxSplitRecordCount, + IN UINTN DescriptorSize, + IN LIST_ENTRY *ImageRecordList + ) +{ + EFI_MEMORY_DESCRIPTOR TempRecord; + IMAGE_PROPERTIES_RECORD *ImageRecord; + IMAGE_PROPERTIES_RECORD *NewImageRecord; + UINT64 PhysicalStart; + UINT64 PhysicalEnd; + UINTN NewRecordCount; + UINTN TotalNewRecordCount; + BOOLEAN IsLastRecordData; + + if (MaxSplitRecordCount =3D=3D 0) { + CopyMem (NewRecord, OldRecord, DescriptorSize); + return 0; + } + + TotalNewRecordCount =3D 0; + + // + // Override previous record + // + CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); + PhysicalStart =3D TempRecord.PhysicalStart; + PhysicalEnd =3D TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.= NumberOfPages); + + ImageRecord =3D NULL; + do { + NewImageRecord =3D GetImageRecordByAddress (PhysicalStart, PhysicalEnd= - PhysicalStart, ImageRecordList); + if (NewImageRecord =3D=3D NULL) { + // + // No more image covered by this range, stop + // + if ((PhysicalEnd > PhysicalStart) && (ImageRecord !=3D NULL)) { + // + // If this is still address in this record, need record. + // + NewRecord =3D PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, Descri= ptorSize); + IsLastRecordData =3D FALSE; + if ((NewRecord->Attribute & EFI_MEMORY_XP) !=3D 0) { + IsLastRecordData =3D TRUE; + } + + if (IsLastRecordData) { + // + // Last record is DATA, just merge it. + // + NewRecord->NumberOfPages =3D EfiSizeToPages (PhysicalEnd - NewRe= cord->PhysicalStart); + } else { + // + // Last record is CODE, create a new DATA entry. + // + NewRecord =3D NEXT_MEMORY_DESCRIPTOR (NewRecord, = DescriptorSize); + NewRecord->Type =3D TempRecord.Type; + NewRecord->PhysicalStart =3D TempRecord.PhysicalStart; + NewRecord->VirtualStart =3D 0; + NewRecord->NumberOfPages =3D TempRecord.NumberOfPages; + NewRecord->Attribute =3D TempRecord.Attribute | EFI_MEMORY_X= P; + TotalNewRecordCount++; + } + } + + break; + } + + ImageRecord =3D NewImageRecord; + + // + // Set new record + // + NewRecordCount =3D SetNewRecord (ImageRecord, NewRecord, &TempRe= cord, DescriptorSize); + TotalNewRecordCount +=3D NewRecordCount; + NewRecord =3D (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord = + NewRecordCount * DescriptorSize); + + // + // Update PhysicalStart, in order to exclude the image buffer already = splitted. + // + PhysicalStart =3D ImageRecord->ImageBase + ImageRecord->Ima= geSize; + TempRecord.PhysicalStart =3D PhysicalStart; + TempRecord.NumberOfPages =3D EfiSizeToPages (PhysicalEnd - PhysicalSta= rt); + } while ((ImageRecord !=3D NULL) && (PhysicalStart < PhysicalEnd)); + + // + // The logic in function SplitTable() ensures that TotalNewRecordCount w= ill not be zero if the + // code reaches here. + // + ASSERT (TotalNewRecordCount !=3D 0); + return TotalNewRecordCount - 1; +} + +/** + Split the original memory map, and add more entries to describe PE code = section and data section. + This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. + This function will merge entries with same attributes finally. + + NOTE: It assumes PE code/data section are page aligned. + NOTE: It assumes enough entry is prepared for new memory map. + + Split table: + +---------------+ + | Record X | + +---------------+ + | Record RtCode | + +---------------+ + | Record Y | + +---------------+ + =3D=3D> + +---------------+ + | Record X | + +---------------+ ---- + | Record RtData | | + +---------------+ | + | Record RtCode | |-> PE/COFF1 + +---------------+ | + | Record RtData | | + +---------------+ ---- + | Record RtData | | + +---------------+ | + | Record RtCode | |-> PE/COFF2 + +---------------+ | + | Record RtData | | + +---------------+ ---- + | Record Y | + +---------------+ + + @param MemoryMapSize A pointer to the size, in bytes,= of the + MemoryMap buffer. On input, this= is the size of + old MemoryMap before split. The = actual buffer + size of MemoryMap is MemoryMapSi= ze + + (AdditionalRecordCount * Descrip= torSize) calculated + below. On output, it is the size= of new MemoryMap + after split. + @param MemoryMap A pointer to the buffer in which= firmware places + the current memory map. + @param DescriptorSize Size, in bytes, of an individual= EFI_MEMORY_DESCRIPTOR. + @param ImageRecordList A list of IMAGE_PROPERTIES_RECOR= D entries used when searching + for an image record contained by= the memory range described in + EFI memory map descriptors. + @param NumberOfAdditionalDescriptors The number of unused descriptors= at the end of the input MemoryMap. +**/ +VOID +EFIAPI +SplitTable ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN DescriptorSize, + IN LIST_ENTRY *ImageRecordList, + IN UINTN NumberOfAdditionalDescriptors + ) +{ + INTN IndexOld; + INTN IndexNew; + UINTN MaxSplitRecordCount; + UINTN RealSplitRecordCount; + UINTN TotalSplitRecordCount; + + TotalSplitRecordCount =3D 0; + // + // Let old record point to end of valid MemoryMap buffer. + // + IndexOld =3D ((*MemoryMapSize) / DescriptorSize) - 1; + // + // Let new record point to end of full MemoryMap buffer. + // + IndexNew =3D ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditiona= lDescriptors; + for ( ; IndexOld >=3D 0; IndexOld--) { + MaxSplitRecordCount =3D GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR= *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList); + // + // Split this MemoryMap record + // + IndexNew -=3D MaxSplitRecordCount; + RealSplitRecordCount =3D SplitRecord ( + (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap = + IndexOld * DescriptorSize), + (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap = + IndexNew * DescriptorSize), + MaxSplitRecordCount, + DescriptorSize, + ImageRecordList + ); + // + // Adjust IndexNew according to real split. + // + CopyMem ( + ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRec= ordCount) * DescriptorSize), + ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), + RealSplitRecordCount * DescriptorSize + ); + IndexNew =3D IndexNew + MaxSplitRecordCount - RealSplitR= ecordCount; + TotalSplitRecordCount +=3D RealSplitRecordCount; + IndexNew--; + } + + // + // Move all records to the beginning. + // + CopyMem ( + MemoryMap, + (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecord= Count) * DescriptorSize, + (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize + ); + + *MemoryMapSize =3D (*MemoryMapSize) + DescriptorSize * TotalSplitRecordC= ount; + + // + // Sort from low to high (Just in case) + // + SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); + + return; +} + +/** + Swap two code sections in image record. + + @param FirstImageRecordCodeSection first code section in image record + @param SecondImageRecordCodeSection second code section in image reco= rd +**/ +VOID +EFIAPI +SwapImageRecordCodeSection ( + IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, + IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection + ) +{ + IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; + + TempImageRecordCodeSection.CodeSegmentBase =3D FirstImageRecordCodeSecti= on->CodeSegmentBase; + TempImageRecordCodeSection.CodeSegmentSize =3D FirstImageRecordCodeSecti= on->CodeSegmentSize; + + FirstImageRecordCodeSection->CodeSegmentBase =3D SecondImageRecordCodeSe= ction->CodeSegmentBase; + FirstImageRecordCodeSection->CodeSegmentSize =3D SecondImageRecordCodeSe= ction->CodeSegmentSize; + + SecondImageRecordCodeSection->CodeSegmentBase =3D TempImageRecordCodeSec= tion.CodeSegmentBase; + SecondImageRecordCodeSection->CodeSegmentSize =3D TempImageRecordCodeSec= tion.CodeSegmentSize; +} + +/** + Sort code section in image record, based upon CodeSegmentBase from low t= o high. + + @param ImageRecord image record to be sorted +**/ +VOID +EFIAPI +SortImageRecordCodeSection ( + IN IMAGE_PROPERTIES_RECORD *ImageRecord + ) +{ + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; + LIST_ENTRY *ImageRecordCodeSectionLink; + LIST_ENTRY *NextImageRecordCodeSectionLink; + LIST_ENTRY *ImageRecordCodeSectionEndLink; + LIST_ENTRY *ImageRecordCodeSectionList; + + ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; + + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLi= nk; + NextImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLi= nk; + ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; + while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { + ImageRecordCodeSection =3D CR ( + ImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE + ); + while (NextImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLi= nk) { + NextImageRecordCodeSection =3D CR ( + NextImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_= SIGNATURE + ); + if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSec= tion->CodeSegmentBase) { + SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecor= dCodeSection); + } + + NextImageRecordCodeSectionLink =3D NextImageRecordCodeSectionLink->F= orwardLink; + } + + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forward= Link; + NextImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->Forward= Link; + } +} + +/** + Check if code section in image record is valid. + + @param ImageRecord image record to be checked + + @retval TRUE image record is valid + @retval FALSE image record is invalid +**/ +BOOLEAN +EFIAPI +IsImageRecordCodeSectionValid ( + IN IMAGE_PROPERTIES_RECORD *ImageRecord + ) +{ + IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; + IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection; + LIST_ENTRY *ImageRecordCodeSectionLink; + LIST_ENTRY *ImageRecordCodeSectionEndLink; + LIST_ENTRY *ImageRecordCodeSectionList; + + DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->C= odeSegmentCount)); + + ImageRecordCodeSectionList =3D &ImageRecord->CodeSegmentList; + + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionList->ForwardLin= k; + ImageRecordCodeSectionEndLink =3D ImageRecordCodeSectionList; + LastImageRecordCodeSection =3D NULL; + while (ImageRecordCodeSectionLink !=3D ImageRecordCodeSectionEndLink) { + ImageRecordCodeSection =3D CR ( + ImageRecordCodeSectionLink, + IMAGE_PROPERTIES_RECORD_CODE_SECTION, + Link, + IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNAT= URE + ); + if (ImageRecordCodeSection->CodeSegmentSize =3D=3D 0) { + return FALSE; + } + + if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) { + return FALSE; + } + + if (ImageRecordCodeSection->CodeSegmentBase >=3D MAX_ADDRESS - ImageRe= cordCodeSection->CodeSegmentSize) { + return FALSE; + } + + if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection-= >CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) { + return FALSE; + } + + if (LastImageRecordCodeSection !=3D NULL) { + if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCo= deSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) { + return FALSE; + } + } + + LastImageRecordCodeSection =3D ImageRecordCodeSection; + ImageRecordCodeSectionLink =3D ImageRecordCodeSectionLink->ForwardLink; + } + + return TRUE; +} + +/** + Swap two image records. + + @param FirstImageRecord first image record. + @param SecondImageRecord second image record. +**/ +VOID +EFIAPI +SwapImageRecord ( + IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, + IN IMAGE_PROPERTIES_RECORD *SecondImageRecord + ) +{ + IMAGE_PROPERTIES_RECORD TempImageRecord; + + TempImageRecord.ImageBase =3D FirstImageRecord->ImageBase; + TempImageRecord.ImageSize =3D FirstImageRecord->ImageSize; + TempImageRecord.CodeSegmentCount =3D FirstImageRecord->CodeSegmentCount; + + FirstImageRecord->ImageBase =3D SecondImageRecord->ImageBase; + FirstImageRecord->ImageSize =3D SecondImageRecord->ImageSize; + FirstImageRecord->CodeSegmentCount =3D SecondImageRecord->CodeSegmentCou= nt; + + SecondImageRecord->ImageBase =3D TempImageRecord.ImageBase; + SecondImageRecord->ImageSize =3D TempImageRecord.ImageSize; + SecondImageRecord->CodeSegmentCount =3D TempImageRecord.CodeSegmentCount; + + SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord-= >CodeSegmentList); +} + +/** + Sort image record based upon the ImageBase from low to high. + + @param ImageRecordList Image record list to be sorted +**/ +VOID +EFIAPI +SortImageRecord ( + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + IMAGE_PROPERTIES_RECORD *NextImageRecord; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *NextImageRecordLink; + LIST_ENTRY *ImageRecordEndLink; + + ImageRecordLink =3D ImageRecordList->ForwardLink; + NextImageRecordLink =3D ImageRecordLink->ForwardLink; + ImageRecordEndLink =3D ImageRecordList; + while (ImageRecordLink !=3D ImageRecordEndLink) { + ImageRecord =3D CR ( + ImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + while (NextImageRecordLink !=3D ImageRecordEndLink) { + NextImageRecord =3D CR ( + NextImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + + ); + if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { + SwapImageRecord (ImageRecord, NextImageRecord); + } + + NextImageRecordLink =3D NextImageRecordLink->ForwardLink; + } + + ImageRecordLink =3D ImageRecordLink->ForwardLink; + NextImageRecordLink =3D ImageRecordLink->ForwardLink; + } +} + +/** + Find image record according to image base and size. + + @param ImageBase Base of PE image + @param ImageSize Size of PE image + @param ImageRecordList Image record list to be searched + + @return image record +**/ +IMAGE_PROPERTIES_RECORD * +EFIAPI +FindImageRecord ( + IN EFI_PHYSICAL_ADDRESS ImageBase, + IN UINT64 ImageSize, + IN LIST_ENTRY *ImageRecordList + ) +{ + IMAGE_PROPERTIES_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + + for (ImageRecordLink =3D ImageRecordList->ForwardLink; + ImageRecordLink !=3D ImageRecordList; + ImageRecordLink =3D ImageRecordLink->ForwardLink) + { + ImageRecord =3D CR ( + ImageRecordLink, + IMAGE_PROPERTIES_RECORD, + Link, + IMAGE_PROPERTIES_RECORD_SIGNATURE + ); + + if ((ImageBase =3D=3D ImageRecord->ImageBase) && + (ImageSize =3D=3D ImageRecord->ImageSize)) + { + return ImageRecord; + } + } + + return NULL; +} diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMai= n.h index 43daa037be44..86a7be2f5188 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -228,26 +228,6 @@ typedef struct { #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA= _SIGNATURE) =20 -#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I',= 'P','R','C') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS CodeSegmentBase; - UINT64 CodeSegmentSize; -} IMAGE_PROPERTIES_RECORD_CODE_SECTION; - -#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS ImageBase; - UINT64 ImageSize; - UINTN CodeSegmentCount; - LIST_ENTRY CodeSegmentList; -} IMAGE_PROPERTIES_RECORD; - // // DXE Core Global Variables // diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeM= ain.inf index 16871f2021e5..090970aec6df 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -94,6 +94,7 @@ [LibraryClasses] DebugAgentLib CpuExceptionHandlerLib PcdLib + ImagePropertiesRecordLib =20 [Guids] gEfiEventMemoryMapChangeGuid ## PRODUCES ##= Event diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeM= odulePkg/Include/Library/ImagePropertiesRecordLib.h index 728008a2e5bb..9139c7b6c05d 100644 --- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h +++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h @@ -11,4 +11,163 @@ #ifndef IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_ #define IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_ =20 +#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I',= 'P','R','C') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_PHYSICAL_ADDRESS CodeSegmentBase; + UINT64 CodeSegmentSize; +} IMAGE_PROPERTIES_RECORD_CODE_SECTION; + +#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_PHYSICAL_ADDRESS ImageBase; + UINT64 ImageSize; + UINTN CodeSegmentCount; + LIST_ENTRY CodeSegmentList; +} IMAGE_PROPERTIES_RECORD; + +/** + Split the original memory map, and add more entries to describe PE code = section and data section. + This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. + This function will merge entries with same attributes finally. + + NOTE: It assumes PE code/data section are page aligned. + NOTE: It assumes enough entry is prepared for new memory map. + + Split table: + +---------------+ + | Record X | + +---------------+ + | Record RtCode | + +---------------+ + | Record Y | + +---------------+ + =3D=3D> + +---------------+ + | Record X | + +---------------+ ---- + | Record RtData | | + +---------------+ | + | Record RtCode | |-> PE/COFF1 + +---------------+ | + | Record RtData | | + +---------------+ ---- + | Record RtData | | + +---------------+ | + | Record RtCode | |-> PE/COFF2 + +---------------+ | + | Record RtData | | + +---------------+ ---- + | Record Y | + +---------------+ + + @param MemoryMapSize A pointer to the size, in bytes,= of the + MemoryMap buffer. On input, this= is the size of + old MemoryMap before split. The = actual buffer + size of MemoryMap is MemoryMapSi= ze + + (AdditionalRecordCount * Descrip= torSize) calculated + below. On output, it is the size= of new MemoryMap + after split. + @param MemoryMap A pointer to the buffer in which= firmware places + the current memory map. + @param DescriptorSize Size, in bytes, of an individual= EFI_MEMORY_DESCRIPTOR. + @param ImageRecordList A list of IMAGE_PROPERTIES_RECOR= D entries used when searching + for an image record contained by= the memory range described in + EFI memory map descriptors. + @param NumberOfAdditionalDescriptors The number of unused descriptors= at the end of the input MemoryMap. +**/ +VOID +EFIAPI +SplitTable ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN DescriptorSize, + IN LIST_ENTRY *ImageRecordList, + IN UINTN NumberOfAdditionalDescriptors + ); + +/** + Sort code section in image record, based upon CodeSegmentBase from low t= o high. + + @param ImageRecord image record to be sorted +**/ +VOID +EFIAPI +SortImageRecordCodeSection ( + IN IMAGE_PROPERTIES_RECORD *ImageRecord + ); + +/** + Check if code section in image record is valid. + + @param ImageRecord image record to be checked + + @retval TRUE image record is valid + @retval FALSE image record is invalid +**/ +BOOLEAN +EFIAPI +IsImageRecordCodeSectionValid ( + IN IMAGE_PROPERTIES_RECORD *ImageRecord + ); + +/** + Sort image record based upon the ImageBase from low to high. + + @param ImageRecordList Image record list to be sorted +**/ +VOID +EFIAPI +SortImageRecord ( + IN LIST_ENTRY *ImageRecordList + ); + +/** + Swap two image records. + + @param[in] FirstImageRecord The first image record. + @param[in] SecondImageRecord The second image record. +**/ +VOID +EFIAPI +SwapImageRecord ( + IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, + IN IMAGE_PROPERTIES_RECORD *SecondImageRecord + ); + +/** + Swap two code sections in a single IMAGE_PROPERTIES_RECORD. + + @param[in] FirstImageRecordCodeSection The first code section + @param[in] SecondImageRecordCodeSection The second code section +**/ +VOID +EFIAPI +SwapImageRecordCodeSection ( + IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, + IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection + ); + +/** + Find image record according to image base and size. + + @param ImageBase Base of PE image + @param ImageSize Size of PE image + @param ImageRecordList Image record list to be searched + + @return image record +**/ +IMAGE_PROPERTIES_RECORD * +EFIAPI +FindImageRecord ( + IN EFI_PHYSICAL_ADDRESS ImageBase, + IN UINT64 ImageSize, + IN LIST_ENTRY *ImageRecordList + ); + #endif diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesR= ecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertie= sRecordLib.inf index b7e493056889..4c1466fc3336 100644 --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi= b.inf +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLi= b.inf @@ -19,6 +19,10 @@ [Defines] [Sources.common] ImagePropertiesRecordLib.c =20 +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib =20 [Packages] MdePkg/MdePkg.dec --=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 (#110655): https://edk2.groups.io/g/devel/message/110655 Mute This Topic: https://groups.io/mt/102368847/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-