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

_cygwin_crt0_common.cc « lib « cygwin « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b22859ec031285b4720537b78f7f0c47b84f8ea1 (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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* _cygwin_crt0_common.cc: common crt0 function for cygwin crt0's.

   Copyright 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, 2012, 2013
   Red Hat, Inc.

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. */

#include "winsup.h"
#include "crt0.h"
#include "cygwin-cxx.h"

/* Weaken these declarations so the references don't pull in C++ dependencies
   unnecessarily.  */
#define WEAK __attribute__ ((weak))

#ifdef __x86_64__
#define REAL_ZNWX		"__real__Znwm"
#define REAL_ZNAX		"__real__Znam"
#define REAL_ZNWX_NOTHROW_T	"__real__ZnwmRKSt9nothrow_t"
#define REAL_ZNAX_NOTHROW_T	"__real__ZnamRKSt9nothrow_t"
#else
#define REAL_ZNWX		"___real__Znwj"
#define REAL_ZNAX		"___real__Znaj"
#define REAL_ZNWX_NOTHROW_T	"___real__ZnwjRKSt9nothrow_t"
#define REAL_ZNAX_NOTHROW_T	"___real__ZnajRKSt9nothrow_t"
#endif
#define REAL_ZDLPV		_SYMSTR (__real__ZdlPv)
#define REAL_ZDAPV		_SYMSTR (__real__ZdaPv)
#define REAL_ZDLPV_NOTHROW_T	_SYMSTR (__real__ZdlPvRKSt9nothrow_t)
#define REAL_ZDAPV_NOTHROW_T	_SYMSTR (__real__ZdaPvRKSt9nothrow_t)

/* Use asm names to bypass the --wrap that is being applied to redirect all other
   references to these operators toward the redirectors in the Cygwin DLL; this
   way we can record what definitions were visible at final link time but still
   send all calls to the redirectors.  */
extern WEAK void *operator new(std::size_t sz) throw (std::bad_alloc)
			__asm__ (REAL_ZNWX);
extern WEAK void *operator new[](std::size_t sz) throw (std::bad_alloc)
			__asm__ (REAL_ZNAX);
extern WEAK void operator delete(void *p) throw()
			__asm__ (REAL_ZDLPV);
extern WEAK void operator delete[](void *p) throw()
			__asm__ (REAL_ZDAPV);
extern WEAK void *operator new(std::size_t sz, const std::nothrow_t &nt) throw()
			__asm__ (REAL_ZNWX_NOTHROW_T);
extern WEAK void *operator new[](std::size_t sz, const std::nothrow_t &nt) throw()
			__asm__ (REAL_ZNAX_NOTHROW_T);
extern WEAK void operator delete(void *p, const std::nothrow_t &nt) throw()
			__asm__ (REAL_ZDLPV_NOTHROW_T);
extern WEAK void operator delete[](void *p, const std::nothrow_t &nt) throw()
			__asm__ (REAL_ZDAPV_NOTHROW_T);

/* Avoid an info message from linker when linking applications.  */
extern __declspec(dllimport) struct _reent *_impure_ptr;

/* Initialised in _cygwin_dll_entry. */
extern int __dynamically_loaded;

#undef environ

extern "C"
{
#ifndef __x86_64__
char **environ;
#endif
int _fmode;

extern char __RUNTIME_PSEUDO_RELOC_LIST__;
extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
#ifdef __x86_64__
extern char __image_base__;
#define _image_base__ __image_base__
#else
extern char _image_base__;
#endif

struct per_process_cxx_malloc __cygwin_cxx_malloc =
{
  &(operator new), &(operator new[]),
  &(operator delete), &(operator delete[]),
  &(operator new), &(operator new[]),
  &(operator delete), &(operator delete[])
};

/* Set up pointers to various pieces so the dll can then use them,
   and then jump to the dll.  */

int __stdcall
_cygwin_crt0_common (MainFunc f, per_process *u)
{
  per_process *newu = (per_process *) cygwin_internal (CW_USER_DATA);
  bool uwasnull;

  /* u is non-NULL if we are in a DLL, and NULL in the main exe.
     newu is the Cygwin DLL's internal per_process and never NULL.  */
  if (u != NULL)
    uwasnull = false;	/* Caller allocated space for per_process structure.  */
  else
    {
      u = newu;		/* Using DLL built-in per_process.  */
      uwasnull = true;	/* 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.  */
  u->magic_biscuit = sizeof (per_process);

  /* cygwin.dll version number in effect at the time the app was created.  */
  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__;
#ifndef __x86_64__
  u->envptr = &environ;
#endif
  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->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;

  /* 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.  */
  u->initial_sp = (char *) __builtin_frame_address (1);

  /* Remember whatever the user linked his application with - or
     point to entries in the dll.  */
  u->malloc = &malloc;
  u->free = &free;
  u->realloc = &realloc;
  u->calloc = &calloc;

  /* Likewise for the C++ memory operators, if any, but not if we
     were dlopen()'d, as we might get dlclose()'d and that would
     leave stale function pointers behind.    */
  if (newu && newu->cxx_malloc && !__dynamically_loaded)
    {
      /* Inherit what we don't override.  */
#define CONDITIONALLY_OVERRIDE(MEMBER) \
      if (!__cygwin_cxx_malloc.MEMBER) \
	__cygwin_cxx_malloc.MEMBER = newu->cxx_malloc->MEMBER;
      CONDITIONALLY_OVERRIDE(oper_new);
      CONDITIONALLY_OVERRIDE(oper_new__);
      CONDITIONALLY_OVERRIDE(oper_delete);
      CONDITIONALLY_OVERRIDE(oper_delete__);
      CONDITIONALLY_OVERRIDE(oper_new_nt);
      CONDITIONALLY_OVERRIDE(oper_new___nt);
      CONDITIONALLY_OVERRIDE(oper_delete_nt);
      CONDITIONALLY_OVERRIDE(oper_delete___nt);
      /* Now update the resulting set into the global redirectors.  */
      *newu->cxx_malloc = __cygwin_cxx_malloc;
    }

  /* Setup the module handle so fork can get the path name.  */
  u->hmodule = GetModuleHandle (0);

  /* variables for fork */
#ifdef __x86_64__
  u->data_start = &__data_start__;
  u->data_end = &__data_end__;
  u->bss_start = &__bss_start__;
  u->bss_end = &__bss_end__;
#else
  u->data_start = &_data_start__;
  u->data_end = &_data_end__;
  u->bss_start = &_bss_start__;
  u->bss_end = &_bss_end__;
#endif
  u->pseudo_reloc_start = &__RUNTIME_PSEUDO_RELOC_LIST__;
  u->pseudo_reloc_end = &__RUNTIME_PSEUDO_RELOC_LIST_END__;
  u->image_base = &_image_base__;
  /* This is actually a dummy call to force the linker to load this
     symbol for older apps which need it.  */
  _pei386_runtime_relocator (NULL);
  return 1;
}
} /* "C" */