This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Fix /proc/<PID>/maps output for PEB and TEBs on W10 1511


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=f1ed5bfa8385a81d72313604e90b9096f8bf2ead

commit f1ed5bfa8385a81d72313604e90b9096f8bf2ead
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Dec 3 13:33:43 2015 +0100

    Fix /proc/<PID>/maps output for PEB and TEBs on W10 1511
    
            * fhandler_process.cc (heap_info::fill_if_match): Return NULL, not 0.
            (thread_info::fill_if_match): Ditto.
            (thread_info::fill_if_match): New method to extract TEB info from
            PEB/TEB region since W10 1511.
            (format_process_maps): Drop outdated FIXME comment.  Add code to handle
            PEB/TEB region since W10 1511.
            * mmap.cc (posix_madvise): Align comment to new W10 1511 version.
            * wincap.h (wincaps::has_new_pebteb_region): New element.
            * wincap.cc: Implement above element throughout.
            (wincap_10_1511): New global wincaps to support Windows 10 since 1511.
            (wincapc::init): Use wincap_10_1511 for W10 builds >= 10586.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog           | 14 +++++++++
 winsup/cygwin/fhandler_process.cc | 60 +++++++++++++++++++++++++++++++++------
 winsup/cygwin/mmap.cc             |  2 +-
 winsup/cygwin/wincap.cc           | 45 ++++++++++++++++++++++++++++-
 winsup/cygwin/wincap.h            |  2 ++
 5 files changed, 113 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 803cb4f..0cc944e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,19 @@
 2015-12-03  Corinna Vinschen  <corinna@vinschen.de>
 
+	* fhandler_process.cc (heap_info::fill_if_match): Return NULL, not 0.
+	(thread_info::fill_if_match): Ditto.
+	(thread_info::fill_if_match): New method to extract TEB info from
+	PEB/TEB region since W10 1511.
+	(format_process_maps): Drop outdated FIXME comment.  Add code to handle
+	PEB/TEB region since W10 1511.
+	* mmap.cc (posix_madvise): Align comment to new W10 1511 version.
+	* wincap.h (wincaps::has_new_pebteb_region): New element.
+	* wincap.cc: Implement above element throughout.
+	(wincap_10_1511): New global wincaps to support Windows 10 since 1511.
+	(wincapc::init): Use wincap_10_1511 for W10 builds >= 10586.
+
+2015-12-03  Corinna Vinschen  <corinna@vinschen.de>
+
 	x86_64 only:
 	* dcrt0.cc (_dll_crt0): Always move stack to pthread stack area.
 	Explain why.
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 516fbe3..ad622c9 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -648,7 +648,7 @@ struct heap_info
 	  stpcpy (p, "]");
 	  return dest;
 	}
-    return 0;
+    return NULL;
   }
 
   ~heap_info ()
@@ -769,7 +769,21 @@ struct thread_info
 	  stpcpy (p, "]");
 	  return dest;
 	}
-    return 0;
+    return NULL;
+  }
+  char *fill_if_match (char *start, char *end, ULONG type, char *dest)
+  {
+    for (region *r = regions; r; r = r->next)
+      if (r->teb && start <= r->start && r->end <= end)
+	{
+	  char *p = dest + __small_sprintf (dest, "[teb (tid %ld)",
+					    r->thread_id);
+	  if (type & MEM_MAPPED)
+	    p = stpcpy (p, " shared");
+	  stpcpy (p, "]");
+	  return dest;
+	}
+    return NULL;
   }
 
   ~thread_info ()
@@ -847,12 +861,7 @@ format_process_maps (void *data, char *&destbuf)
 
   /* Iterate over each VM region in the address space, coalescing
      memory regions with the same permissions. Once we run out, do one
-     last_pass to trigger output of the last accumulated region.
-     
-     FIXME:  32 bit processes can't get address information beyond the
-	     32 bit address space from 64 bit processes.  We have to run
-	     this functionality in the target process, if the target
-	     process is 64 bit and our own process is 32 bit. */
+     last_pass to trigger output of the last accumulated region. */
   for (char *i = 0;
        VirtualQueryEx (proc, i, &mb, sizeof(mb)) || (1 == ++last_pass);
        i = cur.rend)
@@ -899,6 +908,33 @@ format_process_maps (void *data, char *&destbuf)
 	  cur.rend = next.rend; /* merge with previous */
       else
 	{
+	  char *peb_teb_end = NULL;
+peb_teb_rinse_repeat:
+	  /* Starting with W10 1511, PEB and TEBs don't get allocated
+	     separately.  Rather they are created in a single region.  Examine
+	     the region starting at the PEB address page-wise. */
+	  if (wincap.has_new_pebteb_region ())
+	    {
+	      if (!newbase && cur.rbase == (char *) peb)
+		{
+		  strcpy (posix_modname, "[peb]");
+		  peb_teb_end = cur.rend;
+		  cur.rend = cur.rbase + wincap.page_size ();
+		}
+	      else if (peb_teb_end)
+		{
+		  posix_modname[0] = '\0';
+		  if (!threads.fill_if_match (cur.rbase, cur.rend,
+					      mb.Type, posix_modname))
+		    do
+		      {
+			cur.rend += wincap.page_size ();
+		      }
+		    while (!threads.fill_if_match (cur.rbase, cur.rend,
+						   mb.Type, posix_modname)
+			   && cur.rend < peb_teb_end);
+		}
+	    }
 	  /* output the current region if it's "interesting". */
 	  if (cur.a.word)
 	    {
@@ -919,6 +955,14 @@ format_process_maps (void *data, char *&destbuf)
 	      len += written;
 	      len += __small_sprintf (destbuf + len, "%s\n", posix_modname);
 	    }
+
+	  if (peb_teb_end)
+	    {
+	      cur.rbase = cur.rend;
+	      cur.rend += wincap.page_size ();
+	      if (cur.rbase < peb_teb_end)
+		goto peb_teb_rinse_repeat;
+	    }
 	  /* start of a new region (but possibly still the same allocation). */
 	  cur = next;
 	  /* if a new allocation, figure out what kind it is. */
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 984504e..2866f21 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -1578,7 +1578,7 @@ posix_madvise (void *addr, size_t len, int advice)
 	    /* FIXME 2015-08-27: On W10 build 10240 under WOW64,
 	       PrefetchVirtualMemory always returns ERROR_INVALID_PARAMETER
 	       for some reason.  If we're running on W10 WOW64, ignore this
-	       error for now.  There's an open case at Microsoft for this. */
+	       error.  This has been fixed in W10 1511. */
 	    if (!wincap.has_broken_prefetchvm ()
 		|| GetLastError () != ERROR_INVALID_PARAMETER)
 	      ret = EINVAL;
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 6e98df6..4bf62d7 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -51,6 +51,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:false,
   has_processor_groups:false,
   has_broken_prefetchvm:false,
+  has_new_pebteb_region:false,
 };
 
 wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -84,6 +85,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:true,
   has_processor_groups:false,
   has_broken_prefetchvm:false,
+  has_new_pebteb_region:false,
 };
 
 wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -117,6 +119,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:false,
   has_processor_groups:false,
   has_broken_prefetchvm:false,
+  has_new_pebteb_region:false,
 };
 
 wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -150,6 +153,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:false,
   has_processor_groups:true,
   has_broken_prefetchvm:false,
+  has_new_pebteb_region:false,
 };
 
 wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -183,6 +187,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:false,
   has_processor_groups:true,
   has_broken_prefetchvm:false,
+  has_new_pebteb_region:false,
 };
 
 wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -216,6 +221,41 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_rtl_query_process_debug_information:false,
   has_processor_groups:true,
   has_broken_prefetchvm:true,
+  has_new_pebteb_region:false,
+};
+
+wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
+  def_guard_pages:2,
+  max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
+  is_server:false,
+  has_mandatory_integrity_control:true,
+  needs_count_in_si_lpres2:false,
+  has_recycle_dot_bin:true,
+  has_gaa_on_link_prefix:true,
+  has_gaa_largeaddress_bug:false,
+  supports_all_posix_ai_flags:true,
+  has_restricted_stack_args:false,
+  has_transactions:true,
+  has_sendmsg:true,
+  has_broken_udf:false,
+  has_broken_alloc_console:true,
+  has_always_all_codepages:true,
+  has_localenames:true,
+  has_fast_cwd:true,
+  has_restricted_raw_disk_access:true,
+  use_dont_resolve_hack:false,
+  has_console_logon_sid:true,
+  wow64_has_secondary_stack:false,
+  has_program_compatibility_assistant:true,
+  has_pipe_reject_remote_clients:true,
+  terminate_thread_frees_stack:true,
+  has_precise_system_time:true,
+  has_microsoft_accounts:true,
+  has_set_thread_stack_guarantee:true,
+  has_broken_rtl_query_process_debug_information:false,
+  has_processor_groups:true,
+  has_broken_prefetchvm:false,
+  has_new_pebteb_region:true,
 };
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
@@ -263,7 +303,10 @@ wincapc::init ()
 	break;
       case 10:
       default:
-	caps = &wincap_10;
+	if (version.dwBuildNumber >= 10586)
+	  caps = &wincap_10_1511;
+	else
+	  caps = &wincap_10;
 	break;
     }
 
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 26751b1..4508974 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -44,6 +44,7 @@ struct wincaps
   unsigned has_broken_rtl_query_process_debug_information : 1;
   unsigned has_processor_groups				: 1;
   unsigned has_broken_prefetchvm			: 1;
+  unsigned has_new_pebteb_region			: 1;
 };
 
 class wincapc
@@ -102,6 +103,7 @@ public:
   bool	IMPLEMENT (has_broken_rtl_query_process_debug_information)
   bool	IMPLEMENT (has_processor_groups)
   bool	IMPLEMENT (has_broken_prefetchvm)
+  bool	IMPLEMENT (has_new_pebteb_region)
 
 #undef IMPLEMENT
 };


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]