diff -ru binutils-2.22-orig/elfcpp/elfcpp.h binutils-2.22/elfcpp/elfcpp.h
--- binutils-2.22-orig/elfcpp/elfcpp.h	2011-07-03 03:37:07.000000000 -1000
+++ binutils-2.22/elfcpp/elfcpp.h	2012-02-16 20:45:53.876856915 -1000
@@ -471,6 +471,8 @@
   PT_GNU_STACK = 0x6474e551,
   // Read only after relocation.
   PT_GNU_RELRO = 0x6474e552,
+  // PaX flags
+  PT_PAX_FLAGS = 0x65041580,
   // Platform architecture compatibility information
   PT_ARM_ARCHEXT = 0x70000000,
   // Exception unwind tables
@@ -485,7 +487,18 @@
   PF_W = 0x2,
   PF_R = 0x4,
   PF_MASKOS = 0x0ff00000,
-  PF_MASKPROC = 0xf0000000
+  PF_MASKPROC = 0xf0000000,
+  PF_PAGEEXEC	= (1 << 4),	/* Enable  PAGEEXEC */
+  PF_NOPAGEEXEC	= (1 << 5),	/* Disable PAGEEXEC */
+  PF_SEGMEXEC	= (1 << 6),	/* Enable  SEGMEXEC */
+  PF_NOSEGMEXEC	= (1 << 7),	/* Disable SEGMEXEC */
+  PF_MPROTECT	= (1 << 8),	/* Enable  MPROTECT */
+  PF_NOMPROTECT	= (1 << 9),	/* Disable MPROTECT */
+  PF_RANDEXEC	= (1 << 10),	/* Enable  RANDEXEC */
+  PF_NORANDEXEC	= (1 << 11),	/* Disable RANDEXEC */
+  PF_EMUTRAMP	= (1 << 12),	/* Enable  EMUTRAMP */
+  PF_NOEMUTRAMP	= (1 << 13),	/* Disable EMUTRAMP */
+  PF_RANDMMAP	= (1 << 14),	/* Enable  RANDMMAP */
 };
 
 // Symbol binding from Sym st_info field.
diff -ru binutils-2.22-orig/gold/layout.cc binutils-2.22/gold/layout.cc
--- binutils-2.22-orig/gold/layout.cc	2011-09-18 05:06:28.000000000 -1000
+++ binutils-2.22/gold/layout.cc	2012-02-17 10:50:33.221969162 -1000
@@ -2633,10 +2633,30 @@
     {
       if (this->script_options_->saw_phdrs_clause())
 	return;
-      int flags = elfcpp::PF_R | elfcpp::PF_W;
+      int stack_flags = elfcpp::PF_R | elfcpp::PF_W;
+      int pax_flags = elfcpp::PF_NORANDEXEC | elfcpp::PF_NOEMUTRAMP;
+
+      if (parameters->options().is_execheap_set())
+	{
+	  bool is_heap_executable = parameters->options().is_heap_executable();
+	  if (is_heap_executable)
+	    pax_flags |= elfcpp::PF_NOMPROTECT;
+	  else
+	    pax_flags |= elfcpp::PF_MPROTECT;
+        }
+
       if (is_stack_executable)
-	flags |= elfcpp::PF_X;
-      this->make_output_segment(elfcpp::PT_GNU_STACK, flags);
+	{
+	  stack_flags |= elfcpp::PF_X;
+	  if (parameters->options().is_execstack_set())
+	    {
+	      pax_flags |= elfcpp::PF_EMUTRAMP;
+	      pax_flags &= ~elfcpp::PF_NOEMUTRAMP;
+	    }
+	}
+
+      this->make_output_segment(elfcpp::PT_GNU_STACK, stack_flags);
+      this->make_output_segment(elfcpp::PT_PAX_FLAGS, pax_flags);
     }
 }
 
diff -ru binutils-2.22-orig/gold/options.cc binutils-2.22/gold/options.cc
--- binutils-2.22-orig/gold/options.cc	2011-07-11 06:19:51.000000000 -1000
+++ binutils-2.22/gold/options.cc	2012-02-16 22:36:08.836811480 -1000
@@ -912,6 +912,7 @@
 General_options::General_options()
   : printed_version_(false),
     execstack_status_(EXECSTACK_FROM_INPUT),
+    execheap_status_(EXECHEAP_FROM_INPUT),
     icf_status_(ICF_NONE),
     static_(false),
     do_demangle_(false),
@@ -1051,6 +1052,13 @@
   else if (this->noexecstack())
     this->set_execstack_status(EXECSTACK_NO);
 
+  // execheap_status_ is a three-state variable; update it based on
+  // -z [no]execheap.
+  if (this->execheap())
+    this->set_execheap_status(EXECHEAP_YES);
+  else if (this->noexecheap())
+    this->set_execheap_status(EXECHEAP_NO);
+
   // icf_status_ is a three-state variable; update it based on the
   // value of this->icf().
   if (strcmp(this->icf(), "none") == 0)
diff -ru binutils-2.22-orig/gold/options.h binutils-2.22/gold/options.h
--- binutils-2.22-orig/gold/options.h	2011-11-20 23:29:35.000000000 -1000
+++ binutils-2.22/gold/options.h	2012-02-16 22:48:53.719671402 -1000
@@ -1170,6 +1170,8 @@
               NULL);
   DEFINE_bool(execstack, options::DASH_Z, '\0', false,
               N_("Mark output as requiring executable stack"), NULL);
+  DEFINE_bool(execheap, options::DASH_Z, '\0', false,
+              N_("Mark output as requiring executable heap"), NULL);
   DEFINE_bool(initfirst, options::DASH_Z, '\0', false,
 	      N_("Mark DSO to be initialized first at runtime"),
 	      NULL);
@@ -1206,6 +1208,8 @@
 	      NULL);
   DEFINE_bool(noexecstack, options::DASH_Z, '\0', false,
               N_("Mark output as not requiring executable stack"), NULL);
+  DEFINE_bool(noexecheap, options::DASH_Z, '\0', false,
+              N_("Mark output as not requiring executable heap"), NULL);
   DEFINE_bool(now, options::DASH_Z, '\0', false,
 	      N_("Mark object for immediate function binding"),
 	      NULL);
@@ -1307,6 +1311,16 @@
   is_stack_executable() const
   { return this->execstack_status_ == EXECSTACK_YES; }
 
+  // These are the best way to get access to the execheap state,
+  // not execheap() and noexecheap() which are hard to use properly.
+  bool
+  is_execheap_set() const
+  { return this->execheap_status_ != EXECHEAP_FROM_INPUT; }
+
+  bool
+  is_heap_executable() const
+  { return this->execheap_status_ == EXECHEAP_YES; }
+
   bool
   icf_enabled() const
   { return this->icf_status_ != ICF_NONE; }
@@ -1426,6 +1440,17 @@
     EXECSTACK_NO
   };
 
+  // Whether to mark the heap as executable.
+  enum Execheap
+  {
+    // Not set on command line.
+    EXECHEAP_FROM_INPUT,
+    // Mark the heap as executable (-z execheap).
+    EXECHEAP_YES,
+    // Mark the heap as not executable (-z noexecheap).
+    EXECHEAP_NO
+  };
+
   enum Icf_status
   {
     // Do not fold any functions (Default or --icf=none).
@@ -1445,6 +1470,10 @@
   { this->execstack_status_ = value; }
 
   void
+  set_execheap_status(Execheap value)
+  { this->execheap_status_ = value; }
+
+  void
   set_do_demangle(bool value)
   { this->do_demangle_ = value; }
 
@@ -1473,6 +1502,8 @@
   bool printed_version_;
   // Whether to mark the stack as executable.
   Execstack execstack_status_;
+  // Whether to mark the heap as executable.
+  Execheap execheap_status_;
   // Whether to do code folding.
   Icf_status icf_status_;
   // Whether to do a static link.
diff -ru binutils-2.22-orig/gold/script.cc binutils-2.22/gold/script.cc
--- binutils-2.22-orig/gold/script.cc	2011-06-29 11:57:14.000000000 -1000
+++ binutils-2.22/gold/script.cc	2012-02-16 21:29:58.710599233 -1000
@@ -3249,7 +3249,8 @@
   PHDR_TYPE(PT_TLS),
   PHDR_TYPE(PT_GNU_EH_FRAME),
   PHDR_TYPE(PT_GNU_STACK),
-  PHDR_TYPE(PT_GNU_RELRO)
+  PHDR_TYPE(PT_GNU_RELRO),
+  PHDR_TYPE(PT_PAX_FLAGS)
 };
 
 extern "C" unsigned int
