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
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/dll_init.cc')
-rw-r--r--winsup/cygwin/dll_init.cc499
1 files changed, 0 insertions, 499 deletions
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
deleted file mode 100644
index a1d217576..000000000
--- a/winsup/cygwin/dll_init.cc
+++ /dev/null
@@ -1,499 +0,0 @@
-/* dll_init.cc
-
- Copyright 1998, 1999, 2000 Cygnus Solutions.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include <stdlib.h>
-#include "winsup.h"
-#include "exceptions.h"
-#include "dll_init.h"
-
-extern void __stdcall check_sanity_and_sync (per_process *);
-
-#ifdef _MT_SAFE
-extern ResourceLocks _reslock NO_COPY;
-extern MTinterface _mtinterf NO_COPY;
-#endif /*_MT_SAFE*/
-
-/* WARNING: debug can't be called before init !!!! */
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// the private structure
-
-typedef enum { NONE, LINK, LOAD } dllType;
-
-struct dll
-{
- per_process *p;
- HMODULE handle;
- const char *name;
- dllType type;
-};
-
-//-----------------------------------------------------------------------------
-
-#define MAX_DLL_BEFORE_INIT 100 // FIXME: enough ???
-static dll _list_before_init[MAX_DLL_BEFORE_INIT];
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// local variables
-
-static DllList _the;
-static int _last = 0;
-static int _max = MAX_DLL_BEFORE_INIT;
-static dll *_list = _list_before_init;
-static int _initCalled = 0;
-static int _numberOfOpenedDlls = 0;
-static int _forkeeMustReloadDlls = 0;
-static int _in_forkee = 0;
-static const char *_dlopenedLib = 0;
-static int _dlopenIndex = -1;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-static int __dll_global_dtors_recorded = 0;
-
-static void
-__dll_global_dtors()
-{
- _the.doGlobalDestructorsOfDlls();
-}
-
-static void
-doGlobalCTORS (per_process *p)
-{
- void (**pfunc)() = p->ctors;
-
- /* Run ctors backwards, so skip the first entry and find how many
- there are, then run them. */
-
- if (pfunc)
- {
- int i;
- for (i = 1; pfunc[i]; i++);
-
- for (int j = i - 1; j > 0; j-- )
- (pfunc[j]) ();
- }
-}
-
-static void
-doGlobalDTORS (per_process *p)
-{
- if (!p)
- return;
- void (**pfunc)() = p->dtors;
- for (int i = 1; pfunc[i]; i++)
- (pfunc[i]) ();
-}
-
-#define INC 500
-
-static int
-add (HMODULE h, char *name, per_process *p, dllType type)
-{
- int ret = -1;
-
- if (p)
- check_sanity_and_sync (p);
-
- if (_last == _max)
- {
- if (!_initCalled) // we try to load more than MAX_DLL_BEFORE_INIT
- {
- small_printf ("try to load more dll than max allowed=%d\n",
- MAX_DLL_BEFORE_INIT);
- ExitProcess (1);
- }
-
- dll* newArray = new dll[_max+INC];
- if (_list)
- {
- memcpy (newArray, _list, _max * sizeof (dll));
- if (_list != _list_before_init)
- delete []_list;
- }
- _list = newArray;
- _max += INC;
- }
-
- _list[_last].name = name && type == LOAD ? strdup (name) : NULL;
- _list[_last].handle = h;
- _list[_last].p = p;
- _list[_last].type = type;
-
- ret = _last++;
- return ret;
-}
-
-static int
-initOneDll (per_process *p)
-{
- /* global variable user_data must be initialized */
- if (user_data == NULL)
- {
- small_printf ("WARNING: process not inited while trying to init a DLL!\n");
- return 0;
- }
-
- /* init impure_ptr */
- *(p->impure_ptr_ptr) = *(user_data->impure_ptr_ptr);
-
- /* FIXME: init environment (useful?) */
- *(p->envptr) = *(user_data->envptr);
-
- /* FIXME: need other initializations? */
-
- int ret = 1;
- if (!_in_forkee)
- {
- /* global contructors */
- doGlobalCTORS (p);
-
- /* entry point of dll (use main of per_process with null args...) */
- if (p->main)
- ret = (*(p->main)) (0, 0, 0);
- }
-
- return ret;
-}
-
-DllList&
-DllList::the ()
-{
- return _the;
-}
-
-void
-DllList::currentDlOpenedLib (const char *name)
-{
- if (_dlopenedLib != 0)
- small_printf ("WARNING: previous dlopen of %s wasn't correctly performed\n", _dlopenedLib);
- _dlopenedLib = name;
- _dlopenIndex = -1;
-}
-
-int
-DllList::recordDll (HMODULE h, per_process *p)
-{
- int ret = -1;
-
- /* debug_printf ("Record a dll p=%p\n", p); see WARNING */
- dllType type = LINK;
- if (_initCalled)
- {
- type = LOAD;
- _numberOfOpenedDlls++;
- forkeeMustReloadDlls (1);
- }
-
- if (_in_forkee)
- {
- ret = 0; // Just a flag
- goto out;
- }
-
- char buf[MAX_PATH];
- GetModuleFileName (h, buf, MAX_PATH);
-
- if (type == LOAD && _dlopenedLib !=0)
- {
- // it is not the current dlopened lib
- // so we insert one empty lib to preserve place for current dlopened lib
- if (!strcasematch (_dlopenedLib, buf))
- {
- if (_dlopenIndex == -1)
- _dlopenIndex = add (0, 0, 0, NONE);
- ret = add (h, buf, p, type);
- }
- else // it is the current dlopened lib
- {
- if (_dlopenIndex != -1)
- {
- _list[_dlopenIndex].handle = h;
- _list[_dlopenIndex].p = p;
- _list[_dlopenIndex].type = type;
- ret = _dlopenIndex;
- _dlopenIndex = -1;
- }
- else // it this case the dlopened lib doesn't need other lib
- ret = add (h, buf, p, type);
- _dlopenedLib = 0;
- }
- }
- else
- ret = add (h, buf, p, type);
-
-out:
- if (_initCalled) // main module is already initialized
- {
- if (!initOneDll (p))
- ret = -1;
- }
- return ret;
-}
-
-void
-DllList::detachDll (int dll_index)
-{
- if (dll_index != -1)
- {
- dll *aDll = &(_list[dll_index]);
- doGlobalDTORS (aDll->p);
- if (aDll->type == LOAD)
- _numberOfOpenedDlls--;
- aDll->type = NONE;
- }
- else
- small_printf ("WARNING: try to detach an already detached dll ...\n");
-}
-
-void
-DllList::initAll ()
-{
- // init for destructors
- // because initAll isn't called in forked process, this exit function will
- // be recorded only once
- if (!__dll_global_dtors_recorded)
- {
- atexit (__dll_global_dtors);
- __dll_global_dtors_recorded = 1;
- }
-
- if (!_initCalled)
- {
- debug_printf ("call to DllList::initAll");
- for (int i = 0; i < _last; i++)
- {
- per_process *p = _list[i].p;
- if (p)
- initOneDll (p);
- }
- _initCalled = 1;
- }
-}
-
-void
-DllList::doGlobalDestructorsOfDlls ()
-{
- // global destructors in reverse order
- for (int i = _last - 1; i >= 0; i--)
- {
- if (_list[i].type != NONE)
- {
- per_process *p = _list[i].p;
- if (p)
- doGlobalDTORS (p);
- }
- }
-}
-
-int
-DllList::numberOfOpenedDlls ()
-{
- return _numberOfOpenedDlls;
-}
-
-int
-DllList::forkeeMustReloadDlls ()
-{
- return _forkeeMustReloadDlls;
-}
-
-void
-DllList::forkeeMustReloadDlls (int i)
-{
- _forkeeMustReloadDlls = i;
-}
-
-#define A64K (64 * 1024)
-
-/* Mark every memory address up to "here" as reserved. This may force
- Windows NT to load a DLL in the next available, lowest slot. */
-void
-reserve_upto (const char *name, DWORD here)
-{
- DWORD size;
- MEMORY_BASIC_INFORMATION mb;
- for (DWORD start = 0x10000; start < here; start += size)
- if (!VirtualQuery ((void *) start, &mb, sizeof (mb)))
- size = 64 * 1024;
- else
- {
- size = A64K * ((mb.RegionSize + A64K - 1) / A64K);
- start = A64K * (((DWORD) mb.BaseAddress + A64K - 1) / A64K);
-
- if (start + size > here)
- size = here - start;
- if (mb.State == MEM_FREE &&
- !VirtualAlloc ((void *) start, size, MEM_RESERVE, PAGE_NOACCESS))
- api_fatal ("couldn't allocate memory %p(%d) for '%s' alignment, %E\n",
- start, size, name);
- }
-}
-
-/* Release all of the memory previously allocated by "upto" above.
- Note that this may also free otherwise reserved memory. If that becomes
- a problem, we'll have to keep track of the memory that we reserve above. */
-void
-release_upto (const char *name, DWORD here)
-{
- DWORD size;
- MEMORY_BASIC_INFORMATION mb;
- for (DWORD start = 0x10000; start < here; start += size)
- if (!VirtualQuery ((void *) start, &mb, sizeof (mb)))
- size = 64 * 1024;
- else
- {
- size = mb.RegionSize;
- if (!(mb.State == MEM_RESERVE && mb.AllocationProtect == PAGE_NOACCESS &&
- ((void *) start < user_data->heapbase || (void *) start > user_data->heaptop)))
- continue;
- if (!VirtualFree ((void *) start, 0, MEM_RELEASE))
- api_fatal ("couldn't release memory %p(%d) for '%s' alignment, %E\n",
- start, size, name);
- }
-}
-
-/* Reload DLLs after a fork. Iterates over the list of dynamically loaded DLLs
- and attempts to load them in the same place as they were loaded in the parent. */
-void
-DllList::forkeeLoadDlls ()
-{
- _initCalled = 1;
- _in_forkee = 1;
- int try2 = 0;
- for (int i = 0; i < _last; i++)
- if (_list[i].type == LOAD)
- {
- const char *name = _list[i].name;
- HMODULE handle = _list[i].handle;
- HMODULE h = LoadLibraryEx (name, NULL, DONT_RESOLVE_DLL_REFERENCES);
-
- if (h == handle)
- {
- FreeLibrary (h);
- LoadLibrary (name);
- }
- else if (try2)
- api_fatal ("unable to remap %s to same address as parent -- %p", name, h);
- else
- {
- FreeLibrary (h);
- reserve_upto (name, (DWORD) handle);
- try2 = 1;
- i--;
- continue;
- }
- if (try2)
- {
- release_upto (name, (DWORD) handle);
- try2 = 0;
- }
- }
- _in_forkee = 0;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// iterators
-
-DllListIterator::DllListIterator (int type) : _type (type), _index (-1)
-{
- operator++ ();
-}
-
-DllListIterator::~DllListIterator ()
-{
-}
-
-DllListIterator::operator per_process* ()
-{
- return _list[index ()].p;
-}
-
-void
-DllListIterator::operator++ ()
-{
- _index++;
- while (_index < _last && (int) (_list[_index].type) != _type)
- _index++;
- if (_index == _last)
- _index = -1;
-}
-
-LinkedDllIterator::LinkedDllIterator () : DllListIterator ((int) LINK)
-{
-}
-
-LinkedDllIterator::~LinkedDllIterator ()
-{
-}
-
-LoadedDllIterator::LoadedDllIterator () : DllListIterator ((int) LOAD)
-{
-}
-
-LoadedDllIterator::~LoadedDllIterator ()
-{
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// the extern symbols
-
-extern "C"
-{
- /* This is an exported copy of environ which can be used by DLLs
- which use cygwin.dll. */
- extern struct _reent reent_data;
-};
-
-extern "C"
-int
-dll_dllcrt0 (HMODULE h, per_process *p)
-{
- /* Partially initialize Cygwin guts for non-cygwin apps. */
- if (dynamically_loaded && (! user_data || user_data->magic_biscuit == 0))
- {
- dll_crt0 (p);
- }
- return _the.recordDll (h, p);
-}
-
-/* OBSOLETE: This function is obsolescent and will go away in the
- future. Cygwin can now handle being loaded from a noncygwin app
- using the same entry point. */
-
-extern "C"
-int
-dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
-{
- return dll_dllcrt0 (h, p);
-}
-
-extern "C"
-void
-cygwin_detach_dll (int dll_index)
-{
- _the.detachDll (dll_index);
-}
-
-extern "C"
-void
-dlfork (int val)
-{
- _the.forkeeMustReloadDlls (val);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------