* 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.
This commit is contained in:
parent
302cb8165e
commit
ce95c6407e
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
|
@ -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")));
|
||||
}
|
||||
|
@ -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__) :
|
||||
osection_alignment = __section_alignment__;
|
||||
__section_alignment__ = 64 * 1024;
|
||||
.cygheap ALIGN(4096):
|
||||
{
|
||||
*(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) :
|
||||
{
|
||||
__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(.);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 () :
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user