Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dll_init.h « cygwin « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4897c420ff0bb2cf99eb141e515cd1599db14d96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* 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
{
#ifdef __i386__
  char ***envptr;
#endif
  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)
  {
#ifdef __i386__
    envptr = p->envptr;
#endif
    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_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;
  WCHAR ntname[1]; /* must be the last data member */
  void detach ();
  int init ();
  void run_dtors ()
  {
    if (has_dtors)
      {
	has_dtors = 0;
	p.run_dtors ();
      }
  }
};

#define MAX_DLL_BEFORE_INIT     100

class dll_list
{
  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 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 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);

  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*);