OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgfortran/] [runtime/] [main.c] - Blame information for rev 775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 733 jeremybenn
/* Copyright (C) 2002-2003, 2005, 2007, 2009, 2011
2
   Free Software Foundation, Inc.
3
   Contributed by Andy Vaught and Paul Brook <paul@nowt.org>
4
 
5
This file is part of the GNU Fortran runtime library (libgfortran).
6
 
7
Libgfortran is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
Libgfortran is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
Under Section 7 of GPL version 3, you are granted additional
18
permissions described in the GCC Runtime Library Exception, version
19
3.1, as published by the Free Software Foundation.
20
 
21
You should have received a copy of the GNU General Public License and
22
a copy of the GCC Runtime Library Exception along with this program;
23
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
<http://www.gnu.org/licenses/>.  */
25
 
26
#include "libgfortran.h"
27
#include <stdlib.h>
28
#include <string.h>
29
#include <limits.h>
30
 
31
 
32
#ifdef HAVE_UNISTD_H
33
#include <unistd.h>
34
#endif
35
 
36
/* Stupid function to be sure the constructor is always linked in, even
37
   in the case of static linking.  See PR libfortran/22298 for details.  */
38
void
39
stupid_function_name_for_static_linking (void)
40
{
41
  return;
42
}
43
 
44
/* This will be 0 for little-endian
45
   machines and 1 for big-endian machines.  */
46
int big_endian = 0;
47
 
48
 
49
/* Figure out endianness for this machine.  */
50
 
51
static void
52
determine_endianness (void)
53
{
54
  union
55
  {
56
    GFC_LOGICAL_8 l8;
57
    GFC_LOGICAL_4 l4[2];
58
  } u;
59
 
60
  u.l8 = 1;
61
  if (u.l4[0])
62
    big_endian = 0;
63
  else if (u.l4[1])
64
    big_endian = 1;
65
  else
66
    runtime_error ("Unable to determine machine endianness");
67
}
68
 
69
 
70
static int argc_save;
71
static char **argv_save;
72
 
73
static const char *exe_path;
74
static int please_free_exe_path_when_done;
75
 
76
/* Save the path under which the program was called, for use in the
77
   backtrace routines.  */
78
void
79
store_exe_path (const char * argv0)
80
{
81
#ifndef PATH_MAX
82
#define PATH_MAX 1024
83
#endif
84
 
85
#ifndef DIR_SEPARATOR   
86
#define DIR_SEPARATOR '/'
87
#endif
88
 
89
  char buf[PATH_MAX], *path;
90
  const char *cwd;
91
 
92
  /* This can only happen if store_exe_path is called multiple times.  */
93
  if (please_free_exe_path_when_done)
94
    free ((char *) exe_path);
95
 
96
  /* Reading the /proc/self/exe symlink is Linux-specific(?), but if
97
     it works it gives the correct answer.  */
98
#ifdef HAVE_READLINK
99
  int len;
100
  if ((len = readlink ("/proc/self/exe", buf, sizeof (buf) - 1)) != -1)
101
    {
102
      buf[len] = '\0';
103
      exe_path = strdup (buf);
104
      please_free_exe_path_when_done = 1;
105
      return;
106
    }
107
#endif
108
 
109
  /* If the path is absolute or on a simulator where argv is not set.  */
110
#ifdef __MINGW32__
111
  if (argv0 == NULL
112
      || ('A' <= argv0[0] && argv0[0] <= 'Z' && argv0[1] == ':')
113
      || ('a' <= argv0[0] && argv0[0] <= 'z' && argv0[1] == ':')
114
      || (argv0[0] == '/' && argv0[1] == '/')
115
      || (argv0[0] == '\\' && argv0[1] == '\\'))
116
#else
117
  if (argv0 == NULL || argv0[0] == DIR_SEPARATOR)
118
#endif
119
    {
120
      exe_path = argv0;
121
      please_free_exe_path_when_done = 0;
122
      return;
123
    }
124
 
125
#ifdef HAVE_GETCWD
126
  cwd = getcwd (buf, sizeof (buf));
127
#else
128
  cwd = NULL;
129
#endif
130
 
131
  if (!cwd)
132
    {
133
      exe_path = argv0;
134
      please_free_exe_path_when_done = 0;
135
      return;
136
    }
137
 
138
  /* exe_path will be cwd + "/" + argv[0] + "\0".  This will not work
139
     if the executable is not in the cwd, but at this point we're out
140
     of better ideas.  */
141
  size_t pathlen = strlen (cwd) + 1 + strlen (argv0) + 1;
142
  path = malloc (pathlen);
143
  snprintf (path, pathlen, "%s%c%s", cwd, DIR_SEPARATOR, argv0);
144
  exe_path = path;
145
  please_free_exe_path_when_done = 1;
146
}
147
 
148
 
149
/* Return the full path of the executable.  */
150
char *
151
full_exe_path (void)
152
{
153
  return (char *) exe_path;
154
}
155
 
156
 
157
char *addr2line_path;
158
 
159
/* Find addr2line and store the path.  */
160
 
161
void
162
find_addr2line (void)
163
{
164
#ifdef HAVE_ACCESS
165
#define A2L_LEN 10
166
  char *path = getenv ("PATH");
167
  if (!path)
168
    return;
169
  size_t n = strlen (path);
170
  char ap[n + 1 + A2L_LEN];
171
  size_t ai = 0;
172
  for (size_t i = 0; i < n; i++)
173
    {
174
      if (path[i] != ':')
175
        ap[ai++] = path[i];
176
      else
177
        {
178
          ap[ai++] = '/';
179
          memcpy (ap + ai, "addr2line", A2L_LEN);
180
          if (access (ap, R_OK|X_OK) == 0)
181
            {
182
              addr2line_path = strdup (ap);
183
              return;
184
            }
185
          else
186
            ai = 0;
187
        }
188
    }
189
#endif
190
}
191
 
192
 
193
/* Set the saved values of the command line arguments.  */
194
 
195
void
196
set_args (int argc, char **argv)
197
{
198
  argc_save = argc;
199
  argv_save = argv;
200
  store_exe_path (argv[0]);
201
}
202
iexport(set_args);
203
 
204
 
205
/* Retrieve the saved values of the command line arguments.  */
206
 
207
void
208
get_args (int *argc, char ***argv)
209
{
210
  *argc = argc_save;
211
  *argv = argv_save;
212
}
213
 
214
 
215
/* Initialize the runtime library.  */
216
 
217
static void __attribute__((constructor))
218
init (void)
219
{
220
  /* Figure out the machine endianness.  */
221
  determine_endianness ();
222
 
223
  /* Must be first */
224
  init_variables ();
225
 
226
  init_units ();
227
  set_fpu ();
228
  init_compile_options ();
229
 
230
#ifdef DEBUG
231
  /* Check for special command lines.  */
232
 
233
  if (argc > 1 && strcmp (argv[1], "--help") == 0)
234
    show_variables ();
235
 
236
  /* if (argc > 1 && strcmp(argv[1], "--resume") == 0) resume();  */
237
#endif
238
 
239
  if (options.backtrace == 1)
240
    find_addr2line ();
241
 
242
  random_seed_i4 (NULL, NULL, NULL);
243
}
244
 
245
 
246
/* Cleanup the runtime library.  */
247
 
248
static void __attribute__((destructor))
249
cleanup (void)
250
{
251
  close_units ();
252
 
253
  if (please_free_exe_path_when_done)
254
    free ((char *) exe_path);
255
 
256
  free (addr2line_path);
257
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.