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/local_includes/dll_init.h')
-rw-r--r--winsup/cygwin/local_includes/dll_init.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/winsup/cygwin/local_includes/dll_init.h b/winsup/cygwin/local_includes/dll_init.h
new file mode 100644
index 000000000..65f4213db
--- /dev/null
+++ b/winsup/cygwin/local_includes/dll_init.h
@@ -0,0 +1,210 @@
+/* dll_init.h
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+struct per_module
+{
+ void (**ctors)(void);
+ void (**dtors)(void);
+ void *data_start;
+ void *data_end;
+ void *bss_start;
+ void *bss_end;
+ int (*main)(int, char **, char **);
+ per_module &operator = (per_process *p)
+ {
+ ctors = p->ctors;
+ dtors = p->dtors;
+ data_start = p->data_start;
+ data_end = p->data_end;
+ bss_start = p->bss_start;
+ bss_end = p->bss_end;
+ main = p->main;
+ return *this;
+ }
+ void run_ctors ();
+ void run_dtors ();
+};
+
+
+typedef enum
+{
+ DLL_NONE,
+ DLL_SELF, /* main-program.exe, cygwin1.dll */
+ DLL_LINK,
+ DLL_LOAD,
+ DLL_ANY
+} dll_type;
+
+struct dll
+{
+ struct dll *next, *prev;
+ per_module p;
+ HMODULE handle;
+ int count;
+ bool has_dtors;
+ dll_type type;
+ long ndeps;
+ dll** deps;
+ DWORD image_size;
+ void* preferred_base;
+ PWCHAR modname;
+ FILE_INTERNAL_INFORMATION fii;
+ PWCHAR forkable_ntname;
+ WCHAR ntname[1]; /* must be the last data member */
+
+ void detach ();
+ int init ();
+ bool stat_real_file_once ();
+ void nominate_forkable (PCWCHAR);
+ bool create_forkable ();
+ void run_dtors ()
+ {
+ if (has_dtors)
+ {
+ has_dtors = 0;
+ p.run_dtors ();
+ }
+ }
+ PWCHAR forkedntname ()
+ {
+ return forkable_ntname && *forkable_ntname ? forkable_ntname : ntname;
+ }
+};
+
+#define MAX_DLL_BEFORE_INIT 100
+
+class dll_list
+{
+ bool forkables_supported ()
+ {
+ return cygwin_shared->forkable_hardlink_support >= 0;
+ }
+ DWORD forkables_dirx_size;
+ bool forkables_created;
+ PWCHAR forkables_dirx_ntname;
+ PWCHAR forkables_mutex_name;
+ HANDLE forkables_mutex;
+ void track_self ();
+ dll *find_by_forkedntname (PCWCHAR ntname);
+ size_t forkable_ntnamesize (dll_type, PCWCHAR fullntname, PCWCHAR modname);
+ void prepare_forkables_nomination ();
+ void update_forkables_needs ();
+ bool update_forkables ();
+ bool create_forkables ();
+ void denominate_forkables ();
+ bool close_mutex ();
+ void try_remove_forkables (PWCHAR dirbuf, size_t dirlen, size_t dirbufsize);
+ void set_forkables_inheritance (bool);
+ void request_forkables ();
+
+ dll *end;
+ dll *hold;
+ dll_type hold_type;
+ static muto protect;
+ /* Use this buffer under loader lock conditions only. */
+ static WCHAR NO_COPY nt_max_path_buffer[NT_MAX_PATH];
+public:
+ static HANDLE ntopenfile (PCWCHAR ntname, NTSTATUS *pstatus = NULL,
+ ULONG openopts = 0, ACCESS_MASK access = 0,
+ HANDLE rootDir = NULL);
+ static bool read_fii (HANDLE fh, PFILE_INTERNAL_INFORMATION pfii);
+ static PWCHAR form_ntname (PWCHAR ntbuf, size_t bufsize, PCWCHAR name);
+ static PWCHAR form_shortname (PWCHAR shortbuf, size_t bufsize, PCWCHAR name);
+ static PWCHAR nt_max_path_buf ()
+ {
+ return nt_max_path_buffer;
+ }
+ static PCWCHAR buffered_shortname (PCWCHAR name)
+ {
+ form_shortname (nt_max_path_buffer, NT_MAX_PATH, name);
+ return nt_max_path_buffer;
+ }
+
+ dll *main_executable;
+ dll start;
+ int loaded_dlls;
+ int reload_on_fork;
+ dll *operator [] (PCWCHAR ntname);
+ dll *alloc (HINSTANCE, per_process *, dll_type);
+ dll *find (void *);
+ void detach (void *);
+ void init ();
+ void load_after_fork (HANDLE);
+ void reserve_space ();
+ void load_after_fork_impl (HANDLE, dll* which, int retries);
+ dll *find_by_modname (PCWCHAR modname);
+ void populate_deps (dll* d);
+ void topsort ();
+ void topsort_visit (dll* d, bool goto_tail);
+ void append (dll* d);
+
+ void release_forkables ();
+ void cleanup_forkables ();
+ bool setup_forkables (bool with_forkables)
+ {
+ if (!forkables_supported ())
+ return true; /* no need to retry fork */
+ if (forkables_created)
+ /* Once created, use forkables in current
+ process chain on first fork try already. */
+ with_forkables = true;
+ if (with_forkables)
+ request_forkables ();
+ return with_forkables;
+ }
+
+ dll *inext ()
+ {
+ while ((hold = hold->next))
+ if (hold_type == DLL_ANY || hold->type == hold_type)
+ break;
+ return hold;
+ }
+
+ dll *istart (dll_type t)
+ {
+ hold_type = t;
+ hold = &start;
+ return inext ();
+ }
+ void guard(bool lockit)
+ {
+ if (lockit)
+ protect.acquire ();
+ else
+ protect.release ();
+ }
+ friend void dll_global_dtors ();
+ dll_list () { protect.init ("dll_list"); }
+};
+
+/* References:
+ http://msdn.microsoft.com/en-us/windows/hardware/gg463125
+ http://msdn.microsoft.com/en-us/library/ms809762.aspx
+*/
+struct pefile
+{
+ IMAGE_DOS_HEADER dos_hdr;
+
+ char* rva (ptrdiff_t offset) { return (char*) this + offset; }
+ PIMAGE_NT_HEADERS pe_hdr () { return (PIMAGE_NT_HEADERS) rva (dos_hdr.e_lfanew); }
+ PIMAGE_OPTIONAL_HEADER optional_hdr () { return &pe_hdr ()->OptionalHeader; }
+ PIMAGE_DATA_DIRECTORY idata_dir (DWORD which)
+ {
+ PIMAGE_OPTIONAL_HEADER oh = optional_hdr ();
+ return (which < oh->NumberOfRvaAndSizes)? oh->DataDirectory + which : 0;
+ }
+};
+
+extern dll_list dlls;
+void dll_global_dtors ();
+
+/* These probably belong in a newlib header but we can keep them here
+ for now. */
+extern "C" int __cxa_atexit(void (*)(void*), void*, void*);
+extern "C" int __cxa_finalize(void*);