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: 173f8526899cd2c8be4006ad3842287a0cf8d96c (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
/* _cygwin_crt0_common.cc: common crt0 function for cygwin crt0's.

   Copyright 2000, 2001, 2002, 2003, 2004, 2009 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))

/* 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__Znwj");
extern WEAK void *operator new[](std::size_t sz) throw (std::bad_alloc)
			__asm__ ("___real__Znaj");
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__ZnwjRKSt9nothrow_t");
extern WEAK void *operator new[](std::size_t sz, const std::nothrow_t &nt) throw()
			__asm__ ("___real__ZnajRKSt9nothrow_t");
extern WEAK void operator delete(void *p, const std::nothrow_t &nt) throw()
			__asm__ ("___real__ZdlPvRKSt9nothrow_t");
extern WEAK void operator delete[](void *p, const std::nothrow_t &nt) throw()
			__asm__ ("___real__ZdaPvRKSt9nothrow_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"
{
char **environ;
int cygwin_attach_dll (HMODULE, MainFunc);
int cygwin_attach_noncygwin_dll (HMODULE, MainFunc);
int main (int, char **, char **);
int _fmode;
void _pei386_runtime_relocator ();

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__;
  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->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 */
  u->data_start = &_data_start__;
  u->data_end = &_data_end__;
  u->bss_start = &_bss_start__;
  u->bss_end = &_bss_end__;

  _pei386_runtime_relocator ();
  return 1;
}
} /* "C" */