OSDN Git Service

2009-04-17 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / initialize.c
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                           I N I T I A L I Z E                            *
6  *                                                                          *
7  *                          C Implementation File                           *
8  *                                                                          *
9  *          Copyright (C) 1992-2009, Free Software Foundation, Inc.         *
10  *                                                                          *
11  * GNAT is free software;  you can  redistribute it  and/or modify it under *
12  * terms of the  GNU General Public License as published  by the Free Soft- *
13  * ware  Foundation;  either version 3,  or (at your option) any later ver- *
14  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
15  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
16  * or FITNESS FOR A PARTICULAR PURPOSE.                                     *
17  *                                                                          *
18  * As a special exception under Section 7 of GPL version 3, you are granted *
19  * additional permissions described in the GCC Runtime Library Exception,   *
20  * version 3.1, as published by the Free Software Foundation.               *
21  *                                                                          *
22  * You should have received a copy of the GNU General Public License and    *
23  * a copy of the GCC Runtime Library Exception along with this program;     *
24  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
25  * <http://www.gnu.org/licenses/>.                                          *
26  *                                                                          *
27  * GNAT was originally developed  by the GNAT team at  New York University. *
28  * Extensive contributions were provided by Ada Core Technologies Inc.      *
29  *                                                                          *
30  ****************************************************************************/
31
32 /*  This unit provides default implementation for __gnat_initialize ()
33     which is called before the elaboration of the partition. It is provided
34     in a separate file/object so that users can replace it easily.
35     The default implementation should be null on most targets. */
36
37 /* The following include is here to meet the published VxWorks requirement
38    that the __vxworks header appear before any other include. */
39 #ifdef __vxworks
40 #include "vxWorks.h"
41 #endif
42
43 #ifdef IN_RTS
44 #include "tconfig.h"
45 #include "tsystem.h"
46 /* We don't have libiberty, so use malloc.  */
47 #define xmalloc(S) malloc (S)
48 #define xrealloc(V,S) realloc (V,S)
49 #else
50 #include "config.h"
51 #include "system.h"
52 #endif
53
54 #include "raise.h"
55
56 /******************************************/
57 /* __gnat_initialize (NT-mingw32 Version) */
58 /******************************************/
59
60 #if defined (__MINGW32__)
61 #include "mingw32.h"
62 #include <windows.h>
63
64 extern void __gnat_init_float (void);
65 extern void __gnat_install_SEH_handler (void *);
66
67 extern int gnat_argc;
68 extern char **gnat_argv;
69
70 #ifndef RTX
71 /* Do not define for RTX since it is only used for creating child processes
72    which is not supported in RTX. */
73 extern void __gnat_plist_init (void);
74 #endif
75
76 #ifdef GNAT_UNICODE_SUPPORT
77
78 #define EXPAND_ARGV_RATE 128
79
80 static void
81 append_arg (int *index, LPWSTR value, char ***argv, int *last)
82 {
83   int size;
84
85   if (*last < *index)
86     {
87       *last += EXPAND_ARGV_RATE;
88       *argv = (char **) xrealloc (*argv, (*last) * sizeof (char *));
89     }
90
91   size = WS2SC (NULL, value, 0);
92   (*argv)[*index] = (char *) xmalloc (size + 1);
93   WS2SC ((*argv)[*index], value, size);
94
95   (*index)++;
96 }
97 #endif
98
99 void
100 __gnat_initialize (void *eh)
101 {
102    /* Initialize floating-point coprocessor. This call is needed because
103       the MS libraries default to 64-bit precision instead of 80-bit
104       precision, and we require the full precision for proper operation,
105       given that we have set Max_Digits etc with this in mind */
106    __gnat_init_float ();
107
108 #ifdef GNAT_UNICODE_SUPPORT
109    /* Set current code page for filenames handling. */
110    {
111      char *codepage = getenv ("GNAT_CODE_PAGE");
112
113      /* Default code page is UTF-8.  */
114      CurrentCodePage = CP_UTF8;
115
116      if (codepage != NULL)
117        if (strcmp (codepage, "CP_ACP") == 0)
118          CurrentCodePage = CP_ACP;
119        else if (strcmp (codepage, "CP_UTF8") == 0)
120          CurrentCodePage = CP_UTF8;
121    }
122
123    /* Adjust gnat_argv to support Unicode characters. */
124    {
125      LPWSTR *wargv;
126      int wargc;
127      int k;
128      int last;
129      int argc_expanded = 0;
130      TCHAR result [MAX_PATH];
131
132      wargv = CommandLineToArgvW (GetCommandLineW(), &wargc);
133
134      if (wargv != NULL)
135        {
136          /* Set gnat_argv with arguments encoded in UTF-8. */
137          last = wargc + 1;
138          gnat_argv = (char **) xmalloc ((last) * sizeof (char *));
139
140          /* argv[0] is the executable full path-name. */
141
142          SearchPath (NULL, wargv[0], _T(".exe"), MAX_PATH, result, NULL);
143          append_arg (&argc_expanded, result, &gnat_argv, &last);
144
145          for (k=1; k<wargc; k++)
146            {
147              /* Check for wildcard expansion. */
148              if (_tcsstr (wargv[k], _T("?")) != 0 ||
149                  _tcsstr (wargv[k], _T("*")) != 0)
150                {
151                  /* Wilcards are present, append all corresponding matches. */
152                  WIN32_FIND_DATA FileData;
153                  HANDLE hDir = FindFirstFile (wargv[k], &FileData);
154
155                  if (hDir == INVALID_HANDLE_VALUE)
156                    {
157                      /* No match, append arg as-is. */
158                      append_arg (&argc_expanded, wargv[k], &gnat_argv, &last);
159                    }
160                  else
161                    {
162                      /* Append first match and all remaining ones.  */
163
164                      do {
165                        append_arg (&argc_expanded,
166                                    FileData.cFileName, &gnat_argv, &last);
167                      } while (FindNextFile (hDir, &FileData));
168
169                      FindClose (hDir);
170                    }
171                }
172              else
173                {
174                  /*  No wildcard. Store parameter as-is. */
175                  append_arg (&argc_expanded, wargv[k], &gnat_argv, &last);
176                }
177            }
178
179          LocalFree (wargv);
180          gnat_argc = argc_expanded;
181          gnat_argv = (char **) xrealloc
182            (gnat_argv, argc_expanded * sizeof (char *));
183        }
184    }
185 #endif
186
187    /* Note that we do not activate this for the compiler itself to avoid a
188       bootstrap path problem.  Older version of gnatbind will generate a call
189       to __gnat_initialize() without argument. Therefore we cannot use eh in
190       this case.  It will be possible to remove the following #ifdef at some
191       point.  */
192 #ifdef IN_RTS
193    /* Install the Structured Exception handler.  */
194    if (eh)
195      __gnat_install_SEH_handler (eh);
196 #endif
197 }
198
199 /******************************************/
200 /* __gnat_initialize (init_float version) */
201 /******************************************/
202
203 #elif defined (__Lynx__) || defined (__FreeBSD__) || defined(__NetBSD__) \
204   || defined (__OpenBSD__)
205
206 extern void __gnat_init_float (void);
207
208 void
209 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
210 {
211    __gnat_init_float ();
212 }
213
214 /***************************************/
215 /* __gnat_initialize (VxWorks Version) */
216 /***************************************/
217
218 #elif defined(__vxworks)
219
220 extern void __gnat_init_float (void);
221
222 void
223 __gnat_initialize (void *eh)
224 {
225   __gnat_init_float ();
226
227   /* On targets where we use the ZCX scheme, we need to register the frame
228      tables at load/startup time.
229
230      For applications loaded as a set of "modules", the crtstuff objects
231      linked in (crtbegin.o/end.o) are tailored to provide this service
232      automatically, a-la C++ constructor fashion, triggered by the VxWorks
233      loader thanks to a special variable declaration in crtbegin.o (_ctors).
234
235      Automatic de-registration is handled symmetrically, a-la C++ destructor
236      fashion (with a _dtors variable also in crtbegin.o) triggered by the
237      dynamic unloader.
238
239      Note that since the tables shall be registered against a common
240      data structure, libgcc should be one of the modules (vs being partially
241      linked against all the others at build time) and shall be loaded first.
242
243      For applications linked with the kernel, the scheme above would lead to
244      duplicated symbols because the VxWorks kernel build "munches" by default,
245      so we link against crtbeginT.o instead of crtbegin.o, which doesn't
246      include the special variables. We know which set of crt objects is used
247      thanks to a boolean indicator present in both sets (__module_has_ctors),
248      and directly call the appropriate function here in the not-automatic
249      case. We'll never unload that, so there is no de-registration to worry
250      about.
251
252      For whole applications loaded as a single module, we may use one scheme
253      or the other, except for the mixed Ada/C++ case in which the first scheme
254      would fail for the same reason as in the linked-with-kernel situation.
255
256      Selecting the crt set with the ctors/dtors capabilities (first scheme
257      above) is triggered by adding "-dynamic" to the gcc *link* command line
258      options. Selecting the other set is achieved by using "-static" instead.
259
260      This is a first approach, tightly synchronized with a number of GCC
261      configuration and crtstuff changes. We need to ensure that those changes
262      are there to activate this circuitry.  */
263
264 #if (__GNUC__ >= 3) && (defined (_ARCH_PPC) || defined (__ppc))
265  {
266    /* The scheme described above is only useful for the actual ZCX case, and
267       we don't want any reference to the crt provided symbols otherwise.  We
268       may not link with any of the crt objects in the non-ZCX case, e.g. from
269       documented procedures instructing the use of -nostdlib, and references
270       to the ctors symbols here would just remain unsatisfied.
271
272       We have no way to avoid those references in the right conditions in this
273       C module, because we have nothing like a IN_ZCX_RTS macro.  This aspect
274       is then deferred to an Ada routine, which can do that based on a test
275       against a constant System flag value.  */
276
277    extern void __gnat_vxw_setup_for_eh (void);
278    __gnat_vxw_setup_for_eh ();
279  }
280 #endif
281 }
282
283 #elif defined(_T_HPUX10) || (!defined(IN_RTS) && defined(_X_HPUX10))
284
285 /************************************************/
286 /* __gnat_initialize (PA-RISC HP-UX 10 Version) */
287 /************************************************/
288
289 extern void __main (void);
290
291 void
292 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
293 {
294   __main ();
295 }
296
297 #else
298
299 /* For all other versions of GNAT, the initialize routine and handler
300    installation do nothing */
301
302 /***************************************/
303 /* __gnat_initialize (Default Version) */
304 /***************************************/
305
306 void
307 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
308 {
309 }
310
311 #endif