OSDN Git Service

* gcc-interface/trans.c (Call_to_gnu): Robustify test for function case
[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-2011, 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 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 /* The following include is here to meet the published VxWorks requirement
42    that the __vxworks header appear before any other include.  */
43 #ifdef __vxworks
44 #include "vxWorks.h"
45 #endif
46
47 #ifdef IN_RTS
48 #include "tconfig.h"
49 #include "tsystem.h"
50 /* We don't have libiberty, so use malloc.  */
51 #define xmalloc(S) malloc (S)
52 #define xrealloc(V,S) realloc (V,S)
53 #else
54 #include "config.h"
55 #include "system.h"
56 #endif
57
58 #include "raise.h"
59
60 /******************************************/
61 /* __gnat_initialize (NT-mingw32 Version) */
62 /******************************************/
63
64 #if defined (__MINGW32__)
65 #include "mingw32.h"
66 #include <windows.h>
67
68 extern void __gnat_init_float (void);
69 extern void __gnat_install_SEH_handler (void *);
70
71 extern int gnat_argc;
72 extern char **gnat_argv;
73
74 #ifdef GNAT_UNICODE_SUPPORT
75
76 #define EXPAND_ARGV_RATE 128
77
78 static void
79 append_arg (int *index, LPWSTR dir, LPWSTR value,
80             char ***argv, int *last, int quoted)
81 {
82   int size;
83   LPWSTR fullvalue;
84   int vallen = _tcslen (value);
85   int dirlen;
86
87   if (dir == NULL)
88     {
89       /* no dir prefix */
90       dirlen = 0;
91       fullvalue = xmalloc ((vallen + 1) * sizeof(TCHAR));
92     }
93   else
94     {
95       /* Add dir first */
96       dirlen = _tcslen (dir);
97
98       fullvalue = xmalloc ((dirlen + vallen + 1) * sizeof(TCHAR));
99       _tcscpy (fullvalue, dir);
100     }
101
102   /* Append value */
103
104   if (quoted)
105     {
106       _tcsncpy (fullvalue + dirlen, value + 1, vallen - 1);
107       fullvalue [dirlen + vallen - sizeof(TCHAR)] = _T('\0');
108     }
109   else
110     _tcscpy (fullvalue + dirlen, value);
111
112   if (*last <= *index)
113     {
114       *last += EXPAND_ARGV_RATE;
115       *argv = (char **) xrealloc (*argv, (*last) * sizeof (char *));
116     }
117
118   size = WS2SC (NULL, fullvalue, 0);
119   (*argv)[*index] = (char *) xmalloc (size + sizeof(TCHAR));
120   WS2SC ((*argv)[*index], fullvalue, size);
121
122   free (fullvalue);
123
124   (*index)++;
125 }
126 #endif
127
128 void
129 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
130 {
131    /* Initialize floating-point coprocessor. This call is needed because
132       the MS libraries default to 64-bit precision instead of 80-bit
133       precision, and we require the full precision for proper operation,
134       given that we have set Max_Digits etc with this in mind */
135    __gnat_init_float ();
136
137 #ifdef GNAT_UNICODE_SUPPORT
138    /* Set current code page for filenames handling. */
139    {
140      char *codepage = getenv ("GNAT_CODE_PAGE");
141
142      /* Default code page is UTF-8.  */
143      CurrentCodePage = CP_UTF8;
144
145      if (codepage != NULL)
146        {
147          if (strcmp (codepage, "CP_ACP") == 0)
148            CurrentCodePage = CP_ACP;
149          else if (strcmp (codepage, "CP_UTF8") == 0)
150            CurrentCodePage = CP_UTF8;
151        }
152    }
153
154    /* Adjust gnat_argv to support Unicode characters. */
155    {
156      LPWSTR *wargv;
157      int wargc;
158      int k;
159      int last;
160      int argc_expanded = 0;
161      TCHAR result [MAX_PATH];
162      int quoted;
163
164      wargv = CommandLineToArgvW (GetCommandLineW(), &wargc);
165
166      if (wargv != NULL)
167        {
168          /* Set gnat_argv with arguments encoded in UTF-8. */
169          last = wargc + 1;
170          gnat_argv = (char **) xmalloc ((last) * sizeof (char *));
171
172          /* argv[0] is the executable full path-name. */
173
174          SearchPath (NULL, wargv[0], _T(".exe"), MAX_PATH, result, NULL);
175          append_arg (&argc_expanded, NULL, result, &gnat_argv, &last, 0);
176
177          for (k=1; k<wargc; k++)
178            {
179              quoted = (wargv[k][0] == _T('\''));
180
181              /* Check for wildcard expansion if the argument is not quoted. */
182              if (!quoted
183                  && (_tcsstr (wargv[k], _T("?")) != 0 ||
184                      _tcsstr (wargv[k], _T("*")) != 0))
185                {
186                  /* Wilcards are present, append all corresponding matches. */
187                  WIN32_FIND_DATA FileData;
188                  HANDLE hDir = FindFirstFile (wargv[k], &FileData);
189                  LPWSTR dir = NULL;
190                  LPWSTR ldir = _tcsrchr (wargv[k], _T('\\'));
191
192                  if (ldir == NULL)
193                    ldir = _tcsrchr (wargv[k], _T('/'));
194
195                  if (hDir == INVALID_HANDLE_VALUE)
196                    {
197                      /* No match, append arg as-is. */
198                      append_arg (&argc_expanded, NULL, wargv[k],
199                                  &gnat_argv, &last, quoted);
200                    }
201                  else
202                    {
203                      if (ldir != NULL)
204                        {
205                          int n = ldir - wargv[k] + 1;
206                          dir = xmalloc ((n + 1) * sizeof (TCHAR));
207                          _tcsncpy (dir, wargv[k], n);
208                          dir[n] = _T('\0');
209                        }
210
211                      /* Append first match and all remaining ones.  */
212
213                      do {
214                        /* Do not add . and .. special entries */
215
216                        if (_tcscmp (FileData.cFileName, _T(".")) != 0
217                            && _tcscmp (FileData.cFileName, _T("..")) != 0)
218                          append_arg (&argc_expanded, dir, FileData.cFileName,
219                                      &gnat_argv, &last, 0);
220                      } while (FindNextFile (hDir, &FileData));
221
222                      FindClose (hDir);
223
224                      free (dir);
225                    }
226                }
227              else
228                {
229                  /*  No wildcard. Store parameter as-is. Remove quote if
230                      needed. */
231                  append_arg (&argc_expanded, NULL, wargv[k],
232                              &gnat_argv, &last, quoted);
233                }
234            }
235
236          LocalFree (wargv);
237          gnat_argc = argc_expanded;
238          gnat_argv = (char **) xrealloc
239            (gnat_argv, argc_expanded * sizeof (char *));
240        }
241    }
242 #endif
243
244    /* Note that we do not activate this for the compiler itself to avoid a
245       bootstrap path problem.  Older version of gnatbind will generate a call
246       to __gnat_initialize() without argument. Therefore we cannot use eh in
247       this case.  It will be possible to remove the following #ifdef at some
248       point.  */
249 #ifdef IN_RTS
250    /* Install the Structured Exception handler.  */
251    if (eh)
252      __gnat_install_SEH_handler (eh);
253 #endif
254 }
255
256 /******************************************/
257 /* __gnat_initialize (init_float version) */
258 /******************************************/
259
260 #elif defined (__Lynx__) || defined (__FreeBSD__) || defined(__NetBSD__) \
261   || defined (__OpenBSD__)
262
263 extern void __gnat_init_float (void);
264
265 void
266 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
267 {
268    __gnat_init_float ();
269 }
270
271 /***************************************/
272 /* __gnat_initialize (VxWorks Version) */
273 /***************************************/
274
275 #elif defined(__vxworks)
276
277 extern void __gnat_init_float (void);
278
279 void
280 __gnat_initialize (void *eh)
281 {
282   __gnat_init_float ();
283
284   /* On targets where we use the ZCX scheme, we need to register the frame
285      tables at load/startup time.
286
287      For applications loaded as a set of "modules", the crtstuff objects
288      linked in (crtbegin.o/end.o) are tailored to provide this service
289      automatically, a-la C++ constructor fashion, triggered by the VxWorks
290      loader thanks to a special variable declaration in crtbegin.o (_ctors).
291
292      Automatic de-registration is handled symmetrically, a-la C++ destructor
293      fashion (with a _dtors variable also in crtbegin.o) triggered by the
294      dynamic unloader.
295
296      Note that since the tables shall be registered against a common
297      data structure, libgcc should be one of the modules (vs being partially
298      linked against all the others at build time) and shall be loaded first.
299
300      For applications linked with the kernel, the scheme above would lead to
301      duplicated symbols because the VxWorks kernel build "munches" by default,
302      so we link against crtbeginT.o instead of crtbegin.o, which doesn't
303      include the special variables. We know which set of crt objects is used
304      thanks to a boolean indicator present in both sets (__module_has_ctors),
305      and directly call the appropriate function here in the not-automatic
306      case. We'll never unload that, so there is no de-registration to worry
307      about.
308
309      For whole applications loaded as a single module, we may use one scheme
310      or the other, except for the mixed Ada/C++ case in which the first scheme
311      would fail for the same reason as in the linked-with-kernel situation.
312
313      The crt set selection is controlled by command line options via GCC's
314      STARTFILE_SPEC in rs6000/vxworks.h.  This is tightly synchronized with a
315      number of other GCC configuration and crtstuff changes, and we need to
316      ensure that those changes are there to activate this circuitry.  */
317
318 #if (__GNUC__ >= 3) && (defined (_ARCH_PPC) || defined (__ppc))
319  {
320    /* The scheme described above is only useful for the actual ZCX case, and
321       we don't want any reference to the crt provided symbols otherwise.  We
322       may not link with any of the crt objects in the non-ZCX case, e.g. from
323       documented procedures instructing the use of -nostdlib, and references
324       to the ctors symbols here would just remain unsatisfied.
325
326       We have no way to avoid those references in the right conditions in this
327       C module, because we have nothing like a IN_ZCX_RTS macro.  This aspect
328       is then deferred to an Ada routine, which can do that based on a test
329       against a constant System flag value.  */
330
331    extern void __gnat_vxw_setup_for_eh (void);
332    __gnat_vxw_setup_for_eh ();
333  }
334 #endif
335 }
336
337 #elif defined(_T_HPUX10) || (!defined(IN_RTS) && defined(_X_HPUX10))
338
339 /************************************************/
340 /* __gnat_initialize (PA-RISC HP-UX 10 Version) */
341 /************************************************/
342
343 extern void __main (void);
344
345 void
346 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
347 {
348   __main ();
349 }
350
351 #else
352
353 /* For all other versions of GNAT, the initialize routine and handler
354    installation do nothing */
355
356 /***************************************/
357 /* __gnat_initialize (Default Version) */
358 /***************************************/
359
360 void
361 __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
362 {
363 }
364
365 #endif
366
367 #ifdef __cplusplus
368 }
369 #endif