Add comments from email discussion re mprotect.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5057 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 0b5e10b..b63100b 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -4554,7 +4554,23 @@
 
    if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect")) {
       SET_STATUS_Failure( VKI_ENOMEM );
-   } else if (ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
+   } 
+   else 
+   if (ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
+      /* Deal with mprotects on growable stack areas.
+
+         The critical files to understand all this are mm/mprotect.c
+         in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in
+         glibc.
+
+         The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which
+         round the start/end address of mprotect to the start/end of
+         the underlying vma and glibc uses that as an easy way to
+         change the protection of the stack by calling mprotect on the
+         last page of the stack with PROT_GROWSDOWN set.
+
+         The sanity check provided by the kernel is that the vma must
+         have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate.  */
       UInt grows = ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
       NSegment *aseg = VG_(am_find_nsegment)(ARG1);
       NSegment *rseg;
@@ -4586,6 +4602,7 @@
             SET_STATUS_Failure( VKI_EINVAL );
          }
       } else {
+         /* both GROWSUP and GROWSDOWN */
          SET_STATUS_Failure( VKI_EINVAL );
       }
    }