* 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:
Christopher Faylor 2000-07-08 04:36:27 +00:00
parent 77fcb25859
commit 85219b356e
7 changed files with 96 additions and 42 deletions

View File

@ -1,3 +1,20 @@
Sat Jul 8 00:15:01 2000 Christopher Faylor <cgf@cygnus.com>
* 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.
Fri Jul 7 10:31:00 2000 Corinna Vinschen <corinna@vinschen.de>
* include/sys/cygwin.h: Hide internal data types in per_process

View File

@ -100,6 +100,9 @@ cygwin_internal (cygwin_getinfo_types t, ...)
cygwin_shared->mount.import_v1_mounts ();
return 0;
case CW_USER_DATA:
return (DWORD) &__cygwin_user_data;
default:
return (DWORD) -1;
}

View File

@ -36,7 +36,6 @@ extern void cygwin_premain1 (int argc, char **argv);
extern void cygwin_premain2 (int argc, char **argv);
extern void cygwin_premain3 (int argc, char **argv);
#ifdef __cplusplus
/* This lives in the app and is initialized before jumping into the DLL.
It should only contain stuff which the user's process needs to see, or
which is needed before the user pointer is initialized, or is needed to
@ -126,7 +125,6 @@ struct per_process
struct _reent *impure_ptr;
};
#define per_process_overwrite ((unsigned) &(((struct per_process *) NULL)->resourcelocks))
#endif /* __cplusplus */
#ifdef _PATH_PASSWD
extern HANDLE cygwin_logon_user (const struct passwd *, const char *);
@ -152,7 +150,8 @@ typedef enum
CW_SETPINFO,
CW_SETTHREADNAME,
CW_GETVERSIONINFO,
CW_READ_V1_MOUNT_TABLES
CW_READ_V1_MOUNT_TABLES,
CW_USER_DATA
} cygwin_getinfo_types;
struct external_pinfo

View File

@ -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" */

View File

@ -14,7 +14,7 @@ extern "C" {
struct per_process;
typedef int (*MainFunc) (int argc, char *argv[], char **env);
void _cygwin_crt0_common (MainFunc);
int __stdcall _cygwin_crt0_common (MainFunc, struct per_process *);
int dll_dllcrt0 (HMODULE, struct per_process *);
#ifdef __cplusplus

View File

@ -8,15 +8,24 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#undef __INSIDE_CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
#include "crt0.h"
/* for a loaded dll */
int
cygwin_attach_dll (HMODULE h, MainFunc f)
{
_cygwin_crt0_common (f);
struct per_process *u;
if (_cygwin_crt0_common (f, NULL))
u = NULL; /* Newer DLL. Use DLL internal per_process. */
else /* Older DLL. Provide a per_process */
{
u = (struct per_process *) alloca (sizeof (*u));
(void) _cygwin_crt0_common (f, u);
}
/* jump into the dll. */
return dll_dllcrt0 (h, NULL);
return dll_dllcrt0 (h, u);
}

View File

@ -1,4 +1,4 @@
/* crt0.cc: crt0 for libc
/* cygwin_crt0.cc: crt0 for cygwin
Copyright 2000 Cygnus Solutions.
@ -8,17 +8,24 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#undef __INSIDE_CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
#include "crt0.h"
extern void __stdcall _dll_crt0 (void) __declspec (dllimport) __attribute ((noreturn));
extern void dll_crt0__FP11per_process (struct per_process *) __declspec (dllimport) __attribute ((noreturn));
/* for main module */
void
cygwin_crt0 (MainFunc f)
{
_cygwin_crt0_common (f);
/* Jump into the dll. */
_dll_crt0 ();
struct per_process *u;
if (_cygwin_crt0_common (f, NULL))
u = NULL; /* Newer DLL. Use DLL internal per_process. */
else /* Older DLL. Provide a per_process */
{
u = (struct per_process *) alloca (sizeof (*u));
(void) _cygwin_crt0_common (f, u);
}
dll_crt0__FP11per_process (u); /* Jump into the dll, never to return */
}