* external.cc (cygwin_internal): Export __cygwin_user_data.
* include/sys/cygwin.h: Allow definition of per_process even when not compiling with C++. (cygwin_getinfo_types): Add CW_USER_DATA. * lib/_cygwin_crt0_common.cc (_cygwin_crt0_common): Get __cygwin_user_data pointer from cygwin_internal. If it doesn't exist, return failure. Use either this pointer or passed in pointer throughout. Clear forkee. * lib/crt0.h: Accomodate argument changes to _cygwin_crt0_common. * lib/cygwin_attach_dll.c (cygwin_attach_dll): Reorganize to allow use of newer binaries with older DLLs. Detect older DLLs when _cygwin_crt0_common returns 0 and allocate space for a per_process structure on the stack. * lib/cygwin_crt0.c (cygwin_crt0): Ditto.
This commit is contained in:
@@ -13,8 +13,6 @@ details. */
|
||||
#include <reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern __declspec(dllimport) per_process __cygwin_user_data;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
char **environ;
|
||||
@@ -28,49 +26,70 @@ int _fmode;
|
||||
/* Set up pointers to various pieces so the dll can then use them,
|
||||
and then jump to the dll. */
|
||||
|
||||
void
|
||||
_cygwin_crt0_common (MainFunc f)
|
||||
int __stdcall
|
||||
_cygwin_crt0_common (MainFunc f, per_process *u)
|
||||
{
|
||||
/* This is used to record what the initial sp was. The value is needed
|
||||
when copying the parent's stack to the child during a fork. */
|
||||
int onstack;
|
||||
DWORD newu;
|
||||
int uwasnull;
|
||||
|
||||
if (u != NULL)
|
||||
uwasnull = 0; /* Caller allocated space for per_process structure */
|
||||
else if ((newu = cygwin_internal (CW_USER_DATA)) == (DWORD) -1)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
u = (per_process *) newu; /* Using DLL built-in per_process */
|
||||
uwasnull = 1; /* Remember for later */
|
||||
}
|
||||
|
||||
/* The version numbers are the main source of compatibility checking.
|
||||
As a backup to them, we use the size of the per_process struct. */
|
||||
__cygwin_user_data.magic_biscuit = sizeof (per_process);
|
||||
u->magic_biscuit = sizeof (per_process);
|
||||
|
||||
/* cygwin.dll version number in effect at the time the app was created. */
|
||||
__cygwin_user_data.dll_major = CYGWIN_VERSION_DLL_MAJOR;
|
||||
__cygwin_user_data.dll_minor = CYGWIN_VERSION_DLL_MINOR;
|
||||
__cygwin_user_data.api_major = CYGWIN_VERSION_API_MAJOR;
|
||||
__cygwin_user_data.api_minor = CYGWIN_VERSION_API_MINOR;
|
||||
u->dll_major = CYGWIN_VERSION_DLL_MAJOR;
|
||||
u->dll_minor = CYGWIN_VERSION_DLL_MINOR;
|
||||
u->api_major = CYGWIN_VERSION_API_MAJOR;
|
||||
u->api_minor = CYGWIN_VERSION_API_MINOR;
|
||||
|
||||
__cygwin_user_data.ctors = &__CTOR_LIST__;
|
||||
__cygwin_user_data.dtors = &__DTOR_LIST__;
|
||||
__cygwin_user_data.envptr = &environ;
|
||||
_impure_ptr = __cygwin_user_data.impure_ptr;
|
||||
__cygwin_user_data.main = f;
|
||||
__cygwin_user_data.premain[0] = cygwin_premain0;
|
||||
__cygwin_user_data.premain[1] = cygwin_premain1;
|
||||
__cygwin_user_data.premain[2] = cygwin_premain2;
|
||||
__cygwin_user_data.premain[3] = cygwin_premain3;
|
||||
__cygwin_user_data.fmode_ptr = &_fmode;
|
||||
__cygwin_user_data.initial_sp = (char *) &onstack;
|
||||
u->ctors = &__CTOR_LIST__;
|
||||
u->dtors = &__DTOR_LIST__;
|
||||
u->envptr = &environ;
|
||||
if (uwasnull)
|
||||
_impure_ptr = u->impure_ptr; /* Use field initialized in newer DLLs. */
|
||||
else
|
||||
u->impure_ptr_ptr = &_impure_ptr; /* Older DLLs need this. */
|
||||
|
||||
u->forkee = 0; /* This should only be set in dcrt0.cc
|
||||
when the process is actually forked */
|
||||
u->main = f;
|
||||
|
||||
/* These functions are executed prior to main. They are just stubs unless the
|
||||
user overrides them. */
|
||||
u->premain[0] = cygwin_premain0;
|
||||
u->premain[1] = cygwin_premain1;
|
||||
u->premain[2] = cygwin_premain2;
|
||||
u->premain[3] = cygwin_premain3;
|
||||
u->fmode_ptr = &_fmode;
|
||||
u->initial_sp = (char *) __builtin_frame_address (1);
|
||||
|
||||
/* Remember whatever the user linked his application with - or
|
||||
point to entries in the dll. */
|
||||
__cygwin_user_data.malloc = &malloc;
|
||||
__cygwin_user_data.free = &free;
|
||||
__cygwin_user_data.realloc = &realloc;
|
||||
__cygwin_user_data.calloc = &calloc;
|
||||
u->malloc = &malloc;
|
||||
u->free = &free;
|
||||
u->realloc = &realloc;
|
||||
u->calloc = &calloc;
|
||||
|
||||
/* Setup the module handle so fork can get the path name. */
|
||||
__cygwin_user_data.hmodule = GetModuleHandle (0);
|
||||
u->hmodule = GetModuleHandle (0);
|
||||
|
||||
/* variables for fork */
|
||||
__cygwin_user_data.data_start = &_data_start__;
|
||||
__cygwin_user_data.data_end = &_data_end__;
|
||||
__cygwin_user_data.bss_start = &_bss_start__;
|
||||
__cygwin_user_data.bss_end = &_bss_end__;
|
||||
u->data_start = &_data_start__;
|
||||
u->data_end = &_data_end__;
|
||||
u->bss_start = &_bss_start__;
|
||||
u->bss_end = &_bss_end__;
|
||||
return 1;
|
||||
}
|
||||
} /* "C" */
|
||||
|
Reference in New Issue
Block a user