Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-06-01 07:46:56 +0400
committerChristopher Faylor <me@cgf.cx>2005-06-01 07:46:56 +0400
commitce95c6407ef6ab1a60a1b1e2cd62ef4ae2081174 (patch)
tree6d083de1286c20546e090d2d62a45f918182b3af /winsup
parent302cb8165e957ac12528c221f263b358c859c831 (diff)
* child_info.h (child_info::cygheap_h): Delete.
(child_info::dwProcessId): New field. * cygheap.cc (init_cheap): Delete. (dup_now): Ditto. (cygheap_setup_for_child): Ditto. (cygheap_setup_for_child_cleanup): Ditto. (cygheap_fixup_in_child): Simplify. Use new "child_copy" function to copy heap from parent. (_csbrk): Don't attempt allocation if within cygheap section. Fix so that more than one allocation will succeed. (cygheap_init): Reset possibly-nonzero region to zero. * cygheap.h (cygheap_setup_for_child): Delete declaration. (cygheap_setup_for_child_cleanup): Ditto. (cygheap_start): Define as an array. * cygwin.sc: Modernize. Remove unneeded sections. Define cygheap here. * dcrt0.cc (do_exit): Reflect argument change to close_all_files. * dtable.cc (dtable::vfork_parent_restore): Ditto. * dtable.h: Ditto. * fhandler.h: Ditto. * fork.cc (fork_copy): Call ReadProcessMemory if there is no thread (indicating that we're execing). (fork_child): Don't mess with hParent. (fork_parent): Remove hParent stuff. It happens earlier now. Remove call to cygheap_setup_for_child* stuff. (fork): Put child_info_stuff in grouped structure. Issue error if parent handle is not set. (child_copy): New function. * sigproc.cc (child_info::child_info): Put cygheap settings here. Set parent handle. (child_info::~child_info): Close parent handle if it exists. * spawn.cc (spawn_guts): Reorganize so that ciresrv is allocated at only the last minute so that cygheap changes are reflected. Delete cygheap_setup* calls. * syscalls.cc (close_all_files): Add an argument to flag when the fd entry should be released. * winsup.h (close_all_files): Add an argument to close_all_files declaration. Declare child_copy.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog41
-rw-r--r--winsup/cygwin/child_info.h4
-rw-r--r--winsup/cygwin/cygheap.cc195
-rw-r--r--winsup/cygwin/cygheap.h4
-rw-r--r--winsup/cygwin/cygwin.sc105
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/dtable.cc2
-rw-r--r--winsup/cygwin/dtable.h2
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fork.cc61
-rw-r--r--winsup/cygwin/sigproc.cc11
-rw-r--r--winsup/cygwin/spawn.cc45
-rw-r--r--winsup/cygwin/syscalls.cc5
-rw-r--r--winsup/cygwin/winsup.h3
14 files changed, 202 insertions, 280 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 924a907aa..c79e095ef 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,44 @@
+2005-05-30 Christopher Faylor <cgf@timesys.com>
+
+ * child_info.h (child_info::cygheap_h): Delete.
+ (child_info::dwProcessId): New field.
+ * cygheap.cc (init_cheap): Delete.
+ (dup_now): Ditto.
+ (cygheap_setup_for_child): Ditto.
+ (cygheap_setup_for_child_cleanup): Ditto.
+ (cygheap_fixup_in_child): Simplify. Use new "child_copy" function to
+ copy heap from parent.
+ (_csbrk): Don't attempt allocation if within cygheap section. Fix so
+ that more than one allocation will succeed.
+ (cygheap_init): Reset possibly-nonzero region to zero.
+ * cygheap.h (cygheap_setup_for_child): Delete declaration.
+ (cygheap_setup_for_child_cleanup): Ditto.
+ (cygheap_start): Define as an array.
+ * cygwin.sc: Modernize. Remove unneeded sections. Define cygheap
+ here.
+ * dcrt0.cc (do_exit): Reflect argument change to close_all_files.
+ * dtable.cc (dtable::vfork_parent_restore): Ditto.
+ * dtable.h: Ditto.
+ * fhandler.h: Ditto.
+ * fork.cc (fork_copy): Call ReadProcessMemory if there is no thread
+ (indicating that we're execing).
+ (fork_child): Don't mess with hParent.
+ (fork_parent): Remove hParent stuff. It happens earlier now.
+ Remove call to cygheap_setup_for_child* stuff.
+ (fork): Put child_info_stuff in grouped structure. Issue error if
+ parent handle is not set.
+ (child_copy): New function.
+ * sigproc.cc (child_info::child_info): Put cygheap settings here. Set
+ parent handle.
+ (child_info::~child_info): Close parent handle if it exists.
+ * spawn.cc (spawn_guts): Reorganize so that ciresrv is allocated at
+ only the last minute so that cygheap changes are reflected. Delete
+ cygheap_setup* calls.
+ * syscalls.cc (close_all_files): Add an argument to flag when the fd
+ entry should be released.
+ * winsup.h (close_all_files): Add an argument to close_all_files
+ declaration. Declare child_copy.
+
2005-05-30 Vaclav Haisman <v.haisman@sh.cvut.cz>
* thread.h (List_remove): Make node parameter const. Use simple
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index f0fa3d0eb..5e2bc0578 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -29,7 +29,7 @@ enum child_info_types
#define EXEC_MAGIC_SIZE sizeof(child_info)
-#define CURR_CHILD_INFO_MAGIC 0xd079e02U
+#define CURR_CHILD_INFO_MAGIC 0xd94c588aU
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
@@ -48,7 +48,7 @@ public:
init_cygheap *cygheap;
void *cygheap_max;
DWORD cygheap_reserve_sz;
- HANDLE cygheap_h;
+ DWORD dwProcessId;
unsigned fhandler_union_cb;
child_info (unsigned, child_info_types);
~child_info ();
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 369501131..5e85a074f 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -22,12 +22,16 @@
#include "heap.h"
#include "sync.h"
#include "sigproc.h"
+#include "pinfo.h"
+#include <unistd.h>
init_cygheap NO_COPY *cygheap;
void NO_COPY *cygheap_max;
+extern "C" char _cygheap_mid[] __attribute__((section(".cygheap")));
+extern "C" char _cygheap_end[] __attribute__((section(".cygheap_end")));
+
static NO_COPY muto cygheap_protect;
-static NO_COPY DWORD reserve_sz;
struct cygheap_entry
{
@@ -44,141 +48,20 @@ struct cygheap_entry
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
extern "C" {
-static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
-}
-
-static void
-init_cheap ()
-{
-#ifndef DEBUGGING
- reserve_sz = CYGHEAPSIZE;
-#else
- char buf[80];
- DWORD initial_sz = 0;
- if (!GetEnvironmentVariable ("CYGWIN_HEAPSIZE", buf, sizeof buf - 1))
- initial_sz = reserve_sz = CYGHEAPSIZE;
- else
- {
- initial_sz = reserve_sz = atoi (buf);
- small_printf ("using cygheap size %d\n", reserve_sz);
- }
-#endif
- do
- if ((cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start,
- reserve_sz, MEM_RESERVE,
- PAGE_NOACCESS)))
- break;
- while ((reserve_sz -= 2 * (1024 * 1024)) >= CYGHEAPSIZE_MIN);
-#ifdef DEBUGGING
- if (reserve_sz != initial_sz)
- small_printf ("reset initial cygheap size to %u\n", reserve_sz);
-#endif
- if (!cygheap)
- {
- MEMORY_BASIC_INFORMATION m;
- if (!VirtualQuery ((LPCVOID) &_cygheap_start, &m, sizeof m))
- system_printf ("couldn't get memory info, %E");
- system_printf ("Couldn't reserve %d bytes of space for cygwin's heap, %E",
- reserve_sz);
- api_fatal ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
- m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
- }
- cygheap_max = cygheap;
-}
-
-static void dup_now (void *, child_info *, unsigned) __attribute__ ((regparm(3)));
-static void
-dup_now (void *newcygheap, child_info *ci, unsigned n)
-{
- if (!VirtualAlloc (newcygheap, n, MEM_COMMIT, PAGE_READWRITE))
- api_fatal ("couldn't allocate new cygwin heap %p, %d for child, %E",
- newcygheap, n);
- memcpy (newcygheap, cygheap, n);
-}
-
-void *__stdcall
-cygheap_setup_for_child (child_info *ci, bool dup_later)
-{
- void *newcygheap;
- cygheap_protect.acquire ();
- unsigned n = (char *) cygheap_max - (char *) cygheap;
- unsigned size = reserve_sz;
- if (size < n)
- size = n + (128 * 1024);
- ci->cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none,
- CFMAP_OPTIONS, 0, size, NULL);
- if (!ci->cygheap_h)
- api_fatal ("Couldn't create heap for child, size %d, %E", size);
- newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
- if (!newcygheap)
- api_fatal ("couldn't map space for new cygheap, %E");
- ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h);
- if (!dup_later)
- dup_now (newcygheap, ci, n);
- cygheap_protect.release ();
- ci->cygheap = cygheap;
- ci->cygheap_max = cygheap_max;
- ci->cygheap_reserve_sz = size;
- return newcygheap;
-}
-
-void __stdcall
-cygheap_setup_for_child_cleanup (void *newcygheap, child_info *ci,
- bool dup_it_now)
-{
- if (dup_it_now)
- {
- /* NOTE: There is an assumption here that cygheap_max has not changed
- between the time that cygheap_setup_for_child was called and now.
- Make sure that this is a correct assumption. */
- cygheap_protect.acquire ();
- dup_now (newcygheap, ci, (char *) cygheap_max - (char *) cygheap);
- cygheap_protect.release ();
- }
- UnmapViewOfFile (newcygheap);
- ForceCloseHandle1 (ci->cygheap_h, passed_cygheap_h);
+static void __stdcall _cfree (void *) __attribute__((regparm(1)));
+static void *__stdcall _csbrk (int);
}
/* Called by fork or spawn to reallocate cygwin heap */
void __stdcall
cygheap_fixup_in_child (bool execed)
{
- cygheap = child_proc_info->cygheap;
- cygheap_max = child_proc_info->cygheap_max;
- void *addr = !wincap.map_view_of_file_ex_sucks () ? cygheap : NULL;
- void *newaddr;
-
- newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
- reserve_sz = child_proc_info->cygheap_reserve_sz;
- if (newaddr != cygheap)
- {
- if (!newaddr)
- newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
- DWORD n = (DWORD) cygheap_max - (DWORD) cygheap;
- /* Reserve cygwin heap in same spot as parent */
- if (!VirtualAlloc (cygheap, reserve_sz, MEM_RESERVE, PAGE_NOACCESS))
- {
- MEMORY_BASIC_INFORMATION m;
- memset (&m, 0, sizeof m);
- if (!VirtualQuery ((LPCVOID) cygheap, &m, sizeof m))
- system_printf ("couldn't get memory info, %E");
-
- system_printf ("Couldn't reserve %d bytes of space for cygwin's heap (%p <%p>) in child, %E",
- reserve_sz, cygheap, newaddr);
- api_fatal ("m.AllocationBase %p, m.BaseAddress %p, m.RegionSize %p, m.State %p\n",
- m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
- }
-
- /* Allocate same amount of memory as parent */
- if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
- api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
- cygheap, n);
- memcpy (cygheap, newaddr, n);
- UnmapViewOfFile (newaddr);
- }
-
- ForceCloseHandle1 (child_proc_info->cygheap_h, passed_cygheap_h);
-
+ cygheap_max = child_proc_info->cygheap;
+ cygheap = (init_cygheap *) cygheap_max;
+ _csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
+ child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap", cygheap, cygheap_max);
+ if (execed)
+ CloseHandle (child_proc_info->parent);
cygheap_init ();
debug_fixup_after_fork_exec ();
@@ -222,30 +105,42 @@ init_cygheap::close_ctty ()
#endif
}
-#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
+#define nextpage(x) ((char *) (((DWORD) ((char *) x + granmask)) & ~granmask))
+#define allocsize(x) ((DWORD) nextpage (x))
+#ifdef DEBUGGING
+#define somekinda_printf debug_printf
+#else
+#define somekinda_printf malloc_printf
+#endif
static void *__stdcall
_csbrk (int sbs)
{
void *prebrk = cygheap_max;
- void *prebrka = pagetrunc (prebrk);
+ size_t granmask = getshmlba () - 1;
+ char *newbase = nextpage (prebrk);
cygheap_max = (char *) cygheap_max + sbs;
- if (!sbs || (prebrk != prebrka && prebrka == pagetrunc (cygheap_max)))
+ if (!sbs || (newbase > cygheap_max) || (cygheap_max < _cygheap_end))
/* nothing to do */;
- else if (!VirtualAlloc (prebrk, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
+ else
{
-#ifdef DEBUGGING
- system_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
- prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
- reserve_sz);
-#else
- malloc_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
- prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
- reserve_sz);
-#endif
- __seterrno ();
- cygheap_max = (char *) cygheap_max - sbs;
- return NULL;
+ if (prebrk <= _cygheap_end)
+ newbase = _cygheap_end;
+
+ DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
+ if (!VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
+ {
+ MEMORY_BASIC_INFORMATION m;
+ if (!VirtualQuery (newbase, &m, sizeof m))
+ system_printf ("couldn't get memory info, %E");
+ somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
+ adjsbs);
+ somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
+ m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
+ __seterrno ();
+ cygheap_max = (char *) cygheap_max - sbs;
+ return NULL;
+ }
}
return prebrk;
@@ -257,7 +152,13 @@ cygheap_init ()
cygheap_protect.init ("cygheap_protect");
if (!cygheap)
{
- init_cheap ();
+#if 1
+ cygheap = (init_cygheap *) memset (_cygheap_start, 0, _cygheap_mid - _cygheap_start);
+#else
+ cygheap = (init_cygheap *) _cygheap_start;
+#endif
+
+ cygheap_max = cygheap;
(void) _csbrk (sizeof (*cygheap));
}
if (!cygheap->fdtab)
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 2e0a1e254..5738d25d4 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -416,8 +416,6 @@ class cygheap_fdenum : public cygheap_fdmanip
};
class child_info;
-void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
-void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
void __stdcall cygheap_fixup_in_child (bool);
extern "C" {
void __stdcall cfree (void *) __attribute__ ((regparm(1)));
@@ -428,5 +426,5 @@ char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
void __stdcall cygheap_init ();
-extern DWORD _cygheap_start __attribute__((section(".cygheap")));
+extern char _cygheap_start[] __attribute__((section(".idata")));
}
diff --git a/winsup/cygwin/cygwin.sc b/winsup/cygwin/cygwin.sc
index a911b93e4..6393dab9a 100644
--- a/winsup/cygwin/cygwin.sc
+++ b/winsup/cygwin/cygwin.sc
@@ -1,6 +1,4 @@
OUTPUT_FORMAT(pei-i386)
-SEARCH_DIR(/cygnus/i686-pc-cygwin/lib/w32api); SEARCH_DIR(/cygnus/i686-pc-cygwin/lib);
-ENTRY(_mainCRTStartup)
SECTIONS
{
.text __image_base__ + __section_alignment__ :
@@ -10,9 +8,9 @@ SECTIONS
*(SORT(.text$*))
*(.glue_7t)
*(.glue_7)
- ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ ___CTOR_LIST__ = .; __CTOR_LIST__ = .;
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
- ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ ___DTOR_LIST__ = .; __DTOR_LIST__ = .;
LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0);
*(.fini)
/* ??? Why is .gcc_exc here? */
@@ -20,38 +18,42 @@ SECTIONS
etext = .;
*(.gcc_except_table)
}
+ .autoload_text ALIGN(__section_alignment__) :
+ {
+ *(.*_text);
+ }
/* The Cygwin DLL uses a section to avoid copying certain data
on fork. This used to be named ".data". The linker used
to include this between __data_start__ and __data_end__, but that
breaks building the cygwin32 dll. Instead, we name the section
".data_cygwin_nocopy" and explictly include it after __data_end__. */
- .data BLOCK(__section_alignment__) :
+ .data ALIGN(__section_alignment__) :
{
- __data_start__ = . ;
+ __data_start__ = .;
*(.data)
*(.data2)
*(SORT(.data$*))
- __data_end__ = . ;
+ __data_end__ = .;
*(.data_cygwin_nocopy)
}
- .rdata BLOCK(__section_alignment__) :
+ .rdata ALIGN(__section_alignment__) :
{
*(.rdata)
*(SORT(.rdata$*))
*(.eh_frame)
}
- .pdata BLOCK(__section_alignment__) :
+ .pdata ALIGN(__section_alignment__) :
{
*(.pdata)
}
- .bss BLOCK(__section_alignment__) :
+ .bss ALIGN(__section_alignment__) :
{
- __bss_start__ = . ;
+ __bss_start__ = .;
*(.bss)
*(COMMON)
- __bss_end__ = . ;
+ __bss_end__ = .;
}
- .edata BLOCK(__section_alignment__) :
+ .edata ALIGN(__section_alignment__) :
{
*(.edata)
}
@@ -62,7 +64,28 @@ SECTIONS
*(.debug$F)
*(.drectve)
}
- .idata BLOCK(__section_alignment__) :
+ .stab ALIGN(__section_alignment__) (NOLOAD) :
+ {
+ [ .stab ]
+ }
+ .stabstr ALIGN(__section_alignment__) (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
+ .debug_pubnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_info) }
+ .debug_abbrev ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
+ .debug_line ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_line) }
+ .debug_frame ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
+ .debug_str ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_str) }
+ .debug_loc ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
+ .debug_macinfo ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
+ .debug_macinfo ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
+ .debug_ranges ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
+ .idata ALIGN(__section_alignment__) :
{
/* This cannot currently be handled with grouped sections.
See pe.em:sort_sections. */
@@ -74,51 +97,17 @@ SECTIONS
SORT(*)(.idata$5)
SORT(*)(.idata$6)
SORT(*)(.idata$7)
+ . = ALIGN(16);
+ __cygheap_start = ABSOLUTE(.);
}
- .CRT BLOCK(__section_alignment__) :
- {
- *(SORT(.CRT$*))
- }
- .endjunk BLOCK(__section_alignment__) :
- {
- /* end is deprecated, don't use it */
- end = .;
- _end = .;
- __end__ = .;
- }
- .rsrc BLOCK(__section_alignment__) :
- {
- *(.rsrc)
- *(SORT(.rsrc$*))
- }
- .reloc BLOCK(__section_alignment__) :
- {
- *(.reloc)
- }
- .stab BLOCK(__section_alignment__) (NOLOAD) :
- {
- [ .stab ]
- }
- .stabstr BLOCK(__section_alignment__) (NOLOAD) :
- {
- [ .stabstr ]
- }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
- .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) }
- .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
- .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }
- .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
- .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }
- .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
- .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
- .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
- .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
- .cygheap BLOCK(64 * 1024) :
+ osection_alignment = __section_alignment__;
+ __section_alignment__ = 64 * 1024;
+ .cygheap ALIGN(4096):
{
- __system_dlls__ = ABSOLUTE(.) ;
- __cygheap_start = ABSOLUTE(.) ;
+ __cygheap_mid = .;
+ . = ALIGN(512 * 1024, 0x10000);
+ . += 8192; /* inexplicably needed for alignment on 64K boundary?!? */
+_cygheap_foo = .;
}
+ __cygheap_end = ABSOLUTE(.);
}
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 4f643ae1e..fa407d407 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1030,7 +1030,7 @@ do_exit (int status)
if (exit_state < ES_CLOSEALL)
{
exit_state = ES_CLOSEALL;
- close_all_files ();
+ close_all_files (false);
}
if (exit_state < ES_SIGPROCTERMINATE)
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 24a88ce26..db69ed376 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -766,7 +766,7 @@ dtable::vfork_parent_restore ()
lock ();
fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
- close_all_files ();
+ close_all_files (false);
fhandler_base **deleteme = fds;
fds = fds_on_hold;
fds_on_hold = NULL;
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 343eb8cc8..9e0523808 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -84,7 +84,7 @@ public:
fhandler_base **add_archetype ();
void delete_archetype (fhandler_base *);
friend void dtable_init ();
- friend void __stdcall close_all_files ();
+ friend void __stdcall close_all_files (bool);
friend class cygheap_fdmanip;
friend class cygheap_fdget;
friend class cygheap_fdnew;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index ff2f315e3..f0b588fca 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -82,7 +82,7 @@ enum query_state {
class fhandler_base
{
friend class dtable;
- friend void close_all_files ();
+ friend void close_all_files (bool);
struct status_flags
{
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index f2e287c73..5ecd3bbe4 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -81,7 +81,11 @@ fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
DWORD done = 0;
if (here + todo > high)
todo = high - here;
- int res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
+ int res;
+ if (pi.hThread)
+ res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
+ else
+ res = ReadProcessMemory (pi.hProcess, here, here, todo, &done);
debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
low, high, res);
if (!res || todo != done)
@@ -223,18 +227,15 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
if (!load_dlls)
{
cygheap->fdtab.fixup_after_fork (hParent);
- ProtectHandleINH (hParent);
sync_with_parent ("performed fork fixup", false);
}
else
{
dlls.load_after_fork (hParent, first_dll);
cygheap->fdtab.fixup_after_fork (hParent);
- ProtectHandleINH (hParent);
sync_with_parent ("loaded dlls", true);
}
- ForceCloseHandle (hParent);
(void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
_my_tls.fixup_after_fork ();
@@ -276,8 +277,7 @@ slow_pid_reuse (HANDLE h)
#endif
static int __stdcall
-fork_parent (HANDLE& hParent, dll *&first_dll,
- bool& load_dlls, void *stack_here, child_info_fork &ch)
+fork_parent (HANDLE&, dll *&first_dll, bool& load_dlls, void *stack_here, child_info_fork &ch)
{
HANDLE forker_finished;
DWORD rc;
@@ -308,16 +308,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
if (cygheap->fdtab.need_fixup_before ())
c_flags |= CREATE_SUSPENDED;
- /* Create an inheritable handle to pass to the child process. This will
- allow the child to duplicate handles from the parent to itself. */
- hParent = NULL;
- if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, TRUE,
- DUPLICATE_SAME_ACCESS))
- {
- system_printf ("couldn't create handle to myself for child, %E");
- return -1;
- }
-
/* Remember the address of the first loaded dll and decide
if we need to load dlls. We do this here so that this
information will be available in the parent and, when
@@ -331,7 +321,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
if (forker_finished == NULL)
{
- CloseHandle (hParent);
system_printf ("unable to allocate forker_finished event, %E");
return -1;
}
@@ -349,13 +338,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Remove impersonation */
cygheap->user.deimpersonate ();
- ch.parent = hParent;
-
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
bool locked = __malloc_lock ();
- void *newheap;
- newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */
&sec_none_nih,
@@ -367,8 +352,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
&si,
&pi);
- CloseHandle (hParent);
-
if (!rc)
{
__seterrno ();
@@ -376,19 +359,15 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ForceCloseHandle (forker_finished);
/* Restore impersonation */
cygheap->user.reimpersonate ();
- cygheap_setup_for_child_cleanup (newheap, &ch, 0);
__malloc_unlock ();
return -1;
}
/* Fixup the parent datastructure if needed and resume the child's
main thread. */
- if (!cygheap->fdtab.need_fixup_before ())
- cygheap_setup_for_child_cleanup (newheap, &ch, 0);
- else
+ if (cygheap->fdtab.need_fixup_before ())
{
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
- cygheap_setup_for_child_cleanup (newheap, &ch, 1);
ResumeThread (pi.hThread);
}
@@ -542,15 +521,15 @@ fork ()
{
struct
{
- HANDLE hParent;
dll *first_dll;
bool load_dlls;
+ child_info_fork ch;
} grouped;
MALLOC_CHECK;
debug_printf ("entering");
- grouped.hParent = grouped.first_dll = NULL;
+ grouped.first_dll = NULL;
grouped.load_dlls = 0;
void *esp;
@@ -558,19 +537,20 @@ fork ()
myself->set_has_pgid_children ();
- child_info_fork ch;
- if (ch.subproc_ready == NULL)
+ if (grouped.ch.parent == NULL)
+ return -1;
+ if (grouped.ch.subproc_ready == NULL)
{
system_printf ("unable to allocate subproc_ready event, %E");
return -1;
}
sig_send (NULL, __SIGHOLD);
- int res = setjmp (ch.jmp);
+ int res = setjmp (grouped.ch.jmp);
if (res)
- res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
+ res = fork_child (grouped.ch.parent, grouped.first_dll, grouped.load_dlls);
else
- res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
+ res = fork_parent (grouped.ch.parent, grouped.first_dll, grouped.load_dlls, esp, grouped.ch);
sig_send (NULL, __SIGNOHOLD);
MALLOC_CHECK;
@@ -664,3 +644,14 @@ vfork ()
return pid;
#endif
}
+
+int
+child_copy (HANDLE h, DWORD pid, const char *what, void *child_start, void *child_end)
+{
+ PROCESS_INFORMATION pi;
+ pi.hProcess = h;
+ pi.dwProcessId = pid;
+ pi.hThread = NULL;
+ debug_printf ("%s, start %p, end %p", what, child_start, child_end);
+ return fork_copy (pi, what, child_start, child_end, NULL);
+}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e12c18012..46ef79e39 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -737,12 +737,23 @@ child_info::child_info (unsigned in_cb, child_info_types chtype)
if (chtype != PROC_SPAWN)
subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
sigproc_printf ("subproc_ready %p", subproc_ready);
+ cygheap = ::cygheap;
+ cygheap_max = ::cygheap_max;
+ dwProcessId = myself->dwProcessId;
+ /* Create an inheritable handle to pass to the child process. This will
+ allow the child to duplicate handles from the parent to itself. */
+ parent = NULL;
+ if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &parent, 0, TRUE,
+ DUPLICATE_SAME_ACCESS))
+ system_printf ("couldn't create handle to myself for child, %E");
}
child_info::~child_info ()
{
if (subproc_ready)
CloseHandle (subproc_ready);
+ if (parent)
+ CloseHandle (parent);
}
child_info_fork::child_info_fork () :
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 9faec772e..db8b4d97d 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -390,12 +390,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
else
chtype = PROC_EXEC;
- child_info_spawn ciresrv (chtype);
- si.lpReserved2 = (LPBYTE) &ciresrv;
- si.cbReserved2 = sizeof (ciresrv);
-
- ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
- ciresrv.moreinfo->old_title = NULL;
+ cygheap_exec_info *moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
+ moreinfo->old_title = NULL;
/* CreateProcess takes one long string that is the command line (sigh).
We need to quote any argument that has whitespace or embedded "'s. */
@@ -600,16 +596,16 @@ spawn_guts (const char * prog_arg, const char *const *argv,
return -1;
}
- ciresrv.moreinfo->argc = newargv.argc;
- ciresrv.moreinfo->argv = newargv;
+ moreinfo->argc = newargv.argc;
+ moreinfo->argv = newargv;
if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
- &ciresrv.moreinfo->myself_pinfo, 0,
+ &moreinfo->myself_pinfo, 0,
TRUE, DUPLICATE_SAME_ACCESS))
- ciresrv.moreinfo->myself_pinfo = NULL;
+ moreinfo->myself_pinfo = NULL;
else
- VerifyHandle (ciresrv.moreinfo->myself_pinfo);
+ VerifyHandle (moreinfo->myself_pinfo);
skip_arg_parsing:
PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
@@ -665,13 +661,18 @@ spawn_guts (const char * prog_arg, const char *const *argv,
syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf);
- void *newheap;
-
cygbench ("spawn-guts");
cygheap->fdtab.set_file_pointers_for_exec ();
cygheap->user.deimpersonate ();
+ moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ());
+ child_info_spawn ciresrv (chtype);
+ ciresrv.moreinfo = moreinfo;
+
+ si.lpReserved2 = (LPBYTE) &ciresrv;
+ si.cbReserved2 = sizeof (ciresrv);
+
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
effective vs. real ids.
@@ -682,9 +683,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
&& cygheap->user.saved_gid == cygheap->user.real_gid
&& !cygheap->user.groups.issetgroups ()))
{
- ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
- real_path.iscygexec ());
- newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */
&sec_none_nih,/* process security attrs */
@@ -719,9 +717,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
strcat (wstname, dskname);
si.lpDesktop = wstname;
- ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
- real_path.iscygexec ());
- newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
rc = CreateProcessAsUser (cygheap->user.primary_token (),
runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */
@@ -758,7 +753,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
myself->sendsig = myself->exec_sendsig;
myself->exec_sendsig = NULL;
}
- cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
return -1;
}
@@ -779,13 +773,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
/* Fixup the parent data structures if needed and resume the child's
main thread. */
- if (!cygheap->fdtab.need_fixup_before ())
- cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
- else
- {
- cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
- cygheap_setup_for_child_cleanup (newheap, &ciresrv, 1);
- }
+ if (cygheap->fdtab.need_fixup_before ())
+ cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
if (mode != _P_OVERLAY)
cygpid = cygwin_pid (pi.dwProcessId);
@@ -807,7 +796,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
myself.hProcess = hExeced = pi.hProcess;
strcpy (myself->progname, real_path); // FIXME: race?
sigproc_printf ("new process name %s", myself->progname);
- close_all_files ();
+ close_all_files (true);
/* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
process. So, we need to wait around until the process we've just "execed"
dies. Use our own wait facility to wait for our own pid to exit (there
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index c67bc3799..022282036 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -94,7 +94,7 @@ static int __stdcall stat_worker (const char *name, struct __stat64 *buf,
ensure we don't leave any such files lying around. */
void __stdcall
-close_all_files ()
+close_all_files (bool keep_table)
{
cygheap->fdtab.lock ();
@@ -106,7 +106,8 @@ close_all_files ()
debug_printf ("closing fd %d", i);
#endif
fh->close ();
- cygheap->fdtab.release (i);
+ if (!keep_table)
+ cygheap->fdtab.release (i);
}
if (cygheap->ctty)
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index bbb092e70..6145306ed 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -221,7 +221,7 @@ void uinfo_init (void);
void events_init (void);
void events_terminate (void);
-void __stdcall close_all_files ();
+void __stdcall close_all_files (bool);
/* Globals that handle initialization of winsock in a child process. */
extern HANDLE wsock32_handle;
@@ -298,6 +298,7 @@ extern void multiple_cygwin_problem (const char *, unsigned, unsigned);
extern "C" void vklog (int priority, const char *message, va_list ap);
extern "C" void klog (int priority, const char *message, ...);
+int child_copy (HANDLE, DWORD, const char *, void *, void *);
int symlink_worker (const char *, const char *, bool, bool)
__attribute__ ((regparm (3)));