diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
index 61f01bf5380..23634a9d9c9 100644
--- a/bfd/elf-properties.c
+++ b/bfd/elf-properties.c
@@ -177,6 +177,20 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
 	      prop->pr_kind = property_number;
 	      goto next;
 
+	    case GNU_PROPERTY_MEMORY_SEAL:
+	      if (datasz != 0)
+		{
+		  _bfd_error_handler
+		    (_("warning: %pB: corrupt memory sealing size: 0x%x"),
+		     abfd, datasz);
+		  /* Clear all properties.  */
+		  elf_properties (abfd) = NULL;
+		  return false;
+		}
+	      prop = _bfd_elf_get_property (abfd, type, datasz);
+	      prop->pr_kind = property_number;
+	      goto next;
+
 	    default:
 	      if ((type >= GNU_PROPERTY_UINT32_AND_LO
 		   && type <= GNU_PROPERTY_UINT32_AND_HI)
@@ -254,6 +268,7 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd,
       /* FALLTHROUGH */
 
     case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+    case GNU_PROPERTY_MEMORY_SEAL:
       /* Return TRUE if APROP is NULL to indicate that BPROP should
 	 be added to ABFD.  */
       return aprop == NULL;
@@ -607,6 +622,33 @@ elf_write_gnu_properties (struct bfd_link_info *info,
     }
 }
 
+static asection *
+_bfd_elf_link_create_gnu_property_sec (struct bfd_link_info *info, bfd *elf_bfd,
+				       unsigned int elfclass)
+{
+  asection *sec;
+
+  sec = bfd_make_section_with_flags (elf_bfd,
+				     NOTE_GNU_PROPERTY_SECTION_NAME,
+				     (SEC_ALLOC
+				      | SEC_LOAD
+				      | SEC_IN_MEMORY
+				      | SEC_READONLY
+				      | SEC_HAS_CONTENTS
+				      | SEC_DATA));
+  if (sec == NULL)
+    info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
+
+  if (!bfd_set_section_alignment (sec,
+				  elfclass == ELFCLASS64 ? 3 : 2))
+    info->callbacks->einfo (_("%F%pA: failed to align section\n"),
+			    sec);
+
+  elf_section_type (sec) = SHT_NOTE;
+  return sec;
+}
+
+
 /* Set up GNU properties.  Return the first relocatable ELF input with
    GNU properties if found.  Otherwise, return NULL.  */
 
@@ -656,23 +698,7 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
       /* Support -z indirect-extern-access.  */
       if (first_pbfd == NULL)
 	{
-	  sec = bfd_make_section_with_flags (elf_bfd,
-					     NOTE_GNU_PROPERTY_SECTION_NAME,
-					     (SEC_ALLOC
-					      | SEC_LOAD
-					      | SEC_IN_MEMORY
-					      | SEC_READONLY
-					      | SEC_HAS_CONTENTS
-					      | SEC_DATA));
-	  if (sec == NULL)
-	    info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
-
-	  if (!bfd_set_section_alignment (sec,
-					  elfclass == ELFCLASS64 ? 3 : 2))
-	    info->callbacks->einfo (_("%F%pA: failed to align section\n"),
-				    sec);
-
-	  elf_section_type (sec) = SHT_NOTE;
+	  sec = _bfd_elf_link_create_gnu_property_sec (info, elf_bfd, elfclass);
 	  first_pbfd = elf_bfd;
 	  has_properties = true;
 	}
@@ -690,6 +716,31 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
 	  |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
     }
 
+  if (elf_bfd != NULL)
+    {
+      if (info->memory_seal)
+	{
+	  /* Support -z no-memory-seal.  */
+	  if (first_pbfd == NULL)
+	    {
+	      sec = _bfd_elf_link_create_gnu_property_sec (info, elf_bfd, elfclass);
+	      first_pbfd = elf_bfd;
+	      has_properties = true;
+	    }
+
+	  p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_MEMORY_SEAL, 0);
+	  if (p->pr_kind == property_unknown)
+	    {
+	      /* Create GNU_PROPERTY_NO_MEMORY_SEAL.  */
+	      p->u.number = GNU_PROPERTY_MEMORY_SEAL;
+	      p->pr_kind = property_number;
+	    }
+	}
+      else
+	elf_find_and_remove_property (&elf_properties (elf_bfd),
+				      GNU_PROPERTY_MEMORY_SEAL, true);
+    }
+
   /* Do nothing if there is no .note.gnu.property section.  */
   if (!has_properties)
     return NULL;
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 60e81f518a7..7c164e9c131 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -4892,7 +4892,8 @@ _bfd_x86_elf_link_fixup_gnu_properties
   for (p = *listp; p; p = p->next)
     {
       unsigned int type = p->property.pr_type;
-      if (type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
+      if (type == GNU_PROPERTY_MEMORY_SEAL
+	  || type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
 	  || type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
 	  || (type >= GNU_PROPERTY_X86_UINT32_AND_LO
 	      && type <= GNU_PROPERTY_X86_UINT32_AND_HI)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 4f8f879cf91..0f29b65fe30 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -21476,6 +21476,12 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
 		printf (_("<corrupt length: %#x> "), datasz);
 	      goto next;
 
+	    case GNU_PROPERTY_MEMORY_SEAL:
+	      printf ("memory seal ");
+	      if (datasz)
+		printf (_("<corrupt length: %#x> "), datasz);
+	      goto next;
+
 	    default:
 	      if ((type >= GNU_PROPERTY_UINT32_AND_LO
 		   && type <= GNU_PROPERTY_UINT32_AND_HI)
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 85e7da84406..ae451075996 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -429,6 +429,9 @@ struct bfd_link_info
   /* TRUE if only one read-only, non-code segment should be created.  */
   unsigned int one_rosegment: 1;
 
+  /* TRUE if GNU_PROPERTY_MEMORY_SEAL should be generated.  */
+  unsigned int memory_seal: 1;
+
   /* Nonzero if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment
      should be created.  1 for DWARF2 tables, 2 for compact tables.  */
   unsigned int eh_frame_hdr_type: 2;
diff --git a/include/elf/common.h b/include/elf/common.h
index 6077db7a8b7..2e2c486bf8d 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -890,6 +890,7 @@
 /* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).  */
 #define GNU_PROPERTY_STACK_SIZE			1
 #define GNU_PROPERTY_NO_COPY_ON_PROTECTED	2
+#define GNU_PROPERTY_MEMORY_SEAL		3
 
 /* A 4-byte unsigned integer property: A bit is set if it is set in all
    relocatable inputs.  */
diff --git a/ld/NEWS b/ld/NEWS
index 4a19f5a7d5d..5d5fec4aed3 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -33,6 +33,9 @@ Changes in 2.43:
 
 * Add -plugin-save-temps to store plugin intermediate files permanently.
 
+* Add -z memory-seal/-z nomemory-seal options to ELF linker to mark the
+  object to memory sealed.
+
 Changes in 2.42:
 
 * Add -z mark-plt/-z nomark-plt options to x86-64 ELF linker to mark PLT
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index 4d431995d2e..9a14eae749e 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -1083,6 +1083,10 @@ fragment <<EOF
 	link_info.combreloc = false;
       else if (strcmp (optarg, "nocopyreloc") == 0)
 	link_info.nocopyreloc = true;
+      else if (strcmp (optarg, "memory-seal") == 0)
+       link_info.memory_seal = true;
+      else if (strcmp (optarg, "nomemory-seal") == 0)
+       link_info.memory_seal = false;
 EOF
 if test -n "$COMMONPAGESIZE"; then
 fragment <<EOF
diff --git a/ld/ld.texi b/ld/ld.texi
index da714a20855..d3d9f32d8f3 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1590,6 +1590,14 @@ Disable relocation overflow check.  This can be used to disable
 relocation overflow check if there will be no dynamic relocation
 overflow at run-time.  Supported for x86_64.
 
+@item memory-seal
+@item nomemory-seal
+Instruct the executable or shared library that the all PT_LOAD segments
+should be sealed to avoid further manipulation (such as changing the
+protection flags, the segment size, or remove the mapping).
+This is a security hardening that requires system support.  This
+generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section
+
 @item now
 When generating an executable or shared library, mark it to tell the
 dynamic linker to resolve all symbols when the program is started, or
diff --git a/ld/lexsup.c b/ld/lexsup.c
index e63c4310c6e..9cf1a9a033b 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -2265,6 +2265,10 @@ elf_shlib_list_options (FILE *file)
       fprintf (file, _("\
   -z textoff                  Don't treat DT_TEXTREL in output as error\n"));
     }
+  fprintf (file, _("\
+  -z memory-seal              Mark object be memory sealed\n"));
+  fprintf (file, _("\
+  -z nomemory-seal            Don't mark oject to be memory sealed (default)\n"));
 }
 
 static void
diff --git a/ld/testsuite/ld-elf/property-seal-1.d b/ld/testsuite/ld-elf/property-seal-1.d
new file mode 100644
index 00000000000..a0b1feedf31
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-1.d
@@ -0,0 +1,16 @@
+# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on
+# ET_DYN.
+#source: property-seal-1.s
+#as: --generate-missing-build-notes=no
+#ld: -shared
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#failif
+#...
+Displaying notes found in: .note.gnu.property
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-1.s b/ld/testsuite/ld-elf/property-seal-1.s
new file mode 100644
index 00000000000..aa28a3d0516
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-1.s
@@ -0,0 +1,11 @@
+	.section ".note.gnu.property", "a"
+	.p2align ALIGN
+	.long 1f - 0f		/* name length */
+	.long 3f - 2f		/* data length */
+	.long 5			/* note type */
+0:	.asciz "GNU"		/* vendor name */
+1:
+	.p2align ALIGN
+2:	.long 3			/* pr_type.  */
+	.long 0			/* pr_datasz.  */
+3:
diff --git a/ld/testsuite/ld-elf/property-seal-2.d b/ld/testsuite/ld-elf/property-seal-2.d
new file mode 100644
index 00000000000..ebdaa623e0c
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-2.d
@@ -0,0 +1,17 @@
+# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on
+# ET_DYN.
+#source: empty.s
+#source: property-seal-1.s
+#as: --generate-missing-build-notes=no
+#ld: -shared
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#failif
+#...
+Displaying notes found in: .note.gnu.property
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-3.d b/ld/testsuite/ld-elf/property-seal-3.d
new file mode 100644
index 00000000000..969729ee0f4
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-3.d
@@ -0,0 +1,16 @@
+# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on
+# ET_EXEC.
+#source: property-seal-1.s
+#as: --generate-missing-build-notes=no
+#ld: -e _start
+#warning: .*: warning: cannot find entry symbol .*
+#readelf: -n
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#failif
+#...
+Displaying notes found in: .note.gnu.property
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-4.d b/ld/testsuite/ld-elf/property-seal-4.d
new file mode 100644
index 00000000000..3dd990dd68a
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-4.d
@@ -0,0 +1,16 @@
+# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on
+# ET_EXEC.
+#source: empty.s
+#source: property-seal-1.s
+#as: --generate-missing-build-notes=no
+#ld: -e _start
+#readelf: -n
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#failif
+#...
+Displaying notes found in: .note.gnu.property
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-5.d b/ld/testsuite/ld-elf/property-seal-5.d
new file mode 100644
index 00000000000..0b92a8eb6eb
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-5.d
@@ -0,0 +1,15 @@
+#source: empty.s
+#ld: -shared -z memory-seal
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: memory seal 
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-6.d b/ld/testsuite/ld-elf/property-seal-6.d
new file mode 100644
index 00000000000..725911acae7
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-6.d
@@ -0,0 +1,16 @@
+#source: empty.s
+#source: property-seal-1.s
+#ld: -shared -z memory-seal
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: memory seal 
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-7.d b/ld/testsuite/ld-elf/property-seal-7.d
new file mode 100644
index 00000000000..12339e83ebd
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-7.d
@@ -0,0 +1,14 @@
+#source: empty.s
+#ld: -z memory-seal
+#readelf: -n
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: memory seal 
+#pass
diff --git a/ld/testsuite/ld-elf/property-seal-8.d b/ld/testsuite/ld-elf/property-seal-8.d
new file mode 100644
index 00000000000..0c4c4e4907e
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-seal-8.d
@@ -0,0 +1,15 @@
+#source: empty.s
+#source: property-seal-1.s
+#ld: -z memory-seal
+#readelf: -n
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: memory seal 
+#pass
