diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
index f3c3951ac5..42b49a82bb 100644
--- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
+++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
@@ -46,3 +46,4 @@
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask
+ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX
diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c
index 11b8237599..bde745ff38 100644
--- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c
+++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c
@@ -126,7 +126,7 @@ InternalVerifySections (
// Verify the Image section adheres to the W^X principle, if the policy
// demands it.
//
- if (PcdGetBool (PcdImageLoaderWXorX)) {
+ if (PcdGetBool (PcdImageLoaderWXorX) && !PcdGetBool (PcdImageLoaderRemoveXForWX)) {
if ((Sections[SectionIndex].Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) == (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) {
DEBUG_RAISE ();
return RETURN_VOLUME_CORRUPTED;
diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
index e3684fe922..a533706604 100644
--- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
+++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
@@ -39,3 +39,4 @@
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask
+ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX
diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c
index 678c6b2b5a..683ee0a9af 100644
--- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c
+++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c
@@ -37,6 +37,10 @@ InternalCharacteristicsToAttributes (
{
UINT32 Attributes;
+ if (PcdGetBool (PcdImageLoaderRemoveXForWX) && (Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) == (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) {
+ Characteristics &= ~EFI_IMAGE_SCN_MEM_EXECUTE;
+ }
+
Attributes = 0;
if ((Characteristics & EFI_IMAGE_SCN_MEM_READ) == 0) {
Attributes |= EFI_MEMORY_RP;
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 98391bfefe..257841d492 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -2363,6 +2363,15 @@
# @Prompt Allow Misaligned Offset.
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|FALSE|BOOLEAN|0x40001020
+ ## Indicates whether Image sections that do not adhere to the W^X principle
+ # by mistake will have their X permission removed at load time.
+ # TRUE - Image sections with WX permissions will have X permission removed.
+ # FALSE - Image sections with WX permissions will be treated by PcdImageLoaderWXorX.
+ # This feature is only useful for images created by old Apple mtoc utility. Do not enable
+ # it unless such images need to be supported.
+ # @Prompt Remove X permission from WX sections.
+ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX|FALSE|BOOLEAN|0x40001021
+
[PcdsFixedAtBuild,PcdsPatchableInModule]
## Indicates the maximum length of unicode string used in the following
# BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()