* [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs
@ 2023-07-25 1:34 Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 01/14] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:34 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Ard Biesheuvel, Dandan Bi, Eric Dong, Gerd Hoffmann,
Guo Dong, Gua Guo, James Lu, Jian J Wang, Jiewen Yao,
Jordan Justen, Leif Lindholm, Liming Gao, Rahul Kumar, Ray Ni,
Sami Mujawar, Sean Rhodes
v3:
- Refactor patch series so the transition of logic from the DXE
MAT logic to the new library is more clear.
- Update function headers to improve clarity and follow EDK2
standards.
- Add Create and Delete functions for Image Properties Records
and redirect some of the SMM and DXE MAT code to use these
functions.
- Update/Add DumpImageRecords() to print the image name and code
sections of each runtime image which will be put in the MAT.
The DXE and SMM MAT logic will now invoke the DumpImageRecords()
on DEBUG builds at the EndOfDxe event to install the MAT.
v2:
- A one-line change in patch 3 was moved to patch 9 for correctness.
Reference: https://github.com/tianocore/edk2/pull/4590
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4492
The UEFI and SMM MAT logic contains duplicate logic for manipulating image
properties records which is used to track runtime images.
This patch series adds a new library, ImagePropertiesRecordLib,
which consolidates this logic and fixes the bugs which currently exist in
the MAT logic.
The first patch adds the ImagePropertiesRecordLib implementation which
is a copy of the UEFI MAT logic with minor modifications to remove the
reliance on globabl variables and make the code unit testable.
The second patch adds a unit test for the ImagePropertiesRecordLib. The
logic tests various potential layouts of the EFI memory map and runtime
images. 3/4 of these tests will fail which demonstrates the MAT logic
bugs.
The third patch fixes the logic in the ImagePropertiesRecordLib so
that all of the unit tests pass and the MAT logic can be fixed by
using the library.
The remaining patches add library instances to DSC files and remove
the image properties record logic from the SMM and UEFI MAT logic.
Cc: Andrew Fish <afish@apple.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Cc: James Lu <james.lu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Taylor Beebe (14):
MdeModulePkg: Add ImagePropertiesRecordLib
ArmVirtPkg: Add ImagePropertiesRecordLib Instance
EmulatorPkg: Add ImagePropertiesRecordLib Instance
OvmfPkg: Add ImagePropertiesRecordLib Instance
UefiPayloadPkg: Add ImagePropertiesRecordLib Instance
MdeModulePkg: Update MemoryAttributesTable.c to Reduce Global Variable
Use
MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib
MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test
MdeModulePkg: Fix Bugs in MAT Logic
UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero
MdeModulePkg: Transition SMM MAT Logic to Use ImagePropertiesRecordLib
MdeModulePkg: Add Logic to Create/Delete Image Properties Records
MdeModulePkg: Update Function Headers in ImagePropertiesRecordLib
MdeModulePkg: Update DumpImageRecord() in ImagePropertiesRecordLib
MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 967 +----------------
MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 24 +-
MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 958 +----------------
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 1083 ++++++++++++++++++++
MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c | 938 +++++++++++++++++
UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 19 +-
ArmVirtPkg/ArmVirt.dsc.inc | 1 +
EmulatorPkg/EmulatorPkg.dsc | 1 +
MdeModulePkg/Core/Dxe/DxeMain.h | 20 -
MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 1 +
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 191 ++++
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf | 31 +
MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf | 35 +
MdeModulePkg/MdeModulePkg.dec | 5 +
MdeModulePkg/MdeModulePkg.dsc | 2 +
MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 6 +
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/Bhyve/BhyveX64.dsc | 1 +
OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 +
OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfXen.dsc | 1 +
OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 1 +
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
28 files changed, 2420 insertions(+), 1874 deletions(-)
create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
create mode 100644 MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
create mode 100644 MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107197): https://edk2.groups.io/g/devel/message/107197
Mute This Topic: https://groups.io/mt/100342594/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 01/14] MdeModulePkg: Add ImagePropertiesRecordLib
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 02/14] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Create a library for manipulating image properties records. The
library is currently blank and will be filled in a future patch
to help with reviewer readability.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 9 +++++++
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 14 +++++++++++
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf | 25 ++++++++++++++++++++
MdeModulePkg/MdeModulePkg.dec | 5 ++++
MdeModulePkg/MdeModulePkg.dsc | 2 ++
5 files changed, 55 insertions(+)
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
new file mode 100644
index 000000000000..df7c54ebb793
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -0,0 +1,9 @@
+/** @file
+
+ Provides definitions and functionality for manipulating IMAGE_PROPERTIES_RECORD.
+
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
new file mode 100644
index 000000000000..728008a2e5bb
--- /dev/null
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -0,0 +1,14 @@
+/** @file
+
+ Provides definitions and functionality for manipulating IMAGE_PROPERTIES_RECORD.
+
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
+#define IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
+
+#endif
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
new file mode 100644
index 000000000000..b7e493056889
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
@@ -0,0 +1,25 @@
+## @file
+# Provides definitions and functionality for manipulating
+# IMAGE_PROPERTIES_RECORD.
+#
+# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ImagePropertiesRecordLib
+ FILE_GUID = 5CCA36C1-C430-4A90-8BF7-23D2719D5928
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ImagePropertiesRecordLib
+
+[Sources.common]
+ ImagePropertiesRecordLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 0ff058b0a9da..80df553b2a5f 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -164,6 +164,11 @@ [LibraryClasses]
#
VariableFlashInfoLib|Include/Library/VariableFlashInfoLib.h
+ ## @libraryclass Memory Attribute Table support logic for tracking and reporting
+ # runtime images
+ #
+ ImagePropertiesRecordLib|Include/Library/ImagePropertiesRecordLib.h
+
[Guids]
## MdeModule package token space guid
# Include/Guid/MdeModulePkgTokenSpace.h
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index db3b5af53795..6444111b9214 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -96,6 +96,7 @@ [LibraryClasses]
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
@@ -237,6 +238,7 @@ [Components]
MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf
MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+ MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107198): https://edk2.groups.io/g/devel/message/107198
Mute This Topic: https://groups.io/mt/100342597/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 02/14] ArmVirtPkg: Add ImagePropertiesRecordLib Instance
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 01/14] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 03/14] EmulatorPkg: " Taylor Beebe
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Ard Biesheuvel, Leif Lindholm, Sami Mujawar, Gerd Hoffmann
Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
ArmVirtPkg/ArmVirt.dsc.inc | 1 +
1 file changed, 1 insertion(+)
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 2443e8351c99..b299028b9f51 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -52,6 +52,7 @@ [LibraryClasses.common]
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
HobLib|ArmVirtPkg/Library/ArmVirtDxeHobLib/ArmVirtDxeHobLib.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107199): https://edk2.groups.io/g/devel/message/107199
Mute This Topic: https://groups.io/mt/100342598/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 03/14] EmulatorPkg: Add ImagePropertiesRecordLib Instance
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 01/14] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 02/14] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 04/14] OvmfPkg: " Taylor Beebe
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Andrew Fish, Ray Ni
Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
---
EmulatorPkg/EmulatorPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index b44435d7e6ee..e18eeca884a5 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -126,6 +126,7 @@ [LibraryClasses]
SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107200): https://edk2.groups.io/g/devel/message/107200
Mute This Topic: https://groups.io/mt/100342599/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 04/14] OvmfPkg: Add ImagePropertiesRecordLib Instance
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (2 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 03/14] EmulatorPkg: " Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 05/14] UefiPayloadPkg: " Taylor Beebe
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann
Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/Bhyve/BhyveX64.dsc | 1 +
OvmfPkg/CloudHv/CloudHvX64.dsc | 1 +
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 +
OvmfPkg/Microvm/MicrovmX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfXen.dsc | 1 +
OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc | 1 +
10 files changed, 10 insertions(+)
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 2c6ed7c9745f..e8c954a97956 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -171,6 +171,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SOURCE_DEBUG_ENABLE) == TRUE
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 7fa40998ae80..606e84ae1710 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -173,6 +173,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index e000deed9e4d..91816a10996f 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -182,6 +182,7 @@ [LibraryClasses]
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SMM_REQUIRE) == FALSE
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
!endif
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 193657ff2d61..bee98e798717 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -171,6 +171,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2f7585639374..38e0af6ae101 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -185,6 +185,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SOURCE_DEBUG_ENABLE) == TRUE
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ed36935770f3..84807b3ffee9 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -187,6 +187,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SMM_REQUIRE) == FALSE
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
!endif
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 919315e4cb33..dc80edca1671 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -192,6 +192,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SMM_REQUIRE) == FALSE
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
!endif
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 823de0d0f9e0..82a97ca6d3df 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -204,6 +204,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SMM_REQUIRE) == FALSE
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 210578c1d74d..17b622f34bf2 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -176,6 +176,7 @@ [LibraryClasses]
MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SOURCE_DEBUG_ENABLE) == TRUE
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
index 34b2037824f1..f8b9479345d7 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -101,6 +101,7 @@ [LibraryClasses.common]
PciHostBridgeUtilityLib|OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107201): https://edk2.groups.io/g/devel/message/107201
Mute This Topic: https://groups.io/mt/100342600/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 05/14] UefiPayloadPkg: Add ImagePropertiesRecordLib Instance
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (3 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 04/14] OvmfPkg: " Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 06/14] MdeModulePkg: Update MemoryAttributesTable.c to Reduce Global Variable Use Taylor Beebe
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Sean Rhodes, James Lu, Gua Guo
Add an instance of ImagePropertiesRecordLib which will be used by the
DXE Core.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 47812048ddcf..8d237b23339a 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -277,6 +277,7 @@ [LibraryClasses]
#
DebugPrintErrorLevelLib|UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
!if $(SOURCE_DEBUG_ENABLE) == TRUE
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107202): https://edk2.groups.io/g/devel/message/107202
Mute This Topic: https://groups.io/mt/100342601/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 06/14] MdeModulePkg: Update MemoryAttributesTable.c to Reduce Global Variable Use
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (4 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 05/14] UefiPayloadPkg: " Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 07/14] MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib Taylor Beebe
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
This patch updates MemoryAttributesTable.c to reduce reliance on global
variables and allow some logic to move to a library.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 102 +++++++++++---------
1 file changed, 54 insertions(+), 48 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index fd127ee167e1..64b0aa1ff5e5 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -541,8 +541,9 @@ EnforceMemoryMapAttribute (
/**
Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
- @param Buffer Start Address
- @param Length Address length
+ @param Buffer Start Address
+ @param Length Address length
+ @param ImageRecordList Image record list
@return first image record covered by [buffer, length]
**/
@@ -550,14 +551,12 @@ STATIC
IMAGE_PROPERTIES_RECORD *
GetImageRecordByAddress (
IN EFI_PHYSICAL_ADDRESS Buffer,
- IN UINT64 Length
+ IN UINT64 Length,
+ IN LIST_ENTRY *ImageRecordList
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
- LIST_ENTRY *ImageRecordList;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
for (ImageRecordLink = ImageRecordList->ForwardLink;
ImageRecordLink != ImageRecordList;
@@ -692,7 +691,8 @@ SetNewRecord (
STATIC
UINTN
GetMaxSplitRecordCount (
- IN EFI_MEMORY_DESCRIPTOR *OldRecord
+ IN EFI_MEMORY_DESCRIPTOR *OldRecord,
+ IN LIST_ENTRY *ImageRecordList
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
@@ -705,7 +705,7 @@ GetMaxSplitRecordCount (
PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
do {
- ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
+ ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
if (ImageRecord == NULL) {
break;
}
@@ -725,13 +725,16 @@ GetMaxSplitRecordCount (
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 entry.
- @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 OldRecord A pointer to one old memory map entry.
+ @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 entries used when searching
+ for an image record contained by the memory range described in
+ the existing EFI memory map descriptor OldRecord
@retval 0 no entry is splitted.
@return the real number of splitted record.
@@ -742,7 +745,8 @@ SplitRecord (
IN EFI_MEMORY_DESCRIPTOR *OldRecord,
IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord,
IN UINTN MaxSplitRecordCount,
- IN UINTN DescriptorSize
+ IN UINTN DescriptorSize,
+ IN LIST_ENTRY *ImageRecordList
)
{
EFI_MEMORY_DESCRIPTOR TempRecord;
@@ -770,7 +774,7 @@ SplitRecord (
ImageRecord = NULL;
do {
- NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
+ NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
if (NewImageRecord == NULL) {
//
// No more image covered by this range, stop
@@ -867,23 +871,29 @@ SplitRecord (
| 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 MemoryMapSize +
- (AdditionalRecordCount * DescriptorSize) 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 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 MemoryMapSize +
+ (AdditionalRecordCount * DescriptorSize) 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_RECORD 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 UINTN DescriptorSize,
+ IN LIST_ENTRY *ImageRecordList,
+ IN UINTN NumberOfAdditionalDescriptors
)
{
INTN IndexOld;
@@ -891,9 +901,6 @@ SplitTable (
UINTN MaxSplitRecordCount;
UINTN RealSplitRecordCount;
UINTN TotalSplitRecordCount;
- UINTN AdditionalRecordCount;
-
- AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
TotalSplitRecordCount = 0;
//
@@ -903,9 +910,9 @@ SplitTable (
//
// Let new record point to end of full MemoryMap buffer.
//
- IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;
+ IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
for ( ; IndexOld >= 0; IndexOld--) {
- MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));
+ MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
//
// Split this MemoryMap record
//
@@ -914,7 +921,8 @@ SplitTable (
(EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),
(EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
MaxSplitRecordCount,
- DescriptorSize
+ DescriptorSize,
+ ImageRecordList
);
//
// Adjust IndexNew according to real split.
@@ -934,7 +942,7 @@ SplitTable (
//
CopyMem (
MemoryMap,
- (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,
+ (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
(*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
);
@@ -1035,7 +1043,7 @@ CoreGetMemoryMapWithSeparatedImageSection (
//
// Split PE code/data
//
- SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);
+ SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
}
}
@@ -1233,11 +1241,13 @@ SwapImageRecord (
/**
Sort image record based upon the ImageBase from low to high.
+
+ @param ImageRecordList Image record list to be sorted
**/
STATIC
VOID
SortImageRecord (
- VOID
+ IN LIST_ENTRY *ImageRecordList
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
@@ -1245,9 +1255,6 @@ SortImageRecord (
LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *NextImageRecordLink;
LIST_ENTRY *ImageRecordEndLink;
- LIST_ENTRY *ImageRecordList;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
ImageRecordLink = ImageRecordList->ForwardLink;
NextImageRecordLink = ImageRecordLink->ForwardLink;
@@ -1456,7 +1463,7 @@ InsertImageRecord (
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
}
- SortImageRecord ();
+ SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
return;
@@ -1465,8 +1472,9 @@ Finish:
/**
Find image record according to image base and size.
- @param ImageBase Base of PE image
- @param ImageSize Size of PE image
+ @param ImageBase Base of PE image
+ @param ImageSize Size of PE image
+ @param ImageRecordList Image record list to be searched
@return image record
**/
@@ -1474,14 +1482,12 @@ STATIC
IMAGE_PROPERTIES_RECORD *
FindImageRecord (
IN EFI_PHYSICAL_ADDRESS ImageBase,
- IN UINT64 ImageSize
+ IN UINT64 ImageSize,
+ IN LIST_ENTRY *ImageRecordList
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
- LIST_ENTRY *ImageRecordList;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
for (ImageRecordLink = ImageRecordList->ForwardLink;
ImageRecordLink != ImageRecordList;
@@ -1526,7 +1532,7 @@ RemoveImageRecord (
return;
}
- ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize);
+ ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize, &mImagePropertiesPrivateData.ImageRecordList);
if (ImageRecord == NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
return;
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107203): https://edk2.groups.io/g/devel/message/107203
Mute This Topic: https://groups.io/mt/100342602/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 07/14] MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (5 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 06/14] MdeModulePkg: Update MemoryAttributesTable.c to Reduce Global Variable Use Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 08/14] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Move some DXE MAT logic to ImagePropertiesRecordLib to consolidate
code and enable unit testability.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
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 | 133 ++++
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf | 4 +
7 files changed, 921 insertions(+), 805 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/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 <Library/DxeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
#include <Guid/EventGroup.h>
@@ -333,45 +334,6 @@ CoreInitializeMemoryAttributesTable (
// Below functions are for MemoryMap
//
-/**
- 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 specified
- 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 specified
- by Size.
-
-**/
-STATIC
-UINT64
-EfiSizeToPages (
- IN UINT64 Size
- )
-{
- return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
-}
-
/**
Acquire memory lock on mMemoryAttributesTableLock.
**/
@@ -396,48 +358,6 @@ CoreReleasemMemoryAttributesTableLock (
CoreReleaseLock (&mMemoryAttributesTableLock);
}
-/**
- 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_MEMORY_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 = MemoryMap;
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
- while (MemoryMapEntry < MemoryMapEnd) {
- while (NextMemoryMapEntry < MemoryMapEnd) {
- if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
- CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
- }
-
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
- }
-
- MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- }
-
- return;
-}
-
/**
Merge continous memory map entries whose have same attributes.
@@ -471,7 +391,7 @@ MergeMemoryMap (
do {
MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart);
- MemoryBlockLength = (UINT64)(EfiPagesToSize (NewMemoryMapEntry->NumberOfPages));
+ MemoryBlockLength = LShiftU64 (NewMemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
(NewMemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
(NewMemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
@@ -538,434 +458,6 @@ EnforceMemoryMapAttribute (
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 = ImageRecordList->ForwardLink;
- ImageRecordLink != ImageRecordList;
- ImageRecordLink = ImageRecordLink->ForwardLink)
- {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
-
- if ((Buffer <= ImageRecord->ImageBase) &&
- (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
- {
- 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, ImageSize] covered
- by old memory map entry.
- @param NewRecord A pointer to several new memory map entries.
- The caller gurantee the buffer size be 1 +
- (SplitRecordCount * DescriptorSize) calculated
- below.
- @param OldRecord A pointer to one old memory map entry.
- @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_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 = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
- NewRecordCount = 0;
-
- ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-
- if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
- //
- // DATA
- //
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- if (NewRecord->NumberOfPages != 0) {
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecordCount++;
- }
-
- //
- // CODE
- //
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
- NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
- if (NewRecord->NumberOfPages != 0) {
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecordCount++;
- }
-
- TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
- TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
- if (TempRecord.NumberOfPages == 0) {
- break;
- }
- }
- }
-
- ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
-
- //
- // Final DATA
- //
- if (TempRecord.PhysicalStart < ImageEnd) {
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- NewRecordCount++;
- }
-
- return NewRecordCount;
-}
-
-/**
- Return the max number of new splitted entries, according to one old entry,
- 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 = 0;
- PhysicalStart = OldRecord->PhysicalStart;
- PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
-
- do {
- ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
- if (ImageRecord == NULL) {
- break;
- }
-
- SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
- PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
- } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
- if (SplitRecordCount != 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 entry.
- @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 entries used when searching
- for an image record contained by the memory range described in
- the existing EFI memory map descriptor 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 == 0) {
- CopyMem (NewRecord, OldRecord, DescriptorSize);
- return 0;
- }
-
- TotalNewRecordCount = 0;
-
- //
- // Override previous record
- //
- CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
- PhysicalStart = TempRecord.PhysicalStart;
- PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-
- ImageRecord = NULL;
- do {
- NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
- if (NewImageRecord == NULL) {
- //
- // No more image covered by this range, stop
- //
- if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
- //
- // If this is still address in this record, need record.
- //
- NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- IsLastRecordData = FALSE;
- if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
- IsLastRecordData = TRUE;
- }
-
- if (IsLastRecordData) {
- //
- // Last record is DATA, just merge it.
- //
- NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
- } else {
- //
- // Last record is CODE, create a new DATA entry.
- //
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = TempRecord.NumberOfPages;
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- TotalNewRecordCount++;
- }
- }
-
- break;
- }
-
- ImageRecord = NewImageRecord;
-
- //
- // Set new record
- //
- NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
- TotalNewRecordCount += NewRecordCount;
- NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
-
- //
- // Update PhysicalStart, in order to exclude the image buffer already splitted.
- //
- PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
- TempRecord.PhysicalStart = PhysicalStart;
- TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
- } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
- //
- // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the
- // code reaches here.
- //
- ASSERT (TotalNewRecordCount != 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 |
- +---------------+
- ==>
- +---------------+
- | 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 MemoryMapSize +
- (AdditionalRecordCount * DescriptorSize) 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_RECORD 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 = 0;
- //
- // Let old record point to end of valid MemoryMap buffer.
- //
- IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
- //
- // Let new record point to end of full MemoryMap buffer.
- //
- IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
- for ( ; IndexOld >= 0; IndexOld--) {
- MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
- //
- // Split this MemoryMap record
- //
- IndexNew -= MaxSplitRecordCount;
- RealSplitRecordCount = 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 - RealSplitRecordCount) * DescriptorSize),
- ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
- RealSplitRecordCount * DescriptorSize
- );
- IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
- TotalSplitRecordCount += RealSplitRecordCount;
- IndexNew--;
- }
-
- //
- // Move all records to the beginning.
- //
- CopyMem (
- MemoryMap,
- (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
- (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
- );
-
- *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
-
- //
- // 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.
@@ -1044,6 +536,16 @@ CoreGetMemoryMapWithSeparatedImageSection (
// Split PE code/data
//
SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
+
+ //
+ // Set RuntimeData to XP
+ //
+ EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize);
+
+ //
+ // Merge same type to save entry size
+ //
+ MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize);
}
}
@@ -1074,217 +576,6 @@ SetMemoryAttributesTableSectionAlignment (
}
}
-/**
- Swap two code sections in image record.
-
- @param FirstImageRecordCodeSection first code section in image record
- @param SecondImageRecordCodeSection second code section in image record
-**/
-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 = FirstImageRecordCodeSection->CodeSegmentBase;
- TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
-
- FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
- FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
-
- SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
- SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
-}
-
-/**
- Sort code section in image record, based upon CodeSegmentBase from low to 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 = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- NextImageRecordCodeSection = CR (
- NextImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
- SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
- }
-
- NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
- }
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- }
-}
-
-/**
- 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->CodeSegmentCount));
-
- ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- LastImageRecordCodeSection = NULL;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- if (ImageRecordCodeSection->CodeSegmentSize == 0) {
- return FALSE;
- }
-
- if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
- return FALSE;
- }
-
- if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
- return FALSE;
- }
-
- if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
- return FALSE;
- }
-
- if (LastImageRecordCodeSection != NULL) {
- if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
- return FALSE;
- }
- }
-
- LastImageRecordCodeSection = ImageRecordCodeSection;
- ImageRecordCodeSectionLink = 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 = FirstImageRecord->ImageBase;
- TempImageRecord.ImageSize = FirstImageRecord->ImageSize;
- TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
-
- FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;
- FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;
- FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
-
- SecondImageRecord->ImageBase = TempImageRecord.ImageBase;
- SecondImageRecord->ImageSize = TempImageRecord.ImageSize;
- SecondImageRecord->CodeSegmentCount = 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 = ImageRecordList->ForwardLink;
- NextImageRecordLink = ImageRecordLink->ForwardLink;
- ImageRecordEndLink = ImageRecordList;
- while (ImageRecordLink != ImageRecordEndLink) {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- while (NextImageRecordLink != ImageRecordEndLink) {
- NextImageRecord = CR (
- NextImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
- SwapImageRecord (ImageRecord, NextImageRecord);
- }
-
- NextImageRecordLink = NextImageRecordLink->ForwardLink;
- }
-
- ImageRecordLink = ImageRecordLink->ForwardLink;
- NextImageRecordLink = ImageRecordLink->ForwardLink;
- }
-}
-
/**
Insert image record.
@@ -1469,47 +760,6 @@ Finish:
return;
}
-/**
- 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 = ImageRecordList->ForwardLink;
- ImageRecordLink != ImageRecordList;
- ImageRecordLink = ImageRecordLink->ForwardLink)
- {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
-
- if ((ImageBase == ImageRecord->ImageBase) &&
- (ImageSize == ImageRecord->ImageSize))
- {
- return ImageRecord;
- }
- }
-
- return NULL;
-}
-
/**
Remove Image record.
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/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 <Library/DxeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
#include <Guid/EventGroup.h>
#include <Guid/MemoryAttributesTable.h>
@@ -66,29 +67,6 @@ extern LIST_ENTRY mGcdMemorySpaceMap;
STATIC LIST_ENTRY mProtectedImageRecordList;
-/**
- Sort code section in image record, based upon CodeSegmentBase from low to 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.
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index df7c54ebb793..d942c7fef19a 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -7,3 +7,773 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
+
+#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 specified
+ 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 specified
+ by Size.
+
+**/
+STATIC
+UINT64
+EfiSizeToPages (
+ IN UINT64 Size
+ )
+{
+ return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 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_MEMORY_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 = MemoryMap;
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
+ while (MemoryMapEntry < MemoryMapEnd) {
+ while (NextMemoryMapEntry < MemoryMapEnd) {
+ if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
+ CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
+ }
+
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ }
+
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ }
+
+ 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 = ImageRecordList->ForwardLink;
+ ImageRecordLink != ImageRecordList;
+ ImageRecordLink = ImageRecordLink->ForwardLink)
+ {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ if ((Buffer <= ImageRecord->ImageBase) &&
+ (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
+ {
+ 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, ImageSize] covered
+ by old memory map entry.
+ @param NewRecord A pointer to several new memory map entries.
+ The caller gurantee the buffer size be 1 +
+ (SplitRecordCount * DescriptorSize) calculated
+ below.
+ @param OldRecord A pointer to one old memory map entry.
+ @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_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 = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
+ NewRecordCount = 0;
+
+ ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
+
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
+ ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
+ while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+ ImageRecordCodeSection = CR (
+ ImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+
+ if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
+ //
+ // DATA
+ //
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
+ NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
+ if (NewRecord->NumberOfPages != 0) {
+ NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+ NewRecordCount++;
+ }
+
+ //
+ // CODE
+ //
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
+ NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
+ if (NewRecord->NumberOfPages != 0) {
+ NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+ NewRecordCount++;
+ }
+
+ TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
+ TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
+ if (TempRecord.NumberOfPages == 0) {
+ break;
+ }
+ }
+ }
+
+ ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
+
+ //
+ // Final DATA
+ //
+ if (TempRecord.PhysicalStart < ImageEnd) {
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
+ NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
+ NewRecordCount++;
+ }
+
+ return NewRecordCount;
+}
+
+/**
+ Return the max number of new splitted entries, according to one old entry,
+ 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 memory range described in
+ the existing EFI memory map descriptor OldRecord
+
+ @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 = 0;
+ PhysicalStart = OldRecord->PhysicalStart;
+ PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
+
+ do {
+ ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
+ if (ImageRecord == NULL) {
+ break;
+ }
+
+ SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
+ PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
+ } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
+
+ if (SplitRecordCount != 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 entry.
+ @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 entries used when searching
+ for an image record contained by the memory range described in
+ the existing EFI memory map descriptor 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 == 0) {
+ CopyMem (NewRecord, OldRecord, DescriptorSize);
+ return 0;
+ }
+
+ TotalNewRecordCount = 0;
+
+ //
+ // Override previous record
+ //
+ CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
+ PhysicalStart = TempRecord.PhysicalStart;
+ PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
+
+ ImageRecord = NULL;
+ do {
+ NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
+ if (NewImageRecord == NULL) {
+ //
+ // No more image covered by this range, stop
+ //
+ if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
+ //
+ // If this is still address in this record, need record.
+ //
+ NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+ IsLastRecordData = FALSE;
+ if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
+ IsLastRecordData = TRUE;
+ }
+
+ if (IsLastRecordData) {
+ //
+ // Last record is DATA, just merge it.
+ //
+ NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
+ } else {
+ //
+ // Last record is CODE, create a new DATA entry.
+ //
+ NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = TempRecord.NumberOfPages;
+ NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
+ TotalNewRecordCount++;
+ }
+ }
+
+ break;
+ }
+
+ ImageRecord = NewImageRecord;
+
+ //
+ // Set new record
+ //
+ NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
+ TotalNewRecordCount += NewRecordCount;
+ NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
+
+ //
+ // Update PhysicalStart, in order to exclude the image buffer already splitted.
+ //
+ PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
+ TempRecord.PhysicalStart = PhysicalStart;
+ TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+ } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
+
+ //
+ // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the
+ // code reaches here.
+ //
+ ASSERT (TotalNewRecordCount != 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 |
+ +---------------+
+ ==>
+ +---------------+
+ | 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 MemoryMapSize +
+ (AdditionalRecordCount * DescriptorSize) 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_RECORD 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 = 0;
+ //
+ // Let old record point to end of valid MemoryMap buffer.
+ //
+ IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
+ //
+ // Let new record point to end of full MemoryMap buffer.
+ //
+ IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+ for ( ; IndexOld >= 0; IndexOld--) {
+ MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
+ //
+ // Split this MemoryMap record
+ //
+ IndexNew -= MaxSplitRecordCount;
+ RealSplitRecordCount = 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 - RealSplitRecordCount) * DescriptorSize),
+ ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
+ RealSplitRecordCount * DescriptorSize
+ );
+ IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
+ TotalSplitRecordCount += RealSplitRecordCount;
+ IndexNew--;
+ }
+
+ //
+ // Move all records to the beginning.
+ //
+ CopyMem (
+ MemoryMap,
+ (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
+ (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
+ );
+
+ *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
+
+ //
+ // 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 record
+**/
+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 = FirstImageRecordCodeSection->CodeSegmentBase;
+ TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
+
+ FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
+ FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
+
+ SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
+ SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
+}
+
+/**
+ Sort code section in image record, based upon CodeSegmentBase from low to 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 = &ImageRecord->CodeSegmentList;
+
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
+ NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+ ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
+ while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+ ImageRecordCodeSection = CR (
+ ImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+ NextImageRecordCodeSection = CR (
+ NextImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
+ SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
+ }
+
+ NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
+ }
+
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+ NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
+ }
+}
+
+/**
+ 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->CodeSegmentCount));
+
+ ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
+
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
+ ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
+ LastImageRecordCodeSection = NULL;
+ while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
+ ImageRecordCodeSection = CR (
+ ImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ if (ImageRecordCodeSection->CodeSegmentSize == 0) {
+ return FALSE;
+ }
+
+ if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
+ return FALSE;
+ }
+
+ if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
+ return FALSE;
+ }
+
+ if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+ return FALSE;
+ }
+
+ if (LastImageRecordCodeSection != NULL) {
+ if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
+ return FALSE;
+ }
+ }
+
+ LastImageRecordCodeSection = ImageRecordCodeSection;
+ ImageRecordCodeSectionLink = 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 = FirstImageRecord->ImageBase;
+ TempImageRecord.ImageSize = FirstImageRecord->ImageSize;
+ TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
+
+ FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;
+ FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;
+ FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
+
+ SecondImageRecord->ImageBase = TempImageRecord.ImageBase;
+ SecondImageRecord->ImageSize = TempImageRecord.ImageSize;
+ SecondImageRecord->CodeSegmentCount = 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 = ImageRecordList->ForwardLink;
+ NextImageRecordLink = ImageRecordLink->ForwardLink;
+ ImageRecordEndLink = ImageRecordList;
+ while (ImageRecordLink != ImageRecordEndLink) {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+ while (NextImageRecordLink != ImageRecordEndLink) {
+ NextImageRecord = CR (
+ NextImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+
+ );
+ if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
+ SwapImageRecord (ImageRecord, NextImageRecord);
+ }
+
+ NextImageRecordLink = NextImageRecordLink->ForwardLink;
+ }
+
+ ImageRecordLink = ImageRecordLink->ForwardLink;
+ NextImageRecordLink = 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 = ImageRecordList->ForwardLink;
+ ImageRecordLink != ImageRecordList;
+ ImageRecordLink = ImageRecordLink->ForwardLink)
+ {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ if ((ImageBase == ImageRecord->ImageBase) &&
+ (ImageSize == ImageRecord->ImageSize))
+ {
+ return ImageRecord;
+ }
+ }
+
+ return NULL;
+}
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.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)
-#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/DxeMain.inf
index 35d5bf0dee6f..c0aa37d118c5 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -94,6 +94,7 @@ [LibraryClasses]
DebugAgentLib
CpuExceptionHandlerLib
PcdLib
+ ImagePropertiesRecordLib
[Guids]
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
index 728008a2e5bb..7321d99ef51b 100644
--- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -11,4 +11,137 @@
#ifndef IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
#define IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_
+#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 |
+ +---------------+
+ ==>
+ +---------------+
+ | 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 MemoryMapSize +
+ (AdditionalRecordCount * DescriptorSize) 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_RECORD 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 to 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
+ );
+
+/**
+ 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/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
index b7e493056889..4c1466fc3336 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
@@ -19,6 +19,10 @@ [Defines]
[Sources.common]
ImagePropertiesRecordLib.c
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
[Packages]
MdePkg/MdePkg.dec
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107204): https://edk2.groups.io/g/devel/message/107204
Mute This Topic: https://groups.io/mt/100342603/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 08/14] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (6 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 07/14] MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 09/14] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
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.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c | 938 ++++++++++++++++++++
MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf | 35 +
MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 5 +
3 files changed, 978 insertions(+)
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
new file mode 100644
index 000000000000..8b0a55685ce3
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.c
@@ -0,0 +1,938 @@
+/** @file
+ Unit tests the SplitTable() ImagePropertiesRecordLib Logic
+
+ Copyright (C) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
+
+#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) instead 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_NUMBER_OF_PAGES))
+
+// MACRO to get the starting address of a descriptor's described range based 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 * DESCRIPTOR_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 buffer 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 and the split descriptors
+#define SPLIT_MEMORY_MAP_SIZE (BASE_MEMORY_MAP_SIZE + (NUMBER_OF_ADDITIONAL_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[] = {
+ {
+ 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 sections
+ 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 == NULL) {
+ return 0;
+ }
+
+ ReturnBitmap = 0;
+ Shift = 0;
+
+ // Walk through each image record
+ for (ImageRecordLink = ImageRecordList->ForwardLink;
+ ImageRecordLink != ImageRecordList;
+ ImageRecordLink = ImageRecordLink->ForwardLink)
+ {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ SectionBase = ImageRecord->ImageBase;
+
+ // Walk through each code entry
+ for (ImageRecordCodeSectionLink = ImageRecord->CodeSegmentList.ForwardLink;
+ ImageRecordCodeSectionLink != &ImageRecord->CodeSegmentList;
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink)
+ {
+ ImageRecordCodeSection = CR (
+ ImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+
+ // Check for data region before the code section base
+ if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) {
+ ReturnBitmap |= LShiftU64 (1, Shift++);
+ }
+
+ // Code section
+ ReturnBitmap |= LShiftU64 (1, Shift++);
+ SectionBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
+ }
+
+ // Check for data region after the previous code section
+ if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+ ReturnBitmap |= LShiftU64 (1, Shift++);
+ }
+ }
+
+ return ReturnBitmap;
+}
+
+/**
+ Searches the input image list for a section which exactly matches the memory 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 with the memory
+ range Buffer -> Buffer + Length (Code or Data) 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 corresponds with the number of sections inspected
+ in the image list before arriving at the section matching the memory 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 = 0;
+
+ if (ImageRecordList == NULL) {
+ return 1;
+ }
+
+ // Walk through each image record
+ for (ImageRecordLink = ImageRecordList->ForwardLink;
+ ImageRecordLink != ImageRecordList;
+ ImageRecordLink = ImageRecordLink->ForwardLink)
+ {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ SectionBase = ImageRecord->ImageBase;
+
+ // Walk through each code entry
+ for (ImageRecordCodeSectionLink = ImageRecord->CodeSegmentList.ForwardLink;
+ ImageRecordCodeSectionLink != &ImageRecord->CodeSegmentList;
+ ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink)
+ {
+ ImageRecordCodeSection = CR (
+ ImageRecordCodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+
+ if (SectionBase < ImageRecordCodeSection->CodeSegmentBase) {
+ // Check the data region before the code section base
+ if ((Buffer == SectionBase) &&
+ (Length == ImageRecordCodeSection->CodeSegmentBase - SectionBase))
+ {
+ *Type = SectionTypeData;
+ return LShiftU64 (1, Shift);
+ }
+
+ Shift++;
+ }
+
+ // Check the code region
+ if ((Buffer == ImageRecordCodeSection->CodeSegmentBase) &&
+ (Length == ImageRecordCodeSection->CodeSegmentSize))
+ {
+ *Type = SectionTypeCode;
+ return LShiftU64 (1, Shift);
+ }
+
+ Shift++;
+ SectionBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
+ }
+
+ // Check the data region after the code section
+ if (SectionBase < (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
+ if ((Buffer == SectionBase) &&
+ (Length == (ImageRecord->ImageBase + ImageRecord->ImageSize) - SectionBase))
+ {
+ *Type = SectionTypeData;
+ return LShiftU64 (1, Shift);
+ }
+
+ Shift++;
+ }
+ }
+
+ // No image sections match
+ *Type = SectionTypeNotFound;
+ return 0;
+}
+
+/**
+ Walks through the input memory map and checks that every memory descriptor with an attribute matches
+ an image in ImageRecordList.
+
+ @param[in] MemoryMapSize The size, in bytes, of the memory map
+ @param[in] MemoryMap A pointer to the buffer containing the memory map
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
+
+ @retval TRUE if all memory descriptors with attributes match an image section 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 = 0;
+ NumberOfDescriptors = 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 1111111111111111111111111111111111111111111111111111111000000000. 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 memory 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 = ~GetImageSectionBitmap (ImageRecordList);
+
+ // For each descriptor in the memory map
+ for ( ; Index < NumberOfDescriptors; Index++) {
+ if (MemoryMap[Index].Attribute != 0) {
+ ReturnSectionBitmask = MatchDescriptorToImageSection (
+ MemoryMap[Index].PhysicalStart,
+ EFI_PAGES_TO_SIZE (MemoryMap[Index].NumberOfPages),
+ &Type,
+ ImageRecordList
+ );
+
+ // Make sure the attributes of the descriptor match the returned section type.
+ // DATA sections should have execution protection and CODE sections should have
+ // write protection.
+ if ((Type == SectionTypeNotFound) ||
+ ((Type == SectionTypeData) && (MemoryMap[Index].Attribute == EFI_MEMORY_RP)) ||
+ ((Type == SectionTypeCode) && (MemoryMap[Index].Attribute == 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 |= 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 = 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->ImageList);
+}
+
+/**
+ 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 the 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 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+ Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+ CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+ ///////////////
+ // Descriptor 1
+ ///////////////
+ // | | | | | | | |
+ // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+ // | | | | | | | |
+
+ Image1->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+ Image1->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+ Image1->CodeSegmentCount = 2;
+ CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+ TestContext->MemoryMap[1].Type = EfiBootServicesCode;
+
+ AddCodeSectionInImage1 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+ AddCodeSectionInImage1->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ AddCodeSectionInImage1->CodeSegmentBase = CodeSectionInImage1->CodeSegmentBase + CodeSectionInImage1->CodeSegmentSize + EFI_PAGE_SIZE;
+ AddCodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+
+ InsertTailList (&Image1->CodeSegmentList, &AddCodeSectionInImage1->Link);
+
+ ///////////////
+ // Descriptor 2
+ ///////////////
+ // | | | | | | | |
+ // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+ // | | | | | | | |
+
+ Image2->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (2) + EFI_PAGE_SIZE;
+ Image2->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+ Image2->CodeSegmentCount = 2;
+ CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+ TestContext->MemoryMap[2].Type = EfiLoaderCode;
+
+ AddCodeSectionInImage2 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+ AddCodeSectionInImage2->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ AddCodeSectionInImage2->CodeSegmentBase = CodeSectionInImage2->CodeSegmentBase + CodeSectionInImage2->CodeSegmentSize + EFI_PAGE_SIZE;
+ AddCodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+
+ InsertTailList (&Image2->CodeSegmentList, &AddCodeSectionInImage2->Link);
+
+ ///////////////
+ // Descriptor 3
+ ///////////////
+ // | | | | | | | |
+ // | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE * 5 |
+ // | | | | | | | |
+
+ Image3->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (3) + EFI_PAGE_SIZE;
+ Image3->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+ Image3->CodeSegmentCount = 2;
+ CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage3->CodeSegmentSize = EFI_PAGE_SIZE;
+ TestContext->MemoryMap[3].Type = EfiRuntimeServicesCode;
+
+ AddCodeSectionInImage3 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+ AddCodeSectionInImage3->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ AddCodeSectionInImage3->CodeSegmentBase = CodeSectionInImage3->CodeSegmentBase + CodeSectionInImage3->CodeSegmentSize + EFI_PAGE_SIZE;
+ AddCodeSectionInImage3->CodeSegmentSize = 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 the 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 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+ Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+ CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+ ///////////////
+ // Descriptor 1
+ ///////////////
+ // | | | | | | | | | | | | |
+ // | 4K PAGE | DATA | CODE | DATA | 4K PAGE | DATA | CODE | DATA | DATA | CODE | DATA | 4K PAGE |
+ // | | | | | | | | | | | | |
+
+ Image1->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+ Image1->ImageSize = EFI_PAGES_TO_SIZE (3);
+ Image1->CodeSegmentCount = 1;
+ CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage1->CodeSegmentSize = EFI_PAGE_SIZE;
+ TestContext->MemoryMap[1].Type = EfiBootServicesCode;
+
+ Image2->ImageBase = Image1->ImageBase + Image1->ImageSize + EFI_PAGE_SIZE;
+ Image2->ImageSize = EFI_PAGES_TO_SIZE (3);
+ Image2->CodeSegmentCount = 1;
+ CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage2->CodeSegmentSize = EFI_PAGE_SIZE;
+
+ Image3->ImageBase = Image2->ImageBase + Image2->ImageSize;
+ Image3->ImageSize = EFI_PAGES_TO_SIZE (3);
+ Image3->CodeSegmentCount = 1;
+ CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage3->CodeSegmentSize = 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 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 the 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 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+ Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+ CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+ ///////////////
+ // Descriptor 1
+ ///////////////
+ // | | | | |
+ // | 4K PAGE | DATA | CODE * 2 | DATA * 8 |
+ // | | | | |
+
+ Image1->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (1) + EFI_PAGE_SIZE;
+ Image1->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE;
+ Image1->CodeSegmentCount = 1;
+ CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage1->CodeSegmentSize = EFI_PAGES_TO_SIZE (2);
+ TestContext->MemoryMap[1].Type = EfiBootServicesCode;
+
+ ///////////////
+ // Descriptor 3
+ ///////////////
+ // | | | | |
+ // | DATA | CODE * 3 | DATA * 7 | 4K PAGE |
+ // | | | | |
+
+ Image2->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (3);
+ Image2->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE;
+ Image2->CodeSegmentCount = 1;
+ CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage2->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+ TestContext->MemoryMap[3].Type = EfiLoaderCode;
+
+ ///////////////
+ // Descriptor 4
+ ///////////////
+ // | | | | | |
+ // | 4K PAGE | DATA | CODE * 2 | DATA * 7 | 4K PAGE |
+ // | | | | | |
+
+ Image3->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (4) + EFI_PAGE_SIZE;
+ Image3->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE - EFI_PAGE_SIZE - EFI_PAGE_SIZE;
+ Image3->CodeSegmentCount = 1;
+ CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage3->CodeSegmentSize = EFI_PAGES_TO_SIZE (2);
+ TestContext->MemoryMap[4].Type = EfiRuntimeServicesCode;
+
+ UT_ASSERT_TRUE (SeparateAndCheck (TestContext));
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Test the case where all image ranges fit perfectly 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 the 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 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+
+ Image1 = CR (TestContext->ImageList.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image2 = CR (Image1->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+ Image3 = CR (Image2->Link.ForwardLink, IMAGE_PROPERTIES_RECORD, Link, IMAGE_PROPERTIES_RECORD_SIGNATURE);
+
+ CodeSectionInImage1 = CR (Image1->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage2 = CR (Image2->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+ CodeSectionInImage3 = CR (Image3->CodeSegmentList.ForwardLink, IMAGE_PROPERTIES_RECORD_CODE_SECTION, Link, IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE);
+
+ ///////////////
+ // Descriptor 1
+ ///////////////
+ // | | | |
+ // | DATA | CODE * 3 | DATA * 8 |
+ // | | | |
+
+ Image1->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (1);
+ Image1->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE;
+ Image1->CodeSegmentCount = 1;
+ CodeSectionInImage1->CodeSegmentBase = Image1->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage1->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+ TestContext->MemoryMap[1].Type = EfiBootServicesCode;
+
+ ///////////////
+ // Descriptor 2
+ ///////////////
+ // | | | |
+ // | DATA | CODE * 4 | DATA * 7 |
+ // | | | |
+
+ Image2->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (2);
+ Image2->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE;
+ Image2->CodeSegmentCount = 1;
+ CodeSectionInImage2->CodeSegmentBase = Image2->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage2->CodeSegmentSize = EFI_PAGES_TO_SIZE (4);
+ TestContext->MemoryMap[2].Type = EfiLoaderCode;
+
+ ///////////////
+ // Descriptor 3
+ ///////////////
+ // | | | |
+ // | DATA | CODE * 3 | DATA * 8 |
+ // | | | |
+
+ Image3->ImageBase = BASE_DESCRIPTOR_START_ADDRESS (3);
+ Image3->ImageSize = BASE_DESCRIPTOR_ENTRY_SIZE;
+ Image3->CodeSegmentCount = 1;
+ CodeSectionInImage3->CodeSegmentBase = Image3->ImageBase + EFI_PAGE_SIZE;
+ CodeSectionInImage3->CodeSegmentSize = EFI_PAGES_TO_SIZE (3);
+ TestContext->MemoryMap[3].Type = 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 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)Context;
+ ImageRecordLink = &TestContext->ImageList;
+
+ while (!IsListEmpty (ImageRecordLink)) {
+ ImageRecord = CR (
+ ImageRecordLink->ForwardLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ CodeSegmentListHead = &ImageRecord->CodeSegmentList;
+ while (!IsListEmpty (CodeSegmentListHead)) {
+ ImageRecordCodeSection = CR (
+ CodeSegmentListHead->ForwardLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ RemoveEntryList (&ImageRecordCodeSection->Link);
+ FreePool (ImageRecordCodeSection);
+ }
+
+ RemoveEntryList (&ImageRecord->Link);
+ FreePool (ImageRecord);
+ }
+
+ if (TestContext->MemoryMap != NULL) {
+ FreePool (TestContext->MemoryMap);
+ }
+}
+
+/**
+ Create a generic image list with the proper signatures which will be customized 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 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+ CodeSectionInImage1 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+ Image1->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ CodeSectionInImage1->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ InitializeListHead (&Image1->CodeSegmentList);
+
+ InsertTailList (&TestContext->ImageList, &Image1->Link);
+ InsertTailList (&Image1->CodeSegmentList, &CodeSectionInImage1->Link);
+
+ Image2 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+ CodeSectionInImage2 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+ Image2->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ CodeSectionInImage2->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ InitializeListHead (&Image2->CodeSegmentList);
+
+ InsertTailList (&TestContext->ImageList, &Image2->Link);
+ InsertTailList (&Image2->CodeSegmentList, &CodeSectionInImage2->Link);
+
+ Image3 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD));
+ CodeSectionInImage3 = AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_CODE_SECTION));
+
+ Image3->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ CodeSectionInImage3->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+ InitializeListHead (&Image3->CodeSegmentList);
+
+ InsertTailList (&TestContext->ImageList, &Image3->Link);
+ InsertTailList (&Image3->CodeSegmentList, &CodeSectionInImage3->Link);
+
+ TestContext->MemoryMap = 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_VERSION));
+
+ Framework = NULL;
+
+ Context1 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+ Context2 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+ Context3 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (sizeof (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT));
+ Context4 = (IMAGE_PROPERTIES_RECORD_HOST_TEST_CONTEXT *)AllocateZeroPool (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 = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+ goto EXIT;
+ }
+
+ //
+ // Populate the Unit Test Suite.
+ //
+ Status = CreateUnitTestSuite (&ImagePropertiesRecordTests, Framework, "Image Properties Record Tests", "ImagePropertiesRecordLib.SplitTable", NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Image Properties Record Tests\n"));
+ Status = 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", ImagesDontFitDescriptors, NULL, TestCleanup, Context2);
+ AddTestCase (ImagePropertiesRecordTests, "All Images are contined In single descriptor", "MultipleImagesInOneDescriptor", MultipleImagesInOneDescriptor, NULL, TestCleanup, Context3);
+ AddTestCase (ImagePropertiesRecordTests, "Multiple code sections each image", "MaxOutAdditionalDescriptors", MaxOutAdditionalDescriptors, NULL, TestCleanup, Context4);
+
+ //
+ // Execute the tests.
+ //
+ Status = 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/ImagePropertiesRecordLibUnitTestHost.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf
new file mode 100644
index 000000000000..cbc64a14bde7
--- /dev/null
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.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 = 0x00010006
+ BASE_NAME = ImagePropertiesRecordLibUnitTestHost
+ FILE_GUID = 45B39FAA-E25D-4724-A6F4-93C0C8588A80
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = 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
}
+ MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf {
+ <LibraryClasses>
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+ }
+
#
# Build HOST_APPLICATION Libraries
#
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107205): https://edk2.groups.io/g/devel/message/107205
Mute This Topic: https://groups.io/mt/100342604/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 09/14] MdeModulePkg: Fix Bugs in MAT Logic
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (7 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 08/14] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 10/14] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Fix the bugs in the MAT logic before switching the
UEFI and SMM MAT logic to use the new library.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 2 +-
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 98 ++++++++++----------
2 files changed, 49 insertions(+), 51 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index 51630f504ea1..af6c26244cc0 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -517,7 +517,7 @@ CoreGetMemoryMapWithSeparatedImageSection (
CoreAcquiremMemoryAttributesTableLock ();
- AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
+ AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
OldMemoryMapSize = *MemoryMapSize;
Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index d942c7fef19a..b079cc3503ee 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -277,7 +277,7 @@ GetMaxSplitRecordCount (
break;
}
- SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);
+ SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 3);
PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
@@ -323,7 +323,6 @@ SplitRecord (
UINT64 PhysicalEnd;
UINTN NewRecordCount;
UINTN TotalNewRecordCount;
- BOOLEAN IsLastRecordData;
if (MaxSplitRecordCount == 0) {
CopyMem (NewRecord, OldRecord, DescriptorSize);
@@ -344,35 +343,16 @@ SplitRecord (
NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList);
if (NewImageRecord == NULL) {
//
- // No more image covered by this range, stop
+ // No more images cover this range, check if we've reached the end of the old descriptor. If not,
+ // add the remaining range to the new descriptor list.
//
- if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
- //
- // If this is still address in this record, need record.
- //
- NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- IsLastRecordData = FALSE;
- if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {
- IsLastRecordData = TRUE;
- }
-
- if (IsLastRecordData) {
- //
- // Last record is DATA, just merge it.
- //
- NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
- } else {
- //
- // Last record is CODE, create a new DATA entry.
- //
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = TempRecord.NumberOfPages;
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- TotalNewRecordCount++;
- }
+ if (PhysicalEnd > PhysicalStart) {
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = PhysicalStart;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+ NewRecord->Attribute = TempRecord.Attribute;
+ TotalNewRecordCount++;
}
break;
@@ -380,6 +360,24 @@ SplitRecord (
ImageRecord = NewImageRecord;
+ //
+ // Update PhysicalStart to exclude the portion before the image buffer
+ //
+ if (TempRecord.PhysicalStart < ImageRecord->ImageBase) {
+ NewRecord->Type = TempRecord.Type;
+ NewRecord->PhysicalStart = TempRecord.PhysicalStart;
+ NewRecord->VirtualStart = 0;
+ NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart);
+ NewRecord->Attribute = TempRecord.Attribute;
+ TotalNewRecordCount++;
+
+ PhysicalStart = ImageRecord->ImageBase;
+ TempRecord.PhysicalStart = PhysicalStart;
+ TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
+
+ NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + DescriptorSize);
+ }
+
//
// Set new record
//
@@ -465,11 +463,12 @@ SplitTable (
{
INTN IndexOld;
INTN IndexNew;
+ INTN IndexNewStarting;
UINTN MaxSplitRecordCount;
UINTN RealSplitRecordCount;
- UINTN TotalSplitRecordCount;
+ UINTN TotalSkippedRecords;
- TotalSplitRecordCount = 0;
+ TotalSkippedRecords = 0;
//
// Let old record point to end of valid MemoryMap buffer.
//
@@ -477,7 +476,8 @@ SplitTable (
//
// Let new record point to end of full MemoryMap buffer.
//
- IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+ IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + NumberOfAdditionalDescriptors;
+ IndexNewStarting = IndexNew;
for ( ; IndexOld >= 0; IndexOld--) {
MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), ImageRecordList);
//
@@ -491,16 +491,14 @@ SplitTable (
DescriptorSize,
ImageRecordList
);
- //
- // Adjust IndexNew according to real split.
- //
- CopyMem (
- ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
- ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
- RealSplitRecordCount * DescriptorSize
- );
- IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
- TotalSplitRecordCount += RealSplitRecordCount;
+
+ // If we didn't utilize all the extra allocated descriptor slots, set the physical address of the unused slots
+ // to MAX_ADDRESS so they are moved to the bottom of the list when sorting.
+ for ( ; RealSplitRecordCount < MaxSplitRecordCount; RealSplitRecordCount++) {
+ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + ((IndexNew + RealSplitRecordCount + 1) * DescriptorSize)))->PhysicalStart = MAX_ADDRESS;
+ TotalSkippedRecords++;
+ }
+
IndexNew--;
}
@@ -509,16 +507,16 @@ SplitTable (
//
CopyMem (
MemoryMap,
- (UINT8 *)MemoryMap + (NumberOfAdditionalDescriptors - TotalSplitRecordCount) * DescriptorSize,
- (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
+ (UINT8 *)MemoryMap + ((IndexNew + 1) * DescriptorSize),
+ (IndexNewStarting - IndexNew) * DescriptorSize
);
- *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
+ //
+ // Sort from low to high to filter out the MAX_ADDRESS records.
+ //
+ SortMemoryMap (MemoryMap, (IndexNewStarting - IndexNew) * DescriptorSize, DescriptorSize);
- //
- // Sort from low to high (Just in case)
- //
- SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);
+ *MemoryMapSize = (IndexNewStarting - IndexNew - TotalSkippedRecords) * DescriptorSize;
return;
}
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107206): https://edk2.groups.io/g/devel/message/107206
Mute This Topic: https://groups.io/mt/100342605/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 10/14] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (8 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 09/14] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 11/14] MdeModulePkg: Transition SMM MAT Logic to Use ImagePropertiesRecordLib Taylor Beebe
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Eric Dong, Ray Ni, Rahul Kumar, Gerd Hoffmann
The function EnforceMemoryMapAttribute() in the SMM MAT logic will
ensure that the CODE and DATA memory types have the desired attributes.
The consumer of the SMM MAT should only override the Attributes field
in the MAT if it is nonzero. This also allows the UEFI and SMM MAT
logic to use ImagePropertiesRecordLib instead of carrying two copies
of the image properties record manipulation.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 6f498666157e..d302a9b0cbcf 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1062,14 +1062,17 @@ SetMemMapAttributes (
MemoryMap = MemoryMapStart;
for (Index = 0; Index < MemoryMapEntryCount; Index++) {
DEBUG ((DEBUG_VERBOSE, "SetAttribute: Memory Entry - 0x%lx, 0x%x\n", MemoryMap->PhysicalStart, MemoryMap->NumberOfPages));
- if (MemoryMap->Type == EfiRuntimeServicesCode) {
- MemoryAttribute = EFI_MEMORY_RO;
- } else {
- ASSERT ((MemoryMap->Type == EfiRuntimeServicesData) || (MemoryMap->Type == EfiConventionalMemory));
- //
- // Set other type memory as NX.
- //
- MemoryAttribute = EFI_MEMORY_XP;
+ MemoryAttribute = MemoryMap->Attribute & EFI_MEMORY_ACCESS_MASK;
+ if (MemoryAttribute == 0) {
+ if (MemoryMap->Type == EfiRuntimeServicesCode) {
+ MemoryAttribute = EFI_MEMORY_RO;
+ } else {
+ ASSERT ((MemoryMap->Type == EfiRuntimeServicesData) || (MemoryMap->Type == EfiConventionalMemory));
+ //
+ // Set other type memory as NX.
+ //
+ MemoryAttribute = EFI_MEMORY_XP;
+ }
}
//
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107207): https://edk2.groups.io/g/devel/message/107207
Mute This Topic: https://groups.io/mt/100342606/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 11/14] MdeModulePkg: Transition SMM MAT Logic to Use ImagePropertiesRecordLib
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (9 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 10/14] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 12/14] MdeModulePkg: Add Logic to Create/Delete Image Properties Records Taylor Beebe
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Now that the bugs are fixed in the MAT logic, we can remove the
duplicate logic from PiSmmCore/MemoryAttributesTable.c and use
ImagePropertiesRecordLib instead.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 785 +-------------------
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 29 +
MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 1 +
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 11 +
4 files changed, 58 insertions(+), 768 deletions(-)
diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
index 394fdae50741..2e4aaddef4e5 100644
--- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
@@ -14,6 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/SmmServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
@@ -25,26 +26,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
-#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;
-
#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')
typedef struct {
@@ -69,87 +50,6 @@ UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTEC
// Below functions are for MemoryMap
//
-/**
- 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[in] Pages The number of EFI_PAGES.
-
- @return The number of bytes associated with the number of EFI_PAGEs specified
- 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[in] Size A size in bytes.
-
- @return The number of EFI_PAGESs associated with the number of bytes specified
- by Size.
-
-**/
-STATIC
-UINT64
-EfiSizeToPages (
- IN UINT64 Size
- )
-{
- return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
-}
-
-/**
- Sort memory map entries based upon PhysicalStart, from low to high.
-
- @param[in,out] MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.
- @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_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 = MemoryMap;
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
- while (MemoryMapEntry < MemoryMapEnd) {
- while (NextMemoryMapEntry < MemoryMapEnd) {
- if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
- CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
- }
-
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
- }
-
- MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- }
-
- return;
-}
-
/**
Merge continuous memory map entries whose have same attributes.
@@ -183,7 +83,7 @@ MergeMemoryMap (
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
do {
- MemoryBlockLength = (UINT64)(EfiPagesToSize (MemoryMapEntry->NumberOfPages));
+ MemoryBlockLength = LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
(MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
(MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
@@ -254,423 +154,6 @@ EnforceMemoryMapAttribute (
return;
}
-/**
- Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
-
- @param[in] Buffer Start Address
- @param[in] Length Address length
-
- @return first image record covered by [buffer, length]
-**/
-STATIC
-IMAGE_PROPERTIES_RECORD *
-GetImageRecordByAddress (
- IN EFI_PHYSICAL_ADDRESS Buffer,
- IN UINT64 Length
- )
-{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- LIST_ENTRY *ImageRecordLink;
- LIST_ENTRY *ImageRecordList;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
- for (ImageRecordLink = ImageRecordList->ForwardLink;
- ImageRecordLink != ImageRecordList;
- ImageRecordLink = ImageRecordLink->ForwardLink)
- {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
-
- if ((Buffer <= ImageRecord->ImageBase) &&
- (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))
- {
- 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[in] ImageRecord An image record whose [ImageBase, ImageSize] covered
- by old memory map entry.
- @param[in, out] NewRecord A pointer to several new memory map entries.
- The caller guarantee the buffer size be 1 +
- (SplitRecordCount * DescriptorSize) calculated
- below.
- @param[in] OldRecord A pointer to one old memory map entry.
- @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_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 = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
- NewRecordCount = 0;
-
- //
- // Always create a new entry for non-PE image record
- //
- if (ImageRecord->ImageBase > TempRecord.PhysicalStart) {
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart);
- NewRecord->Attribute = TempRecord.Attribute;
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecordCount++;
- TempRecord.PhysicalStart = ImageRecord->ImageBase;
- TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
- }
-
- ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
-
- if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
- //
- // DATA
- //
- NewRecord->Type = EfiRuntimeServicesData;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- if (NewRecord->NumberOfPages != 0) {
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecordCount++;
- }
-
- //
- // CODE
- //
- NewRecord->Type = EfiRuntimeServicesCode;
- NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
- NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
- if (NewRecord->NumberOfPages != 0) {
- NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
- NewRecordCount++;
- }
-
- TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
- TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
- if (TempRecord.NumberOfPages == 0) {
- break;
- }
- }
- }
-
- ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
-
- //
- // Final DATA
- //
- if (TempRecord.PhysicalStart < ImageEnd) {
- NewRecord->Type = EfiRuntimeServicesData;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);
- NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
- NewRecordCount++;
- }
-
- return NewRecordCount;
-}
-
-/**
- Return the max number of new splitted entries, according to one old entry,
- based upon PE code section and data section.
-
- @param[in] 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
- )
-{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- UINTN SplitRecordCount;
- UINT64 PhysicalStart;
- UINT64 PhysicalEnd;
-
- SplitRecordCount = 0;
- PhysicalStart = OldRecord->PhysicalStart;
- PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
-
- do {
- ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
- if (ImageRecord == NULL) {
- break;
- }
-
- SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2);
- PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
- } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
- return SplitRecordCount;
-}
-
-/**
- Split the memory map to new entries, according to one old entry,
- based upon PE code section and data section.
-
- @param[in] OldRecord A pointer to one old memory map entry.
- @param[in, out] NewRecord A pointer to several new memory map entries.
- The caller guarantee the buffer size be 1 +
- (SplitRecordCount * DescriptorSize) calculated
- below.
- @param[in] MaxSplitRecordCount The max number of splitted entries
- @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-
- @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
- )
-{
- EFI_MEMORY_DESCRIPTOR TempRecord;
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- IMAGE_PROPERTIES_RECORD *NewImageRecord;
- UINT64 PhysicalStart;
- UINT64 PhysicalEnd;
- UINTN NewRecordCount;
- UINTN TotalNewRecordCount;
-
- if (MaxSplitRecordCount == 0) {
- CopyMem (NewRecord, OldRecord, DescriptorSize);
- return 0;
- }
-
- TotalNewRecordCount = 0;
-
- //
- // Override previous record
- //
- CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
- PhysicalStart = TempRecord.PhysicalStart;
- PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);
-
- ImageRecord = NULL;
- do {
- NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
- if (NewImageRecord == NULL) {
- //
- // No more image covered by this range, stop
- //
- if (PhysicalEnd > PhysicalStart) {
- //
- // Always create a new entry for non-PE image record
- //
- NewRecord->Type = TempRecord.Type;
- NewRecord->PhysicalStart = TempRecord.PhysicalStart;
- NewRecord->VirtualStart = 0;
- NewRecord->NumberOfPages = TempRecord.NumberOfPages;
- NewRecord->Attribute = TempRecord.Attribute;
- TotalNewRecordCount++;
- }
-
- break;
- }
-
- ImageRecord = NewImageRecord;
-
- //
- // Set new record
- //
- NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);
- TotalNewRecordCount += NewRecordCount;
- NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);
-
- //
- // Update PhysicalStart, in order to exclude the image buffer already splitted.
- //
- PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;
- TempRecord.PhysicalStart = PhysicalStart;
- TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
- } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
-
- 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 |
- +---------------+
- ==>
- +---------------+
- | Record X |
- +---------------+
- | Record RtCode |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF1
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record RtCode |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF2
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record RtCode |
- +---------------+
- | Record Y |
- +---------------+
-
- @param[in, out] 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 MemoryMapSize +
- (AdditionalRecordCount * DescriptorSize) calculated
- below. On output, it is the size of new MemoryMap
- after split.
- @param[in, out] MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SplitTable (
- IN OUT UINTN *MemoryMapSize,
- IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- IN UINTN DescriptorSize
- )
-{
- INTN IndexOld;
- INTN IndexNew;
- UINTN MaxSplitRecordCount;
- UINTN RealSplitRecordCount;
- UINTN TotalSplitRecordCount;
- UINTN AdditionalRecordCount;
-
- AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
-
- TotalSplitRecordCount = 0;
- //
- // Let old record point to end of valid MemoryMap buffer.
- //
- IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;
- //
- // Let new record point to end of full MemoryMap buffer.
- //
- IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;
- for ( ; IndexOld >= 0; IndexOld--) {
- MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));
- //
- // Split this MemoryMap record
- //
- IndexNew -= MaxSplitRecordCount;
- RealSplitRecordCount = SplitRecord (
- (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),
- (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
- MaxSplitRecordCount,
- DescriptorSize
- );
- //
- // Adjust IndexNew according to real split.
- //
- if (MaxSplitRecordCount != RealSplitRecordCount) {
- CopyMem (
- ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
- ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
- (RealSplitRecordCount + 1) * DescriptorSize
- );
- }
-
- IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
- TotalSplitRecordCount += RealSplitRecordCount;
- IndexNew--;
- }
-
- //
- // Move all records to the beginning.
- //
- CopyMem (
- MemoryMap,
- (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,
- (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize
- );
-
- *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;
-
- //
- // 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 memory attributes table.
@@ -729,7 +212,7 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
return EFI_INVALID_PARAMETER;
}
- AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;
+ AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
OldMemoryMapSize = *MemoryMapSize;
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@@ -747,7 +230,17 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
// Split PE code/data
//
ASSERT (MemoryMap != NULL);
- SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);
+ SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
+
+ //
+ // Set RuntimeData to XP
+ //
+ EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize);
+
+ //
+ // Merge same type to save entry size
+ //
+ MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize);
}
}
@@ -777,250 +270,6 @@ SetMemoryAttributesTableSectionAlignment (
}
}
-/**
- Swap two code sections in image record.
-
- @param[in] FirstImageRecordCodeSection first code section in image record
- @param[in] SecondImageRecordCodeSection second code section in image record
-**/
-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 = FirstImageRecordCodeSection->CodeSegmentBase;
- TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
-
- FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
- FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
-
- SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
- SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
-}
-
-/**
- Sort code section in image record, based upon CodeSegmentBase from low to high.
-
- @param[in] ImageRecord image record to be sorted
-**/
-STATIC
-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 = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- NextImageRecordCodeSection = CR (
- NextImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
- SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
- }
-
- NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
- }
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- }
-}
-
-/**
- Check if code section in image record is valid.
-
- @param[in] ImageRecord image record to be checked
-
- @retval TRUE image record is valid
- @retval FALSE image record is invalid
-**/
-STATIC
-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, "SMM ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
-
- ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
-
- ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
- ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
- LastImageRecordCodeSection = NULL;
- while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
- ImageRecordCodeSection = CR (
- ImageRecordCodeSectionLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- if (ImageRecordCodeSection->CodeSegmentSize == 0) {
- return FALSE;
- }
-
- if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
- return FALSE;
- }
-
- if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
- return FALSE;
- }
-
- if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
- return FALSE;
- }
-
- if (LastImageRecordCodeSection != NULL) {
- if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
- return FALSE;
- }
- }
-
- LastImageRecordCodeSection = ImageRecordCodeSection;
- ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
- }
-
- return TRUE;
-}
-
-/**
- Swap two image records.
-
- @param[in] FirstImageRecord first image record.
- @param[in] SecondImageRecord second image record.
-**/
-STATIC
-VOID
-SwapImageRecord (
- IN IMAGE_PROPERTIES_RECORD *FirstImageRecord,
- IN IMAGE_PROPERTIES_RECORD *SecondImageRecord
- )
-{
- IMAGE_PROPERTIES_RECORD TempImageRecord;
-
- TempImageRecord.ImageBase = FirstImageRecord->ImageBase;
- TempImageRecord.ImageSize = FirstImageRecord->ImageSize;
- TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
-
- FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;
- FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;
- FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
-
- SecondImageRecord->ImageBase = TempImageRecord.ImageBase;
- SecondImageRecord->ImageSize = TempImageRecord.ImageSize;
- SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
-
- SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
-}
-
-/**
- Sort image record based upon the ImageBase from low to high.
-**/
-STATIC
-VOID
-SortImageRecord (
- VOID
- )
-{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- IMAGE_PROPERTIES_RECORD *NextImageRecord;
- LIST_ENTRY *ImageRecordLink;
- LIST_ENTRY *NextImageRecordLink;
- LIST_ENTRY *ImageRecordEndLink;
- LIST_ENTRY *ImageRecordList;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
- ImageRecordLink = ImageRecordList->ForwardLink;
- NextImageRecordLink = ImageRecordLink->ForwardLink;
- ImageRecordEndLink = ImageRecordList;
- while (ImageRecordLink != ImageRecordEndLink) {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- while (NextImageRecordLink != ImageRecordEndLink) {
- NextImageRecord = CR (
- NextImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
- SwapImageRecord (ImageRecord, NextImageRecord);
- }
-
- NextImageRecordLink = NextImageRecordLink->ForwardLink;
- }
-
- ImageRecordLink = ImageRecordLink->ForwardLink;
- NextImageRecordLink = ImageRecordLink->ForwardLink;
- }
-}
-
-/**
- Dump image record.
-**/
-STATIC
-VOID
-DumpImageRecord (
- VOID
- )
-{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- LIST_ENTRY *ImageRecordLink;
- LIST_ENTRY *ImageRecordList;
- UINTN Index;
-
- ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
-
- for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
- ImageRecordLink != ImageRecordList;
- ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
- {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));
- }
-}
-
/**
Insert image record.
@@ -1059,7 +308,7 @@ SmmInsertImageRecord (
// Step 1: record whole region
//
ImageRecord->ImageBase = DriverEntry->ImageBuffer;
- ImageRecord->ImageSize = EfiPagesToSize (DriverEntry->NumberOfPage);
+ ImageRecord->ImageSize = LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT);
ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer;
@@ -1193,7 +442,7 @@ SmmInsertImageRecord (
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
}
- SortImageRecord ();
+ SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
return;
@@ -1361,7 +610,7 @@ SmmInstallMemoryAttributesTable (
DEBUG ((DEBUG_VERBOSE, "SMM Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
DEBUG ((DEBUG_VERBOSE, "SMM Dump ImageRecord:\n"));
- DumpImageRecord ();
+ DumpImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
PublishMemoryAttributesTable ();
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index b079cc3503ee..eaef54464395 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -735,6 +735,35 @@ SortImageRecord (
}
}
+/**
+ Dump image record.
+
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
+**/
+VOID
+EFIAPI
+DumpImageRecord (
+ IN LIST_ENTRY *ImageRecordList
+ )
+{
+ IMAGE_PROPERTIES_RECORD *ImageRecord;
+ LIST_ENTRY *ImageRecordLink;
+ UINTN Index;
+
+ for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
+ ImageRecordLink != ImageRecordList;
+ ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
+ {
+ ImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+ DEBUG ((DEBUG_VERBOSE, "Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));
+ }
+}
+
/**
Find image record according to image base and size.
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 3df44b38f13c..75a5934f0c1d 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -61,6 +61,7 @@ [LibraryClasses]
HobLib
SmmMemLib
SafeIntLib
+ ImagePropertiesRecordLib
[Protocols]
gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
index 7321d99ef51b..90e6a262463c 100644
--- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -144,4 +144,15 @@ FindImageRecord (
IN LIST_ENTRY *ImageRecordList
);
+/**
+ Dump image record.
+
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
+**/
+VOID
+EFIAPI
+DumpImageRecord (
+ IN LIST_ENTRY *ImageRecordList
+ );
+
#endif
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107208): https://edk2.groups.io/g/devel/message/107208
Mute This Topic: https://groups.io/mt/100342607/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 12/14] MdeModulePkg: Add Logic to Create/Delete Image Properties Records
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (10 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 11/14] MdeModulePkg: Transition SMM MAT Logic to Use ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 13/14] MdeModulePkg: Update Function Headers in ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 14/14] MdeModulePkg: Update DumpImageRecord() " Taylor Beebe
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Add logic to create and delete image properties records. Where
applicable, redirect existing code to use the new library.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 184 +++----------------
MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 166 +++--------------
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 186 ++++++++++++++++++++
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 39 ++++
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf | 1 +
5 files changed, 281 insertions(+), 295 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index af6c26244cc0..993db281062a 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -557,25 +557,6 @@ CoreGetMemoryMapWithSeparatedImageSection (
// Below functions are for ImageRecord
//
-/**
- Set MemoryAttributesTable according to PE/COFF image section alignment.
-
- @param SectionAlignment PE/COFF section alignment
-**/
-STATIC
-VOID
-SetMemoryAttributesTableSectionAlignment (
- IN UINT32 SectionAlignment
- )
-{
- if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
- mMemoryAttributesTableEnable)
- {
- DEBUG ((DEBUG_VERBOSE, "SetMemoryAttributesTableSectionAlignment - Clear\n"));
- mMemoryAttributesTableEnable = FALSE;
- }
-}
-
/**
Insert image record.
@@ -586,20 +567,12 @@ InsertImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
)
{
- VOID *ImageAddress;
- EFI_IMAGE_DOS_HEADER *DosHdr;
- UINT32 PeCoffHeaderOffset;
- UINT32 SectionAlignment;
- EFI_IMAGE_SECTION_HEADER *Section;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- UINT8 *Name;
- UINTN Index;
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- CHAR8 *PdbPointer;
- IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
+ EFI_STATUS Status;
+ IMAGE_PROPERTIES_RECORD *ImageRecord;
+ CHAR8 *PdbPointer;
+ UINT32 RequiredAlignment;
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
- DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
if (mMemoryAttributesTableEndOfDxe) {
DEBUG ((DEBUG_INFO, "Do not insert runtime image record after EndOfDxe\n"));
@@ -611,139 +584,48 @@ InsertImageRecord (
return;
}
- ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ InitializeListHead (&ImageRecord->Link);
+ InitializeListHead (&ImageRecord->CodeSegmentList);
- DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
-
- //
- // Step 1: record whole region
- //
- ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase;
- ImageRecord->ImageSize = RuntimeImage->ImageSize;
-
- ImageAddress = RuntimeImage->ImageBase;
-
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RuntimeImage->ImageBase);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
}
- //
- // Check PE/COFF image
- //
- DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
- PeCoffHeaderOffset = 0;
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
- PeCoffHeaderOffset = DosHdr->e_lfanew;
- }
-
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
- if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
- DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));
- // It might be image in SMM.
- goto Finish;
- }
-
- //
- // Get SectionAlignment
- //
- if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
- } else {
- SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;
- }
-
- SetMemoryAttributesTableSectionAlignment (SectionAlignment);
- if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
- DEBUG ((
- DEBUG_WARN,
- "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
- SectionAlignment,
- RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10
- ));
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
- if (PdbPointer != NULL) {
- DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
+ RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
+ Status = CreateImagePropertiesRecord (
+ RuntimeImage->ImageBase,
+ RuntimeImage->ImageSize,
+ &RequiredAlignment,
+ ImageRecord
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ mMemoryAttributesTableEnable = FALSE;
}
+ Status = EFI_ABORTED;
goto Finish;
}
- Section = (EFI_IMAGE_SECTION_HEADER *)(
- (UINT8 *)(UINTN)ImageAddress +
- PeCoffHeaderOffset +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- Hdr.Pe32->FileHeader.SizeOfOptionalHeader
- );
- ImageRecord->CodeSegmentCount = 0;
- InitializeListHead (&ImageRecord->CodeSegmentList);
- for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
- Name = Section[Index].Name;
- DEBUG ((
- DEBUG_VERBOSE,
- " Section - '%c%c%c%c%c%c%c%c'\n",
- Name[0],
- Name[1],
- Name[2],
- Name[3],
- Name[4],
- Name[5],
- Name[6],
- Name[7]
- ));
-
- if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {
- DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));
- DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));
- DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));
- DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));
- DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));
- DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));
- DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));
- DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));
- DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics));
-
- //
- // Step 2: record code section
- //
- ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));
- if (ImageRecordCodeSection == NULL) {
- return;
- }
-
- ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
-
- ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;
- ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;
-
- DEBUG ((DEBUG_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));
-
- InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);
- ImageRecord->CodeSegmentCount++;
- }
- }
-
if (ImageRecord->CodeSegmentCount == 0) {
- SetMemoryAttributesTableSectionAlignment (1);
+ mMemoryAttributesTableEnable = FALSE;
DEBUG ((DEBUG_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
+ Status = EFI_ABORTED;
goto Finish;
}
- //
- // Final
- //
- SortImageRecordCodeSection (ImageRecord);
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));
+ Status = EFI_ABORTED;
goto Finish;
}
@@ -757,6 +639,10 @@ InsertImageRecord (
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
+ if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
+ DeleteImagePropertiesRecord (ImageRecord);
+ }
+
return;
}
@@ -770,9 +656,7 @@ RemoveImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
)
{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- LIST_ENTRY *CodeSegmentListHead;
- IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
+ IMAGE_PROPERTIES_RECORD *ImageRecord;
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
@@ -788,19 +672,7 @@ RemoveImageRecord (
return;
}
- CodeSegmentListHead = &ImageRecord->CodeSegmentList;
- while (!IsListEmpty (CodeSegmentListHead)) {
- ImageRecordCodeSection = CR (
- CodeSegmentListHead->ForwardLink,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION,
- Link,
- IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
- );
- RemoveEntryList (&ImageRecordCodeSection->Link);
- FreePool (ImageRecordCodeSection);
- }
+ DeleteImagePropertiesRecord (ImageRecord);
- RemoveEntryList (&ImageRecord->Link);
- FreePool (ImageRecord);
mImagePropertiesPrivateData.ImageRecordCount--;
}
diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
index 2e4aaddef4e5..03de9b2c5fff 100644
--- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
@@ -251,25 +251,6 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
// Below functions are for ImageRecord
//
-/**
- Set MemoryProtectionAttribute according to PE/COFF image section alignment.
-
- @param[in] SectionAlignment PE/COFF section alignment
-**/
-STATIC
-VOID
-SetMemoryAttributesTableSectionAlignment (
- IN UINT32 SectionAlignment
- )
-{
- if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
- ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0))
- {
- DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n"));
- mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
- }
-}
-
/**
Insert image record.
@@ -280,158 +261,61 @@ SmmInsertImageRecord (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry
)
{
- VOID *ImageAddress;
- EFI_IMAGE_DOS_HEADER *DosHdr;
- UINT32 PeCoffHeaderOffset;
- UINT32 SectionAlignment;
- EFI_IMAGE_SECTION_HEADER *Section;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- UINT8 *Name;
- UINTN Index;
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- CHAR8 *PdbPointer;
- IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
+ EFI_STATUS Status;
+ IMAGE_PROPERTIES_RECORD *ImageRecord;
+ CHAR8 *PdbPointer;
+ UINT32 RequiredAlignment;
DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry));
- DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", DriverEntry->ImageBuffer, DriverEntry->NumberOfPage));
ImageRecord = AllocatePool (sizeof (*ImageRecord));
if (ImageRecord == NULL) {
return;
}
- ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ InitializeListHead (&ImageRecord->Link);
+ InitializeListHead (&ImageRecord->CodeSegmentList);
- DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
-
- //
- // Step 1: record whole region
- //
- ImageRecord->ImageBase = DriverEntry->ImageBuffer;
- ImageRecord->ImageSize = LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT);
-
- ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer;
-
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));
}
- //
- // Check PE/COFF image
- //
- DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
- PeCoffHeaderOffset = 0;
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
- PeCoffHeaderOffset = DosHdr->e_lfanew;
- }
-
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
- if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
- DEBUG ((DEBUG_VERBOSE, "SMM Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));
- goto Finish;
- }
-
- //
- // Get SectionAlignment
- //
- if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
- } else {
- SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;
- }
-
- SetMemoryAttributesTableSectionAlignment (SectionAlignment);
- if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
- DEBUG ((
- DEBUG_WARN,
- "SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
- SectionAlignment,
- RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10
- ));
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
- if (PdbPointer != NULL) {
- DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
+ RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
+ Status = CreateImagePropertiesRecord (
+ (VOID *)(UINTN)DriverEntry->ImageBuffer,
+ LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT),
+ &RequiredAlignment,
+ ImageRecord
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ mMemoryProtectionAttribute &=
+ ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
}
goto Finish;
}
- Section = (EFI_IMAGE_SECTION_HEADER *)(
- (UINT8 *)(UINTN)ImageAddress +
- PeCoffHeaderOffset +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- Hdr.Pe32->FileHeader.SizeOfOptionalHeader
- );
- ImageRecord->CodeSegmentCount = 0;
- InitializeListHead (&ImageRecord->CodeSegmentList);
- for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
- Name = Section[Index].Name;
- DEBUG ((
- DEBUG_VERBOSE,
- "SMM Section - '%c%c%c%c%c%c%c%c'\n",
- Name[0],
- Name[1],
- Name[2],
- Name[3],
- Name[4],
- Name[5],
- Name[6],
- Name[7]
- ));
-
- if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {
- DEBUG ((DEBUG_VERBOSE, "SMM VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));
- DEBUG ((DEBUG_VERBOSE, "SMM VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));
- DEBUG ((DEBUG_VERBOSE, "SMM SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));
- DEBUG ((DEBUG_VERBOSE, "SMM PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));
- DEBUG ((DEBUG_VERBOSE, "SMM PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));
- DEBUG ((DEBUG_VERBOSE, "SMM PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));
- DEBUG ((DEBUG_VERBOSE, "SMM NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));
- DEBUG ((DEBUG_VERBOSE, "SMM NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));
- DEBUG ((DEBUG_VERBOSE, "SMM Characteristics - 0x%08x\n", Section[Index].Characteristics));
-
- //
- // Step 2: record code section
- //
- ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));
- if (ImageRecordCodeSection == NULL) {
- return;
- }
-
- ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
-
- ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;
- ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;
-
- DEBUG ((DEBUG_VERBOSE, "SMM ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));
-
- InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);
- ImageRecord->CodeSegmentCount++;
- }
- }
-
if (ImageRecord->CodeSegmentCount == 0) {
- SetMemoryAttributesTableSectionAlignment (1);
+ mMemoryProtectionAttribute &=
+ ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
+ Status = EFI_ABORTED;
goto Finish;
}
- //
- // Final
- //
- SortImageRecordCodeSection (ImageRecord);
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n"));
+ Status = EFI_ABORTED;
goto Finish;
}
@@ -445,6 +329,10 @@ SmmInsertImageRecord (
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
+ if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
+ DeleteImagePropertiesRecord (ImageRecord);
+ }
+
return;
}
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index eaef54464395..9ac3afdaa202 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -13,6 +13,7 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/ImagePropertiesRecordLib.h>
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
@@ -804,3 +805,188 @@ FindImageRecord (
return NULL;
}
+
+/**
+ Creates an IMAGE_PROPERTIES_RECORD from a loaded PE image. The PE/COFF header will be found
+ and parsed to determine the number of code segments and their base addresses and sizes.
+
+ @param[in] ImageBase Base of the PE image
+ @param[in] ImageSize Size of the PE image
+ @param[in] RequiredAlignment If non-NULL, the alignment specified in the PE/COFF header
+ will be compared against this value.
+ @param[out] ImageRecord On out, a populated image properties record
+
+ @retval EFI_INVALID_PARAMETER This function ImageBase or ImageRecord was NULL, or the
+ image located at ImageBase was not a valid PE/COFF image
+ @retval EFI_OUT_OF_RESOURCES Failure to Allocate()
+ @retval EFI_ABORTED The input Alignment was non-NULL and did not match the
+ alignment specified in the PE/COFF header
+ @retval EFI_SUCCESS The image properties record was successfully created
+**/
+EFI_STATUS
+EFIAPI
+CreateImagePropertiesRecord (
+ IN CONST VOID *ImageBase,
+ IN CONST UINT64 ImageSize,
+ IN CONST UINT32 *RequiredAlignment OPTIONAL,
+ OUT IMAGE_PROPERTIES_RECORD *ImageRecord
+ )
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
+ UINTN Index;
+ UINT8 *Name;
+ UINT32 SectionAlignment;
+ UINT32 PeCoffHeaderOffset;
+
+ if ((ImageRecord == NULL) || (ImageBase == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "Creating Image Properties Record: 0x%016lx - 0x%016lx\n",
+ (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase,
+ ImageSize
+ ));
+
+ //
+ // Step 1: record whole region
+ //
+ Status = EFI_SUCCESS;
+ ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
+ ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase;
+ ImageRecord->ImageSize = ImageSize;
+ ImageRecord->CodeSegmentCount = 0;
+ InitializeListHead (&ImageRecord->Link);
+ InitializeListHead (&ImageRecord->CodeSegmentList);
+
+ // Check PE/COFF image
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageBase;
+ PeCoffHeaderOffset = 0;
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ PeCoffHeaderOffset = DosHdr->e_lfanew;
+ }
+
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageBase + PeCoffHeaderOffset);
+ if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Get SectionAlignment
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
+ } else {
+ SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;
+ }
+
+ // Check RequiredAlignment
+ if ((RequiredAlignment != NULL) && ((SectionAlignment & (*RequiredAlignment - 1)) != 0)) {
+ DEBUG ((
+ DEBUG_WARN,
+ "!!!!!!!! Image Section Alignment(0x%x) does not match Required Alignment (0x%x) !!!!!!!!\n",
+ SectionAlignment,
+ *RequiredAlignment
+ ));
+
+ return EFI_ABORTED;
+ }
+
+ Section = (EFI_IMAGE_SECTION_HEADER *)(
+ (UINT8 *)(UINTN)ImageBase +
+ PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader
+ );
+ for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
+ Name = Section[Index].Name;
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " Section - '%c%c%c%c%c%c%c%c'\n",
+ Name[0],
+ Name[1],
+ Name[2],
+ Name[3],
+ Name[4],
+ Name[5],
+ Name[6],
+ Name[7]
+ ));
+
+ if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {
+ DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));
+ DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));
+ DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));
+ DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));
+ DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));
+ DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));
+ DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));
+ DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));
+ DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics));
+
+ // Record code section(s)
+ ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));
+ if (ImageRecordCodeSection == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
+
+ ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageBase + Section[Index].VirtualAddress;
+ ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;
+
+ InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);
+ ImageRecord->CodeSegmentCount++;
+ }
+ }
+
+ if (ImageRecord->CodeSegmentCount > 0) {
+ SortImageRecordCodeSection (ImageRecord);
+ }
+
+ return Status;
+}
+
+/**
+ Deleted an image properties record. The function will also call
+ RemoveEntryList() on each code segment and the input ImageRecord before
+ freeing each pool.
+
+ @param[in] ImageRecord The IMAGE_PROPERTIES_RECORD to delete
+**/
+VOID
+EFIAPI
+DeleteImagePropertiesRecord (
+ IN IMAGE_PROPERTIES_RECORD *ImageRecord
+ )
+{
+ LIST_ENTRY *CodeSegmentListHead;
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
+
+ if (ImageRecord == NULL) {
+ return;
+ }
+
+ CodeSegmentListHead = &ImageRecord->CodeSegmentList;
+ while (!IsListEmpty (CodeSegmentListHead)) {
+ ImageRecordCodeSection = CR (
+ CodeSegmentListHead->ForwardLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+ RemoveEntryList (&ImageRecordCodeSection->Link);
+ FreePool (ImageRecordCodeSection);
+ }
+
+ if (!IsListEmpty (&ImageRecord->Link)) {
+ RemoveEntryList (&ImageRecord->Link);
+ }
+
+ FreePool (ImageRecord);
+}
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
index 90e6a262463c..99e030c988f3 100644
--- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -155,4 +155,43 @@ DumpImageRecord (
IN LIST_ENTRY *ImageRecordList
);
+/**
+ Creates an IMAGE_PROPERTIES_RECORD from a loaded PE image. The PE/COFF header will be found
+ and parsed to determine the number of code segments and their base addresses and sizes.
+
+ @param[in] ImageBase Base of the PE image
+ @param[in] ImageSize Size of the PE image
+ @param[in] RequiredAlignment If non-NULL, the alignment specified in the PE/COFF header
+ will be compared against this value.
+ @param[out] ImageRecord On out, a populated image properties record
+
+ @retval EFI_INVALID_PARAMETER This function ImageBase or ImageRecord was NULL, or the
+ image located at ImageBase was not a valid PE/COFF image
+ @retval EFI_OUT_OF_RESOURCES Failure to Allocate()
+ @retval EFI_ABORTED The input Alignment was non-NULL and did not match the
+ alignment specified in the PE/COFF header
+ @retval EFI_SUCCESS The image properties record was successfully created
+**/
+EFI_STATUS
+EFIAPI
+CreateImagePropertiesRecord (
+ IN CONST VOID *ImageBase,
+ IN CONST UINT64 ImageSize,
+ IN CONST UINT32 *Alignment OPTIONAL,
+ OUT IMAGE_PROPERTIES_RECORD *ImageRecord
+ );
+
+/**
+ Deleted an image properties record. The function will also call
+ RemoveEntryList() on each code segment and the input ImageRecord before
+ freeing each pool.
+
+ @param[in] ImageRecord The IMAGE_PROPERTIES_RECORD to delete
+**/
+VOID
+EFIAPI
+DeleteImagePropertiesRecord (
+ IN IMAGE_PROPERTIES_RECORD *ImageRecord
+ );
+
#endif
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
index 4c1466fc3336..cfe0c04b3b05 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
@@ -23,6 +23,7 @@ [LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
+ MemoryAllocationLib
[Packages]
MdePkg/MdePkg.dec
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107209): https://edk2.groups.io/g/devel/message/107209
Mute This Topic: https://groups.io/mt/100342608/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 13/14] MdeModulePkg: Update Function Headers in ImagePropertiesRecordLib
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (11 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 12/14] MdeModulePkg: Add Logic to Create/Delete Image Properties Records Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 14/14] MdeModulePkg: Update DumpImageRecord() " Taylor Beebe
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Update function headers to clarify the contract of each function and
improve readability.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 220 ++++++++++----------
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 114 +++++-----
2 files changed, 162 insertions(+), 172 deletions(-)
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index 9ac3afdaa202..0c96e4220964 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -23,14 +23,13 @@
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
/**
- Converts a number of EFI_PAGEs to a size in bytes.
+ Converts a number of 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.
+ @param[in] Pages The number of EFI_PAGES.
- @return The number of bytes associated with the number of EFI_PAGEs specified
- by Pages.
+ @retval The number of bytes associated with the input number of pages.
**/
STATIC
UINT64
@@ -46,10 +45,9 @@ EfiPagesToSize (
NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
- @param Size A size in bytes.
+ @param[in] Size A size in bytes.
- @return The number of EFI_PAGESs associated with the number of bytes specified
- by Size.
+ @retval The number of pages associated with the input number of bytes.
**/
STATIC
@@ -62,12 +60,12 @@ EfiSizeToPages (
}
/**
- Sort memory map entries based upon PhysicalStart, from low to high.
+ 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_MEMORY_DESCRIPTOR.
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.
+ @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
**/
STATIC
VOID
@@ -106,11 +104,12 @@ SortMemoryMap (
/**
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
+ @param[in] Buffer Starting Address
+ @param[in] Length Length to check
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries to check against
+ the memory range Buffer -> Buffer + Length
- @return first image record covered by [buffer, length]
+ @retval The first image record covered by [Buffer, Length]
**/
STATIC
IMAGE_PROPERTIES_RECORD *
@@ -145,17 +144,19 @@ GetImageRecordByAddress (
}
/**
- Set the memory map to new entries, according to one old entry,
- based upon PE code section and data section in image record
+ Break up the input OldRecord into multiple new records based on the code
+ and data sections in the input ImageRecord.
- @param ImageRecord An image record whose [ImageBase, ImageSize] covered
- by old memory map entry.
- @param NewRecord A pointer to several new memory map entries.
- The caller gurantee the buffer size be 1 +
- (SplitRecordCount * DescriptorSize) calculated
- below.
- @param OldRecord A pointer to one old memory map entry.
- @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+ @param[in] ImageRecord An IMAGE_PROPERTIES_RECORD whose ImageBase and
+ ImageSize is covered by by OldRecord.
+ @param[in, out] NewRecord A pointer to several new memory map entries.
+ The caller gurantee the buffer size be 1 +
+ (SplitRecordCount * DescriptorSize) calculated
+ below.
+ @param[in] OldRecord A pointer to one old memory map entry.
+ @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+
+ @retval The number of new descriptors created.
**/
STATIC
UINTN
@@ -245,16 +246,16 @@ SetNewRecord (
}
/**
- Return the max number of new splitted entries, according to one old entry,
- based upon PE code section and data section.
+ Return the maximum number of new entries required to describe the code and data sections
+ of all images covered by the input OldRecord.
- @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 memory range described in
- the existing EFI memory map descriptor OldRecord
+ @param[in] OldRecord A pointer to one old memory map entry.
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
+ for an image record contained by the memory range described by
+ OldRecord
- @retval 0 no entry need to be splitted.
- @return the max number of new splitted entries
+ @retval The maximum number of new descriptors required to describe the code and data sections
+ of all images covered by OldRecord.
**/
STATIC
UINTN
@@ -290,22 +291,20 @@ GetMaxSplitRecordCount (
}
/**
- Split the memory map to new entries, according to one old entry,
- based upon PE code section and data section.
+ Split the memory map into new entries based upon the PE code and data sections
+ in ImageRecordList covered by the input OldRecord.
- @param OldRecord A pointer to one old memory map entry.
- @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 entries used when searching
- for an image record contained by the memory range described in
- the existing EFI memory map descriptor OldRecord
+ @param[in] OldRecord A pointer to one old memory map entry.
+ @param[in, out] NewRecord A pointer to several new memory map entries.
+ The caller gurantee the buffer size be
+ (SplitRecordCount * DescriptorSize).
+ @param[in] MaxSplitRecordCount The maximum number of entries post-split.
+ @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
+ for an image record contained by the memory range described in
+ the existing EFI memory map descriptor OldRecord
- @retval 0 no entry is splitted.
- @return the real number of splitted record.
+ @retval The number of split entries.
**/
STATIC
UINTN
@@ -403,54 +402,42 @@ SplitRecord (
}
/**
- 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.
+ Split the original memory map and add more entries to describe PE code
+ and data sections for each image in the input ImageRecordList.
- NOTE: It assumes PE code/data section are page aligned.
- NOTE: It assumes enough entry is prepared for new memory map.
+ NOTE: This function assumes PE code/data section are page aligned.
+ NOTE: This function assumes there are enough entries for the new memory map.
- Split table:
- +---------------+
- | Record X |
- +---------------+
- | Record RtCode |
- +---------------+
- | Record Y |
- +---------------+
- ==>
- +---------------+
- | Record X |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF1
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF2
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record Y |
- +---------------+
+ | | | | | | | |
+ | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE |
+ | | | | | | | |
+ Assume the above memory region is the result of one split memory map descriptor. It's unlikely
+ that a linker will orient an image this way, but the caller must assume the worst case scenario.
+ This image layout example contains code sections oriented in a way that maximizes the number of
+ descriptors which would be required to describe each section. To ensure we have enough space
+ for every descriptor of the broken up memory map, the caller must assume that every image will
+ have the maximum number of code sections oriented in a way which maximizes the number of data
+ sections with unrelated memory regions flanking each image within a single descriptor.
- @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 MemoryMapSize +
- (AdditionalRecordCount * DescriptorSize) 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_RECORD 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.
+ Given an image record list, the caller should use the following formula when allocating extra descriptors:
+ NumberOfAdditionalDescriptors = (MemoryMapSize / DescriptorSize) +
+ ((2 * <Most Code Segments in a Single Image> + 3) * <Number of Images>)
+
+ @param[in, out] MemoryMapSize IN: The size, in bytes, of the old memory map before the split.
+ OUT: The size, in bytes, of the used descriptors of the split
+ memory map
+ @param[in, out] MemoryMap IN: A pointer to the buffer containing the current memory map.
+ This buffer must have enough space to accomodate the "worst case"
+ scenario where every image in ImageRecordList needs a new descriptor
+ to describe its code and data sections.
+ OUT: A pointer to the updated memory map with separated image section
+ descriptors.
+ @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
+ for an image record contained by the memory range described in
+ EFI memory map descriptors.
+ @param[in] NumberOfAdditionalDescriptors The number of unused descriptors at the end of the input MemoryMap.
+ The formula in the description should be used to calculate this value.
**/
VOID
EFIAPI
@@ -523,10 +510,10 @@ SplitTable (
}
/**
- Swap two code sections in image record.
+ Swap two code sections in a single IMAGE_PROPERTIES_RECORD.
- @param FirstImageRecordCodeSection first code section in image record
- @param SecondImageRecordCodeSection second code section in image record
+ @param[in] FirstImageRecordCodeSection The first code section
+ @param[in] SecondImageRecordCodeSection The second code section
**/
STATIC
VOID
@@ -548,9 +535,9 @@ SwapImageRecordCodeSection (
}
/**
- Sort code section in image record, based upon CodeSegmentBase from low to high.
+ Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high.
- @param ImageRecord image record to be sorted
+ @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be sorted
**/
VOID
EFIAPI
@@ -597,12 +584,15 @@ SortImageRecordCodeSection (
}
/**
- Check if code section in image record is valid.
+ Check if the code sections in the input ImageRecord are valid.
+ The code sections are valid if they don't overlap, are contained
+ within the the ImageRecord's ImageBase and ImageSize, and are
+ contained within the MAX_ADDRESS.
- @param ImageRecord image record to be checked
+ @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked
- @retval TRUE image record is valid
- @retval FALSE image record is invalid
+ @retval TRUE The code sections in the input ImageRecord are valid
+ @retval FALSE The code sections in the input ImageRecord are invalid
**/
BOOLEAN
EFIAPI
@@ -662,8 +652,8 @@ IsImageRecordCodeSectionValid (
/**
Swap two image records.
- @param FirstImageRecord first image record.
- @param SecondImageRecord second image record.
+ @param[in] FirstImageRecord The first image record.
+ @param[in] SecondImageRecord The second image record.
**/
STATIC
VOID
@@ -690,9 +680,9 @@ SwapImageRecord (
}
/**
- Sort image record based upon the ImageBase from low to high.
+ Sort the input ImageRecordList based upon the ImageBase from low to high.
- @param ImageRecordList Image record list to be sorted
+ @param[in] ImageRecordList Image record list to be sorted
**/
VOID
EFIAPI
@@ -739,7 +729,10 @@ SortImageRecord (
/**
Dump image record.
- @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
+/**
+ Debug dumps the input list of IMAGE_PROPERTIES_RECORD structs
+
+ @param[in] ImageRecordList Head of the IMAGE_PROPERTIES_RECORD list
**/
VOID
EFIAPI
@@ -766,13 +759,16 @@ DumpImageRecord (
}
/**
- Find image record according to image base and size.
+ Find image properties record according to image base and size in the
+ input ImageRecordList.
- @param ImageBase Base of PE image
- @param ImageSize Size of PE image
- @param ImageRecordList Image record list to be searched
+ @param[in] ImageBase Base of PE image
+ @param[in] ImageSize Size of PE image
+ @param[in] ImageRecordList Image record list to be searched
- @return image record
+ @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase
+ and ImageSize in the input ImageRecordList
+ @retval Other The found IMAGE_PROPERTIES_RECORD
**/
IMAGE_PROPERTIES_RECORD *
EFIAPI
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
index 99e030c988f3..107255d9e16d 100644
--- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -32,54 +32,42 @@ typedef struct {
} 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.
+ Split the original memory map and add more entries to describe PE code
+ and data sections for each image in the input ImageRecordList.
- NOTE: It assumes PE code/data section are page aligned.
- NOTE: It assumes enough entry is prepared for new memory map.
+ NOTE: This function assumes PE code/data section are page aligned.
+ NOTE: This function assumes there are enough entries for the new memory map.
- Split table:
- +---------------+
- | Record X |
- +---------------+
- | Record RtCode |
- +---------------+
- | Record Y |
- +---------------+
- ==>
- +---------------+
- | Record X |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF1
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record RtData | |
- +---------------+ |
- | Record RtCode | |-> PE/COFF2
- +---------------+ |
- | Record RtData | |
- +---------------+ ----
- | Record Y |
- +---------------+
+ | | | | | | | |
+ | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE |
+ | | | | | | | |
+ Assume the above memory region is the result of one split memory map descriptor. It's unlikely
+ that a linker will orient an image this way, but the caller must assume the worst case scenario.
+ This image layout example contains code sections oriented in a way that maximizes the number of
+ descriptors which would be required to describe each section. To ensure we have enough space
+ for every descriptor of the broken up memory map, the caller must assume that every image will
+ have the maximum number of code sections oriented in a way which maximizes the number of data
+ sections with unrelated memory regions flanking each image within a single descriptor.
- @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 MemoryMapSize +
- (AdditionalRecordCount * DescriptorSize) 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_RECORD 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.
+ Given an image record list, the caller should use the following formula when allocating extra descriptors:
+ NumberOfAdditionalDescriptors = (MemoryMapSize / DescriptorSize) +
+ ((2 * <Most Code Segments in a Single Image> + 3) * <Number of Images>)
+
+ @param[in, out] MemoryMapSize IN: The size, in bytes, of the old memory map before the split.
+ OUT: The size, in bytes, of the used descriptors of the split
+ memory map
+ @param[in, out] MemoryMap IN: A pointer to the buffer containing the current memory map.
+ This buffer must have enough space to accomodate the "worst case"
+ scenario where every image in ImageRecordList needs a new descriptor
+ to describe its code and data sections.
+ OUT: A pointer to the updated memory map with separated image section
+ descriptors.
+ @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
+ for an image record contained by the memory range described in
+ EFI memory map descriptors.
+ @param[in] NumberOfAdditionalDescriptors The number of unused descriptors at the end of the input MemoryMap.
+ The formula in the description should be used to calculate this value.
**/
VOID
EFIAPI
@@ -92,9 +80,9 @@ SplitTable (
);
/**
- Sort code section in image record, based upon CodeSegmentBase from low to high.
+ Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high.
- @param ImageRecord image record to be sorted
+ @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be sorted
**/
VOID
EFIAPI
@@ -103,12 +91,15 @@ SortImageRecordCodeSection (
);
/**
- Check if code section in image record is valid.
+ Check if the code sections in the input ImageRecord are valid.
+ The code sections are valid if they don't overlap, are contained
+ within the the ImageRecord's ImageBase and ImageSize, and are
+ contained within the MAX_ADDRESS.
- @param ImageRecord image record to be checked
+ @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked
- @retval TRUE image record is valid
- @retval FALSE image record is invalid
+ @retval TRUE The code sections in the input ImageRecord are valid
+ @retval FALSE The code sections in the input ImageRecord are invalid
**/
BOOLEAN
EFIAPI
@@ -117,9 +108,9 @@ IsImageRecordCodeSectionValid (
);
/**
- Sort image record based upon the ImageBase from low to high.
+ Sort the input ImageRecordList based upon the ImageBase from low to high.
- @param ImageRecordList Image record list to be sorted
+ @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
**/
VOID
EFIAPI
@@ -128,13 +119,16 @@ SortImageRecord (
);
/**
- Find image record according to image base and size.
+ Find image properties record according to image base and size in the
+ input ImageRecordList.
- @param ImageBase Base of PE image
- @param ImageSize Size of PE image
- @param ImageRecordList Image record list to be searched
+ @param[in] ImageBase Base of PE image
+ @param[in] ImageSize Size of PE image
+ @param[in] ImageRecordList Image record list to be searched
- @return image record
+ @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase
+ and ImageSize in the input ImageRecordList
+ @retval Other The found IMAGE_PROPERTIES_RECORD
**/
IMAGE_PROPERTIES_RECORD *
EFIAPI
@@ -145,9 +139,9 @@ FindImageRecord (
);
/**
- Dump image record.
+ DEBUG dump the input ImageRecordList.
- @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries
+ @param[in] ImageRecordList Head of the IMAGE_PROPERTIES_RECORD list
**/
VOID
EFIAPI
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107210): https://edk2.groups.io/g/devel/message/107210
Mute This Topic: https://groups.io/mt/100342609/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [edk2-devel] [PATCH v3 14/14] MdeModulePkg: Update DumpImageRecord() in ImagePropertiesRecordLib
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
` (12 preceding siblings ...)
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 13/14] MdeModulePkg: Update Function Headers in ImagePropertiesRecordLib Taylor Beebe
@ 2023-07-25 1:35 ` Taylor Beebe
13 siblings, 0 replies; 15+ messages in thread
From: Taylor Beebe @ 2023-07-25 1:35 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Dandan Bi
Update DumpImageRecord() to be DumpImageRecords(), and improve
the debug output. The function will output at DEBUG_INFO instead,
and the function will be run in DXE and SMM
MAT logic when the MAT is installed at EndOfDxe on DEBUG builds.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 9 ++
MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c | 11 +-
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c | 131 +++++++++++++++++---
MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h | 2 +-
MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf | 1 +
MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 1 +
6 files changed, 133 insertions(+), 22 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index 993db281062a..e9343a2c4ef1 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -284,6 +284,15 @@ InstallMemoryAttributesTableOnEndOfDxe (
{
mMemoryAttributesTableEndOfDxe = TRUE;
InstallMemoryAttributesTable ();
+
+ DEBUG_CODE_BEGIN ();
+ if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
+ DEBUG ((DEBUG_INFO, "DXE - Total Runtime Image Count: 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
+ DEBUG ((DEBUG_INFO, "DXE - Dump Runtime Image Records:\n"));
+ DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
+ }
+
+ DEBUG_CODE_END ();
}
/**
diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
index 03de9b2c5fff..28fe74ecc421 100644
--- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
@@ -496,9 +496,14 @@ SmmInstallMemoryAttributesTable (
return EFI_SUCCESS;
}
- DEBUG ((DEBUG_VERBOSE, "SMM Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
- DEBUG ((DEBUG_VERBOSE, "SMM Dump ImageRecord:\n"));
- DumpImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
+ DEBUG_CODE_BEGIN ();
+ if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
+ DEBUG ((DEBUG_INFO, "SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
+ DEBUG ((DEBUG_INFO, "SMM - Dump Runtime Image Records:\n"));
+ DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
+ }
+
+ DEBUG_CODE_END ();
PublishMemoryAttributesTable ();
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
index 0c96e4220964..b025c9485c6c 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c
@@ -14,6 +14,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/ImagePropertiesRecordLib.h>
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
@@ -727,34 +728,128 @@ SortImageRecord (
}
/**
- Dump image record.
+ Extract the .efi filename out of the input PDB.
+
+ @param[in] PdbPointer Pointer to the PDB file path.
+ @param[out] EfiFileName Pointer to the .efi filename.
+ @param[in] EfiFileNameSize Size of the .efi filename buffer.
+**/
+STATIC
+VOID
+GetFilename (
+ IN CHAR8 *PdbPointer,
+ OUT CHAR8 *EfiFileName,
+ IN UINTN EfiFileNameSize
+ )
+{
+ UINTN Index;
+ UINTN StartIndex;
+
+ if ((PdbPointer == NULL) || (EfiFileNameSize < 5)) {
+ return;
+ }
+
+ // Print Module Name by Pdb file path.
+ StartIndex = 0;
+ for (Index = 0; PdbPointer[Index] != 0; Index++) {
+ if ((PdbPointer[Index] == '\\') || (PdbPointer[Index] == '/')) {
+ StartIndex = Index + 1;
+ }
+ }
+
+ // Copy the PDB file name to EfiFileName and replace .pdb with .efi
+ for (Index = 0; Index < EfiFileNameSize - 4; Index++) {
+ EfiFileName[Index] = PdbPointer[Index + StartIndex];
+ if (EfiFileName[Index] == 0) {
+ EfiFileName[Index] = '.';
+ }
+
+ if (EfiFileName[Index] == '.') {
+ EfiFileName[Index + 1] = 'e';
+ EfiFileName[Index + 2] = 'f';
+ EfiFileName[Index + 3] = 'i';
+ EfiFileName[Index + 4] = 0;
+ break;
+ }
+ }
+
+ if (Index == sizeof (EfiFileName) - 4) {
+ EfiFileName[Index] = 0;
+ }
+}
/**
- Debug dumps the input list of IMAGE_PROPERTIES_RECORD structs
+ Debug dumps the input list of IMAGE_PROPERTIES_RECORD structs.
@param[in] ImageRecordList Head of the IMAGE_PROPERTIES_RECORD list
**/
VOID
EFIAPI
-DumpImageRecord (
+DumpImageRecords (
IN LIST_ENTRY *ImageRecordList
)
{
- IMAGE_PROPERTIES_RECORD *ImageRecord;
- LIST_ENTRY *ImageRecordLink;
- UINTN Index;
-
- for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
- ImageRecordLink != ImageRecordList;
- ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
- {
- ImageRecord = CR (
- ImageRecordLink,
- IMAGE_PROPERTIES_RECORD,
- Link,
- IMAGE_PROPERTIES_RECORD_SIGNATURE
- );
- DEBUG ((DEBUG_VERBOSE, "Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));
+ LIST_ENTRY *ImageRecordLink;
+ IMAGE_PROPERTIES_RECORD *CurrentImageRecord;
+ LIST_ENTRY *CodeSectionLink;
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION *CurrentCodeSection;
+ CHAR8 *PdbPointer;
+ CHAR8 EfiFileName[256];
+
+ if (ImageRecordList == NULL) {
+ return;
+ }
+
+ ImageRecordLink = ImageRecordList->ForwardLink;
+
+ while (ImageRecordLink != ImageRecordList) {
+ CurrentImageRecord = CR (
+ ImageRecordLink,
+ IMAGE_PROPERTIES_RECORD,
+ Link,
+ IMAGE_PROPERTIES_RECORD_SIGNATURE
+ );
+
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)CurrentImageRecord->ImageBase);
+ if (PdbPointer != NULL) {
+ GetFilename (PdbPointer, EfiFileName, sizeof (EfiFileName));
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: 0x%llx - 0x%llx\n",
+ EfiFileName,
+ CurrentImageRecord->ImageBase,
+ CurrentImageRecord->ImageBase + CurrentImageRecord->ImageSize
+ ));
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "Unknown Image: 0x%llx - 0x%llx\n",
+ CurrentImageRecord->ImageBase,
+ CurrentImageRecord->ImageBase + CurrentImageRecord->ImageSize
+ ));
+ }
+
+ CodeSectionLink = CurrentImageRecord->CodeSegmentList.ForwardLink;
+
+ while (CodeSectionLink != &CurrentImageRecord->CodeSegmentList) {
+ CurrentCodeSection = CR (
+ CodeSectionLink,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION,
+ Link,
+ IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
+ );
+
+ DEBUG ((
+ DEBUG_INFO,
+ " Code Section: 0x%llx - 0x%llx\n",
+ CurrentCodeSection->CodeSegmentBase,
+ CurrentCodeSection->CodeSegmentBase + CurrentCodeSection->CodeSegmentSize
+ ));
+
+ CodeSectionLink = CodeSectionLink->ForwardLink;
+ }
+
+ ImageRecordLink = ImageRecordLink->ForwardLink;
}
}
diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
index 107255d9e16d..5ce38bcb3f83 100644
--- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
+++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h
@@ -145,7 +145,7 @@ FindImageRecord (
**/
VOID
EFIAPI
-DumpImageRecord (
+DumpImageRecords (
IN LIST_ENTRY *ImageRecordList
);
diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
index cfe0c04b3b05..1f82cc3e469c 100644
--- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
@@ -24,6 +24,7 @@ [LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
+ PeCoffGetEntryPointLib
[Packages]
MdePkg/MdePkg.dec
diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
index 2b8cbb867a73..198cdd814fb9 100644
--- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
+++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
@@ -57,6 +57,7 @@ [Components]
MdeModulePkg/Library/ImagePropertiesRecordLib/UnitTest/ImagePropertiesRecordLibUnitTestHost.inf {
<LibraryClasses>
ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
}
#
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107211): https://edk2.groups.io/g/devel/message/107211
Mute This Topic: https://groups.io/mt/100342610/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 15+ messages in thread
end of thread, other threads:[~2023-07-25 1:35 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-25 1:34 [edk2-devel] [PATCH v3 00/14] Add ImagePropertiesRecordLib and Fix MAT Bugs Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 01/14] MdeModulePkg: Add ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 02/14] ArmVirtPkg: Add ImagePropertiesRecordLib Instance Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 03/14] EmulatorPkg: " Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 04/14] OvmfPkg: " Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 05/14] UefiPayloadPkg: " Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 06/14] MdeModulePkg: Update MemoryAttributesTable.c to Reduce Global Variable Use Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 07/14] MdeModulePkg: Move Some DXE MAT Logic to ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 08/14] MdeModulePkg: Add ImagePropertiesRecordLib Host-Based Unit Test Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 09/14] MdeModulePkg: Fix Bugs in MAT Logic Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 10/14] UefiCpuPkg: Use Attribute From SMM MemoryAttributesTable if Nonzero Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 11/14] MdeModulePkg: Transition SMM MAT Logic to Use ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 12/14] MdeModulePkg: Add Logic to Create/Delete Image Properties Records Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 13/14] MdeModulePkg: Update Function Headers in ImagePropertiesRecordLib Taylor Beebe
2023-07-25 1:35 ` [edk2-devel] [PATCH v3 14/14] MdeModulePkg: Update DumpImageRecord() " Taylor Beebe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox