aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/lib
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-07-08 04:36:27 +0000
committerChristopher Faylor <me@cgf.cx>2000-07-08 04:36:27 +0000
commit85219b356e249702b845cf667462584945b1735b (patch)
treef8f12ef24cb53fe3cd35b1d89b483a5068544984 /winsup/cygwin/lib
parent77fcb25859f17680c4acd09cf2118cf06492b00b (diff)
downloadnewlib-85219b356e249702b845cf667462584945b1735b.zip
newlib-85219b356e249702b845cf667462584945b1735b.tar.gz
newlib-85219b356e249702b845cf667462584945b1735b.tar.bz2
* 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.
Diffstat (limited to 'winsup/cygwin/lib')
-rw-r--r--winsup/cygwin/lib/_cygwin_crt0_common.cc79
-rw-r--r--winsup/cygwin/lib/crt0.h2
-rw-r--r--winsup/cygwin/lib/cygwin_attach_dll.c13
-rw-r--r--winsup/cygwin/lib/cygwin_crt0.c19
4 files changed, 74 insertions, 39 deletions
diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc b/winsup/cygwin/lib/_cygwin_crt0_common.cc
index 676d466..4ca6dd7 100644
--- a/winsup/cygwin/lib/_cygwin_crt0_common.cc
+++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc
@@ -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;
+
+ 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;
- __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;
+ /* 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" */
diff --git a/winsup/cygwin/lib/crt0.h b/winsup/cygwin/lib/crt0.h
index 74c2c4b..523eedf 100644
--- a/winsup/cygwin/lib/crt0.h
+++ b/winsup/cygwin/lib/crt0.h
@@ -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
diff --git a/winsup/cygwin/lib/cygwin_attach_dll.c b/winsup/cygwin/lib/cygwin_attach_dll.c
index 18d9d7f..09b898b 100644
--- a/winsup/cygwin/lib/cygwin_attach_dll.c
+++ b/winsup/cygwin/lib/cygwin_attach_dll.c
@@ -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);
}
diff --git a/winsup/cygwin/lib/cygwin_crt0.c b/winsup/cygwin/lib/cygwin_crt0.c
index f0656a1..785d9f1 100644
--- a/winsup/cygwin/lib/cygwin_crt0.c
+++ b/winsup/cygwin/lib/cygwin_crt0.c
@@ -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 */
}