diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 803cb4f5c..0cc944e96 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2015-12-03 Corinna Vinschen + + * 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 x86_64 only: diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 516fbe32c..ad622c982 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 984504ede..2866f2182 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 6e98df6c4..4bf62d725 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 26751b18e..4508974f5 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 };