annotate gcc/config/vms/vms-ld.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* VMS linker wrapper.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by AdaCore
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 /* This program is a wrapper around the VMS linker.
kono
parents:
diff changeset
22 It translates Unix style command line options into corresponding
kono
parents:
diff changeset
23 VMS style qualifiers and then spawns the VMS linker.
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 It is possible to build this program on UNIX but only for the purpose of
kono
parents:
diff changeset
26 checking for errors. */
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #include <stdlib.h>
kono
parents:
diff changeset
29 #include <string.h>
kono
parents:
diff changeset
30 #include <unistd.h>
kono
parents:
diff changeset
31 #include <stdio.h>
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 #include "libiberty.h"
kono
parents:
diff changeset
34 #include <safe-ctype.h>
kono
parents:
diff changeset
35 #include <sys/stat.h>
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 /* Macro for logicals. */
kono
parents:
diff changeset
38 #define LNM__STRING 2
kono
parents:
diff changeset
39 #define LNM_C_NAMLENGTH 255
kono
parents:
diff changeset
40 #define PSL_C_SUPER 2
kono
parents:
diff changeset
41 #define PSL_C_USER 3
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 /* Local variable declarations. */
kono
parents:
diff changeset
44 static int ld_nocall_debug = 0;
kono
parents:
diff changeset
45 static int ld_mkthreads = 0;
kono
parents:
diff changeset
46 static int ld_upcalls = 0;
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 /* verbose = 1 if -v passed. */
kono
parents:
diff changeset
49 static int verbose = 0;
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 /* save_temps = 1 if -save-temps passed. */
kono
parents:
diff changeset
52 static int save_temps = 0;
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* By default don't generate executable file if there are errors
kono
parents:
diff changeset
55 in the link. Override with --noinhibit-exec. */
kono
parents:
diff changeset
56 static int inhibit_exec = 1;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 /* debug = 1 if -g passed. */
kono
parents:
diff changeset
59 static int debug = 0;
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 /* By default prefer to link with static libraries. */
kono
parents:
diff changeset
62 static int staticp = 1;
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 /* By default generate an executable, not a shareable image library.
kono
parents:
diff changeset
65 Override with -shared. */
kono
parents:
diff changeset
66 static int share = 0;
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 /* Linker command line. */
kono
parents:
diff changeset
69 static int link_cmd_maxlen = 0;
kono
parents:
diff changeset
70 static char *link_cmd = 0;
kono
parents:
diff changeset
71 static int link_cmd_len = 0;
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* Keep track of filenames. */
kono
parents:
diff changeset
74 static char *sharebasename;
kono
parents:
diff changeset
75 static const char *exefullfilename;
kono
parents:
diff changeset
76 static const char *exefilename;
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 /* Search dir list passed on command line (with -L). */
kono
parents:
diff changeset
79 static const char **search_dirs;
kono
parents:
diff changeset
80 static int search_dirs_len;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 /* Local function declarations. */
kono
parents:
diff changeset
83 static void addarg (const char *);
kono
parents:
diff changeset
84 static int is_regular_file (char *);
kono
parents:
diff changeset
85 static char *to_host_file_spec (char *);
kono
parents:
diff changeset
86 static char *locate_lib (char *);
kono
parents:
diff changeset
87 static const char *expand_lib (char *);
kono
parents:
diff changeset
88 static void preprocess_args (int, char **);
kono
parents:
diff changeset
89 static void process_args (int, char **);
kono
parents:
diff changeset
90 static void maybe_set_link_compat (void);
kono
parents:
diff changeset
91 static int set_exe (const char *);
kono
parents:
diff changeset
92 #ifdef VMS
kono
parents:
diff changeset
93 static int translate_unix (char *, int);
kono
parents:
diff changeset
94 #endif
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 /* Append STR to the command line to invoke the linker.
kono
parents:
diff changeset
98 Expand the line as necessary to accommodate. */
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 static void
kono
parents:
diff changeset
101 addarg (const char *str)
kono
parents:
diff changeset
102 {
kono
parents:
diff changeset
103 int l = strlen (str);
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 /* Extend the line. */
kono
parents:
diff changeset
106 if (link_cmd_len + l >= link_cmd_maxlen)
kono
parents:
diff changeset
107 {
kono
parents:
diff changeset
108 link_cmd_maxlen = link_cmd_len + l + 1024;
kono
parents:
diff changeset
109 link_cmd = XRESIZEVEC (char, link_cmd, link_cmd_maxlen);
kono
parents:
diff changeset
110 }
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 memcpy (link_cmd + link_cmd_len, str, l);
kono
parents:
diff changeset
113 link_cmd_len += l;
kono
parents:
diff changeset
114 }
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 /* Check to see if NAME is a regular file, i.e. not a directory. */
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 static int
kono
parents:
diff changeset
119 is_regular_file (char *name)
kono
parents:
diff changeset
120 {
kono
parents:
diff changeset
121 int ret;
kono
parents:
diff changeset
122 struct stat statbuf;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 ret = stat (name, &statbuf);
kono
parents:
diff changeset
125 return !ret && S_ISREG (statbuf.st_mode);
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 #ifdef VMS
kono
parents:
diff changeset
129 static char new_host_filespec [255];
kono
parents:
diff changeset
130 static char filename_buff [256];
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 /* Action routine called by decc$to_vms. NAME is a file name or
kono
parents:
diff changeset
133 directory name. TYPE is unused. */
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 static int
kono
parents:
diff changeset
136 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
kono
parents:
diff changeset
137 {
kono
parents:
diff changeset
138 strcpy (filename_buff, name);
kono
parents:
diff changeset
139 return 0;
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141 #endif
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 /* Translate a Unix syntax file specification FILESPEC into VMS syntax.
kono
parents:
diff changeset
144 If indicators of VMS syntax found, return input string.
kono
parents:
diff changeset
145 Return a pointer to a static buffer. */
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 static char *
kono
parents:
diff changeset
148 to_host_file_spec (char *filespec)
kono
parents:
diff changeset
149 {
kono
parents:
diff changeset
150 #ifdef VMS
kono
parents:
diff changeset
151 if (strchr (filespec, ']') || strchr (filespec, ':'))
kono
parents:
diff changeset
152 {
kono
parents:
diff changeset
153 /* Looks like a VMS path. */
kono
parents:
diff changeset
154 return filespec;
kono
parents:
diff changeset
155 }
kono
parents:
diff changeset
156 else
kono
parents:
diff changeset
157 {
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 strcpy (filename_buff, filespec);
kono
parents:
diff changeset
160 decc$to_vms (filespec, translate_unix, 1, 1);
kono
parents:
diff changeset
161 strcpy (new_host_filespec, filename_buff);
kono
parents:
diff changeset
162 return new_host_filespec;
kono
parents:
diff changeset
163 }
kono
parents:
diff changeset
164 #else
kono
parents:
diff changeset
165 return filespec;
kono
parents:
diff changeset
166 #endif
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 /* Locate library LIB_NAME on the library path. */
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 static char *
kono
parents:
diff changeset
172 locate_lib (char *lib_name)
kono
parents:
diff changeset
173 {
kono
parents:
diff changeset
174 int lib_len = strlen (lib_name);
kono
parents:
diff changeset
175 const char *exts[3];
kono
parents:
diff changeset
176 int i;
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 if (staticp)
kono
parents:
diff changeset
179 {
kono
parents:
diff changeset
180 /* For static links, look for shareable image libraries last. */
kono
parents:
diff changeset
181 exts[0] = ".a";
kono
parents:
diff changeset
182 exts[1] = ".olb";
kono
parents:
diff changeset
183 exts[2] = ".exe";
kono
parents:
diff changeset
184 }
kono
parents:
diff changeset
185 else
kono
parents:
diff changeset
186 {
kono
parents:
diff changeset
187 exts[0] = ".exe";
kono
parents:
diff changeset
188 exts[1] = ".a";
kono
parents:
diff changeset
189 exts[2] = ".olb";
kono
parents:
diff changeset
190 }
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 for (i = 0; i < search_dirs_len; i++)
kono
parents:
diff changeset
193 {
kono
parents:
diff changeset
194 char *buf;
kono
parents:
diff changeset
195 int l;
kono
parents:
diff changeset
196 int j;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 l = strlen (search_dirs[i]);
kono
parents:
diff changeset
199 buf = (char *)alloca (l + 4 + lib_len + 4 + 1);
kono
parents:
diff changeset
200 /* Put PATH/libLIB. */
kono
parents:
diff changeset
201 memcpy (buf, search_dirs[i], l);
kono
parents:
diff changeset
202 memcpy (buf + l, "/lib", 4);
kono
parents:
diff changeset
203 l += 4;
kono
parents:
diff changeset
204 memcpy (buf + l, lib_name, lib_len);
kono
parents:
diff changeset
205 l += lib_len;
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 /* Look for files with the extensions. */
kono
parents:
diff changeset
208 for (j = 0; j < 3; j++)
kono
parents:
diff changeset
209 {
kono
parents:
diff changeset
210 strcpy (buf + l, exts[j]);
kono
parents:
diff changeset
211 if (is_regular_file (buf))
kono
parents:
diff changeset
212 return xstrdup (to_host_file_spec (buf));
kono
parents:
diff changeset
213 }
kono
parents:
diff changeset
214 }
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 return NULL;
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 /* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
kono
parents:
diff changeset
220 libfoo.a in the set of directories we are allowed to search in.
kono
parents:
diff changeset
221 May return NULL if the library can be discarded. */
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 static const char *
kono
parents:
diff changeset
224 expand_lib (char *name)
kono
parents:
diff changeset
225 {
kono
parents:
diff changeset
226 char *lib_path;
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 /* Discard libc. */
kono
parents:
diff changeset
229 if (strcmp (name, "c") == 0)
kono
parents:
diff changeset
230 return NULL;
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 /* Discard libm. No separate library for math functions. */
kono
parents:
diff changeset
233 if (strcmp (name, "m") == 0)
kono
parents:
diff changeset
234 return NULL;
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 /* Search on path. */
kono
parents:
diff changeset
237 lib_path = locate_lib (name);
kono
parents:
diff changeset
238 if (lib_path)
kono
parents:
diff changeset
239 return lib_path;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 fprintf (stderr,
kono
parents:
diff changeset
242 "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
kono
parents:
diff changeset
243 name, name, name);
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 exit (EXIT_FAILURE);
kono
parents:
diff changeset
246 }
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 /* Preprocess the number of args P_ARGC in ARGV.
kono
parents:
diff changeset
249 Look for special flags, etc. that must be handled first. */
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 static void
kono
parents:
diff changeset
252 preprocess_args (int argc, char **argv)
kono
parents:
diff changeset
253 {
kono
parents:
diff changeset
254 int i;
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 /* Scan for -shared. */
kono
parents:
diff changeset
257 for (i = 1; i < argc; i++)
kono
parents:
diff changeset
258 if (strcmp (argv[i], "-shared") == 0)
kono
parents:
diff changeset
259 {
kono
parents:
diff changeset
260 share = 1;
kono
parents:
diff changeset
261 break;
kono
parents:
diff changeset
262 }
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 for (i = 1; i < argc; i++)
kono
parents:
diff changeset
265 if (strcmp (argv[i], "-o") == 0)
kono
parents:
diff changeset
266 {
kono
parents:
diff changeset
267 int len;
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 i++;
kono
parents:
diff changeset
270 exefilename = lbasename (argv[i]);
kono
parents:
diff changeset
271 exefullfilename = xstrdup (to_host_file_spec (argv[i]));
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 if (share)
kono
parents:
diff changeset
274 addarg(" /share=");
kono
parents:
diff changeset
275 else
kono
parents:
diff changeset
276 addarg (" /exe=");
kono
parents:
diff changeset
277 addarg (exefullfilename);
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 if (share)
kono
parents:
diff changeset
280 {
kono
parents:
diff changeset
281 char *ptr;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 /* Extract the basename. */
kono
parents:
diff changeset
284 ptr = strchr (argv[i], ']');
kono
parents:
diff changeset
285 if (ptr == NULL)
kono
parents:
diff changeset
286 ptr = strchr (argv[i], ':');
kono
parents:
diff changeset
287 if (ptr == NULL)
kono
parents:
diff changeset
288 ptr = strchr (argv[i], '/');
kono
parents:
diff changeset
289 if (ptr == NULL)
kono
parents:
diff changeset
290 sharebasename = xstrdup (argv[i]);
kono
parents:
diff changeset
291 else
kono
parents:
diff changeset
292 sharebasename = xstrdup (ptr + 1);
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 len = strlen (sharebasename);
kono
parents:
diff changeset
295 if (strncasecmp (&sharebasename[len-4], ".exe", 4) == 0)
kono
parents:
diff changeset
296 sharebasename[len - 4] = 0;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 /* Convert to uppercase. */
kono
parents:
diff changeset
299 for (ptr = sharebasename; *ptr; ptr++)
kono
parents:
diff changeset
300 *ptr = TOUPPER (*ptr);
kono
parents:
diff changeset
301 }
kono
parents:
diff changeset
302 }
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 if (exefullfilename == NULL && !share)
kono
parents:
diff changeset
305 {
kono
parents:
diff changeset
306 exefilename = "a_out.exe";
kono
parents:
diff changeset
307 exefullfilename = "a_out.exe";
kono
parents:
diff changeset
308 addarg (xstrdup (" /exe=a_out.exe"));
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310 }
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 /* Preprocess the number of args ARGC in ARGV. Look for
kono
parents:
diff changeset
313 special flags, etc. that must be handled for the VMS linker. */
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 static void
kono
parents:
diff changeset
316 process_args (int argc, char **argv)
kono
parents:
diff changeset
317 {
kono
parents:
diff changeset
318 int i;
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 for (i = 1; i < argc; i++)
kono
parents:
diff changeset
321 {
kono
parents:
diff changeset
322 if (strncmp (argv[i], "-L", 2) == 0)
kono
parents:
diff changeset
323 {
kono
parents:
diff changeset
324 search_dirs = XRESIZEVEC(const char *, search_dirs,
kono
parents:
diff changeset
325 search_dirs_len + 1);
kono
parents:
diff changeset
326 search_dirs[search_dirs_len++] = &argv[i][2];
kono
parents:
diff changeset
327 }
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 /* -v turns on verbose option here and is passed on to gcc. */
kono
parents:
diff changeset
330 else if (strcmp (argv[i], "-v") == 0)
kono
parents:
diff changeset
331 verbose++;
kono
parents:
diff changeset
332 else if (strcmp (argv[i], "--version") == 0)
kono
parents:
diff changeset
333 {
kono
parents:
diff changeset
334 fprintf (stdout, "VMS Linker\n");
kono
parents:
diff changeset
335 exit (EXIT_SUCCESS);
kono
parents:
diff changeset
336 }
kono
parents:
diff changeset
337 else if (strcmp (argv[i], "--help") == 0)
kono
parents:
diff changeset
338 {
kono
parents:
diff changeset
339 fprintf (stdout, "VMS Linker\n");
kono
parents:
diff changeset
340 exit (EXIT_SUCCESS);
kono
parents:
diff changeset
341 }
kono
parents:
diff changeset
342 else if (strcmp (argv[i], "-g0") == 0)
kono
parents:
diff changeset
343 addarg ("/notraceback");
kono
parents:
diff changeset
344 else if (strncmp (argv[i], "-g", 2) == 0)
kono
parents:
diff changeset
345 {
kono
parents:
diff changeset
346 addarg ("/debug");
kono
parents:
diff changeset
347 debug = 1;
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349 else if (strcmp (argv[i], "-static") == 0)
kono
parents:
diff changeset
350 staticp = 1;
kono
parents:
diff changeset
351 else if (strcmp (argv[i], "-map") == 0)
kono
parents:
diff changeset
352 {
kono
parents:
diff changeset
353 char *buff, *ptr;
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 buff = (char *) xstrdup (exefullfilename);
kono
parents:
diff changeset
356 ptr = strrchr (buff, '.');
kono
parents:
diff changeset
357 if (ptr)
kono
parents:
diff changeset
358 *ptr = 0;
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 strcat (buff, ".map");
kono
parents:
diff changeset
361 addarg ("/map=");
kono
parents:
diff changeset
362 addarg (buff);
kono
parents:
diff changeset
363 addarg (".map");
kono
parents:
diff changeset
364 addarg ("/full");
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 free (buff);
kono
parents:
diff changeset
367 }
kono
parents:
diff changeset
368 else if (strcmp (argv[i], "-save-temps") == 0)
kono
parents:
diff changeset
369 save_temps = 1;
kono
parents:
diff changeset
370 else if (strcmp (argv[i], "--noinhibit-exec") == 0)
kono
parents:
diff changeset
371 inhibit_exec = 0;
kono
parents:
diff changeset
372 }
kono
parents:
diff changeset
373 }
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 #ifdef VMS
kono
parents:
diff changeset
376 typedef struct dsc
kono
parents:
diff changeset
377 {
kono
parents:
diff changeset
378 unsigned short len, mbz;
kono
parents:
diff changeset
379 const char *adr;
kono
parents:
diff changeset
380 } Descriptor;
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 struct lst
kono
parents:
diff changeset
383 {
kono
parents:
diff changeset
384 unsigned short buflen, item_code;
kono
parents:
diff changeset
385 const void *bufaddr;
kono
parents:
diff changeset
386 void *retlenaddr;
kono
parents:
diff changeset
387 };
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 static struct
kono
parents:
diff changeset
390 {
kono
parents:
diff changeset
391 struct lst items [1];
kono
parents:
diff changeset
392 unsigned int terminator;
kono
parents:
diff changeset
393 } item_lst1;
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 static struct
kono
parents:
diff changeset
396 {
kono
parents:
diff changeset
397 struct lst items [2];
kono
parents:
diff changeset
398 unsigned int terminator;
kono
parents:
diff changeset
399 } item_lst2;
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 /* Checks if logical names are defined for setting system library path and
kono
parents:
diff changeset
402 linker program to enable compatibility with earlier VMS versions. */
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 static void
kono
parents:
diff changeset
405 maybe_set_link_compat (void)
kono
parents:
diff changeset
406 {
kono
parents:
diff changeset
407 char lnm_buff [LNM_C_NAMLENGTH];
kono
parents:
diff changeset
408 unsigned int lnm_buff_len;
kono
parents:
diff changeset
409 int status;
kono
parents:
diff changeset
410 Descriptor tabledsc, linkdsc;
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 tabledsc.adr = "LNM$JOB";
kono
parents:
diff changeset
413 tabledsc.len = strlen (tabledsc.adr);
kono
parents:
diff changeset
414 tabledsc.mbz = 0;
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 linkdsc.adr = "GCC_LD_SYS$LIBRARY";
kono
parents:
diff changeset
417 linkdsc.len = strlen (linkdsc.adr);
kono
parents:
diff changeset
418 linkdsc.mbz = 0;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
kono
parents:
diff changeset
421 item_lst1.items[0].item_code = LNM__STRING;
kono
parents:
diff changeset
422 item_lst1.items[0].bufaddr = lnm_buff;
kono
parents:
diff changeset
423 item_lst1.items[0].retlenaddr = &lnm_buff_len;
kono
parents:
diff changeset
424 item_lst1.terminator = 0;
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 status = SYS$TRNLNM
kono
parents:
diff changeset
427 (0, /* attr */
kono
parents:
diff changeset
428 &tabledsc, /* tabnam */
kono
parents:
diff changeset
429 &linkdsc, /* lognam */
kono
parents:
diff changeset
430 0, /* acmode */
kono
parents:
diff changeset
431 &item_lst1);
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 /* If GCC_LD_SYS$LIBRARY is defined, redefine SYS$LIBRARY to search
kono
parents:
diff changeset
434 the equivalence name first for system libraries, then the default
kono
parents:
diff changeset
435 system library directory */
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 if ((status & 1) == 1)
kono
parents:
diff changeset
438 {
kono
parents:
diff changeset
439 unsigned char acmode = PSL_C_USER; /* Don't retain after image exit */
kono
parents:
diff changeset
440 const char *syslib = "SYS$SYSROOT:[SYSLIB]"; /* Default SYS$LIBRARY */
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 /* Only visible to current and child processes */
kono
parents:
diff changeset
443 tabledsc.adr = "LNM$PROCESS";
kono
parents:
diff changeset
444 tabledsc.len = strlen (tabledsc.adr);
kono
parents:
diff changeset
445 tabledsc.mbz = 0;
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 linkdsc.adr = "SYS$LIBRARY";
kono
parents:
diff changeset
448 linkdsc.len = strlen (linkdsc.adr);
kono
parents:
diff changeset
449 linkdsc.mbz = 0;
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 item_lst2.items[0].buflen = lnm_buff_len;
kono
parents:
diff changeset
452 item_lst2.items[0].item_code = LNM__STRING;
kono
parents:
diff changeset
453 item_lst2.items[0].bufaddr = lnm_buff;
kono
parents:
diff changeset
454 item_lst2.items[0].retlenaddr = 0;
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 item_lst2.items[1].buflen = strlen (syslib);
kono
parents:
diff changeset
457 item_lst2.items[1].item_code = LNM__STRING;
kono
parents:
diff changeset
458 item_lst2.items[1].bufaddr = syslib;
kono
parents:
diff changeset
459 item_lst2.items[1].retlenaddr = 0;
kono
parents:
diff changeset
460 item_lst2.terminator = 0;
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 status = SYS$CRELNM
kono
parents:
diff changeset
463 (0, /* attr */
kono
parents:
diff changeset
464 &tabledsc, /* tabnam */
kono
parents:
diff changeset
465 &linkdsc, /* lognam */
kono
parents:
diff changeset
466 &acmode, /* acmode */
kono
parents:
diff changeset
467 &item_lst2);
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 }
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 tabledsc.adr = "LNM$JOB";
kono
parents:
diff changeset
472 tabledsc.len = strlen (tabledsc.adr);
kono
parents:
diff changeset
473 tabledsc.mbz = 0;
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 linkdsc.adr = "GCC_LD_LINK";
kono
parents:
diff changeset
476 linkdsc.len = strlen (linkdsc.adr);
kono
parents:
diff changeset
477 linkdsc.mbz = 0;
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
kono
parents:
diff changeset
480 item_lst1.items[0].item_code = LNM__STRING;
kono
parents:
diff changeset
481 item_lst1.items[0].bufaddr = lnm_buff;
kono
parents:
diff changeset
482 item_lst1.items[0].retlenaddr = &lnm_buff_len;
kono
parents:
diff changeset
483 item_lst1.terminator = 0;
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 status = SYS$TRNLNM
kono
parents:
diff changeset
486 (0, /* attr */
kono
parents:
diff changeset
487 &tabledsc, /* tabnam */
kono
parents:
diff changeset
488 &linkdsc, /* lognam */
kono
parents:
diff changeset
489 0, /* acmode */
kono
parents:
diff changeset
490 &item_lst1);
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 /* If GCC_LD_LINK is defined, redefine LINK to use the equivalence name
kono
parents:
diff changeset
493 (sometimes the LINK program version is used by VMS to determine
kono
parents:
diff changeset
494 compatibility). */
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 if ((status & 1) == 1)
kono
parents:
diff changeset
497 {
kono
parents:
diff changeset
498 unsigned char acmode = PSL_C_USER; /* Don't retain after image exit. */
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 /* Only visible to current and child processes. */
kono
parents:
diff changeset
501 tabledsc.adr = "LNM$PROCESS";
kono
parents:
diff changeset
502 tabledsc.len = strlen (tabledsc.adr);
kono
parents:
diff changeset
503 tabledsc.mbz = 0;
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 linkdsc.adr = "LINK";
kono
parents:
diff changeset
506 linkdsc.len = strlen (linkdsc.adr);
kono
parents:
diff changeset
507 linkdsc.mbz = 0;
kono
parents:
diff changeset
508
kono
parents:
diff changeset
509 item_lst1.items[0].buflen = lnm_buff_len;
kono
parents:
diff changeset
510 item_lst1.items[0].item_code = LNM__STRING;
kono
parents:
diff changeset
511 item_lst1.items[0].bufaddr = lnm_buff;
kono
parents:
diff changeset
512 item_lst1.items[0].retlenaddr = 0;
kono
parents:
diff changeset
513 item_lst1.terminator = 0;
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 status = SYS$CRELNM
kono
parents:
diff changeset
516 (0, /* attr */
kono
parents:
diff changeset
517 &tabledsc, /* tabnam */
kono
parents:
diff changeset
518 &linkdsc, /* lognam */
kono
parents:
diff changeset
519 &acmode, /* acmode */
kono
parents:
diff changeset
520 &item_lst1);
kono
parents:
diff changeset
521 }
kono
parents:
diff changeset
522 }
kono
parents:
diff changeset
523 #else
kono
parents:
diff changeset
524 static void
kono
parents:
diff changeset
525 maybe_set_link_compat (void)
kono
parents:
diff changeset
526 {
kono
parents:
diff changeset
527 }
kono
parents:
diff changeset
528 #endif
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 /* Set environment defined executable attributes. */
kono
parents:
diff changeset
531
kono
parents:
diff changeset
532 static int
kono
parents:
diff changeset
533 set_exe (const char *arg)
kono
parents:
diff changeset
534 {
kono
parents:
diff changeset
535 char allargs [1024];
kono
parents:
diff changeset
536 int res;
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 snprintf (allargs, sizeof (allargs),
kono
parents:
diff changeset
539 "$@gnu:[bin]set_exe %s %s", exefullfilename, arg);
kono
parents:
diff changeset
540 if (verbose)
kono
parents:
diff changeset
541 printf ("%s\n", allargs);
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 res = system (allargs);
kono
parents:
diff changeset
544 if (verbose > 1)
kono
parents:
diff changeset
545 printf ("$!status = %d\n", res);
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 if ((res & 1) != 1)
kono
parents:
diff changeset
548 {
kono
parents:
diff changeset
549 fprintf (stderr, "ld error: popen set_exe\n");
kono
parents:
diff changeset
550 return 1;
kono
parents:
diff changeset
551 }
kono
parents:
diff changeset
552 return 0;
kono
parents:
diff changeset
553 }
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 /* The main program. Spawn the VMS linker after fixing up the Unix-like flags
kono
parents:
diff changeset
556 and args to be what the VMS linker wants. */
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 int
kono
parents:
diff changeset
559 main (int argc, char **argv)
kono
parents:
diff changeset
560 {
kono
parents:
diff changeset
561 /* File specification for vms-dwarf2.o. */
kono
parents:
diff changeset
562 char *vmsdwarf2spec = 0;
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 /* File specification for vms-dwarf2eh.o. */
kono
parents:
diff changeset
565 char *vmsdwarf2ehspec = 0;
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 int i;
kono
parents:
diff changeset
568 char cwdev[128], *devptr;
kono
parents:
diff changeset
569 int cwdevlen;
kono
parents:
diff changeset
570 FILE *optfile;
kono
parents:
diff changeset
571 char *cwd, *ptr;
kono
parents:
diff changeset
572 char *optfilename;
kono
parents:
diff changeset
573 int status = 0;
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 /* Some linker options can be set with logicals. */
kono
parents:
diff changeset
576 if (getenv ("GNAT$LD_NOCALL_DEBUG"))
kono
parents:
diff changeset
577 ld_nocall_debug = 1;
kono
parents:
diff changeset
578 if (getenv ("GNAT$LD_MKTHREADS"))
kono
parents:
diff changeset
579 ld_mkthreads = 1;
kono
parents:
diff changeset
580 if (getenv ("GNAT$LD_UPCALLS"))
kono
parents:
diff changeset
581 ld_upcalls = 1;
kono
parents:
diff changeset
582 if (getenv ("GNAT$LD_SHARED_LIBS"))
kono
parents:
diff changeset
583 staticp = 0;
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 /* Get current dir. */
kono
parents:
diff changeset
586 #ifdef VMS
kono
parents:
diff changeset
587 cwd = getcwd (0, 1024, 1);
kono
parents:
diff changeset
588 #else
kono
parents:
diff changeset
589 cwd = getcwd (0, 1024);
kono
parents:
diff changeset
590 strcat (cwd, "/");
kono
parents:
diff changeset
591 #endif
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 /* Extract device part of the path. */
kono
parents:
diff changeset
594 devptr = strchr (cwd, ':');
kono
parents:
diff changeset
595 if (devptr)
kono
parents:
diff changeset
596 cwdevlen = (devptr - cwd) + 1;
kono
parents:
diff changeset
597 else
kono
parents:
diff changeset
598 cwdevlen = 0;
kono
parents:
diff changeset
599 memcpy (cwdev, cwd, cwdevlen);
kono
parents:
diff changeset
600 cwdev [cwdevlen] = '\0';
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 maybe_set_link_compat ();
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 /* Linker command starts with the command name. */
kono
parents:
diff changeset
605 addarg ("$ link");
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 /* Pass to find args that have to be append first. */
kono
parents:
diff changeset
608 preprocess_args (argc , argv);
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 /* Pass to find the rest of the args. */
kono
parents:
diff changeset
611 process_args (argc , argv);
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 if (!verbose)
kono
parents:
diff changeset
614 addarg ("/noinform");
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 /* Create a temp file to hold args, otherwise we can easily exceed the VMS
kono
parents:
diff changeset
617 command line length limits. */
kono
parents:
diff changeset
618 optfilename = (char *) xmalloc (strlen (exefilename) + 13);
kono
parents:
diff changeset
619 strcpy (optfilename, exefilename);
kono
parents:
diff changeset
620 ptr = strrchr (optfilename, '.');
kono
parents:
diff changeset
621 if (ptr)
kono
parents:
diff changeset
622 *ptr = 0;
kono
parents:
diff changeset
623 strcat (optfilename, ".opt_tmpfile");
kono
parents:
diff changeset
624 optfile = fopen (optfilename, "w");
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 /* Write out the IDENTIFICATION argument first so that it can be overridden
kono
parents:
diff changeset
627 by an options file. */
kono
parents:
diff changeset
628 for (i = 1; i < argc; i++)
kono
parents:
diff changeset
629 {
kono
parents:
diff changeset
630 int arg_len = strlen (argv[i]);
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
kono
parents:
diff changeset
633 {
kono
parents:
diff changeset
634 /* Comes from command line. If present will always appear before
kono
parents:
diff changeset
635 --identification=... and will override. */
kono
parents:
diff changeset
636 break;
kono
parents:
diff changeset
637 }
kono
parents:
diff changeset
638 else if (arg_len > 17
kono
parents:
diff changeset
639 && strncasecmp (argv[i], "--identification=", 17) == 0)
kono
parents:
diff changeset
640 {
kono
parents:
diff changeset
641 /* Comes from pragma Ident (). */
kono
parents:
diff changeset
642 fprintf (optfile, "case_sensitive=yes\n");
kono
parents:
diff changeset
643 fprintf (optfile, "IDENTIFICATION=\"%-.15s\"\n", &argv[i][17]);
kono
parents:
diff changeset
644 fprintf (optfile, "case_sensitive=NO\n");
kono
parents:
diff changeset
645 }
kono
parents:
diff changeset
646 }
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 for (i = 1; i < argc; i++)
kono
parents:
diff changeset
649 {
kono
parents:
diff changeset
650 int arg_len = strlen (argv[i]);
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 if (strcmp (argv[i], "-o") == 0)
kono
parents:
diff changeset
653 {
kono
parents:
diff changeset
654 /* Already handled. */
kono
parents:
diff changeset
655 i++;
kono
parents:
diff changeset
656 }
kono
parents:
diff changeset
657 else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
kono
parents:
diff changeset
658 {
kono
parents:
diff changeset
659 const char *libname;
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 libname = expand_lib (&argv[i][2]);
kono
parents:
diff changeset
662 if (libname != NULL)
kono
parents:
diff changeset
663 {
kono
parents:
diff changeset
664 int len = strlen (libname);
kono
parents:
diff changeset
665 const char *ext;
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
kono
parents:
diff changeset
668 ext = "/shareable";
kono
parents:
diff changeset
669 else
kono
parents:
diff changeset
670 ext = "/library";
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 if (libname[0] == '[')
kono
parents:
diff changeset
673 fprintf (optfile, "%s%s%s\n", cwdev, libname, ext);
kono
parents:
diff changeset
674 else
kono
parents:
diff changeset
675 fprintf (optfile, "%s%s\n", libname, ext);
kono
parents:
diff changeset
676 }
kono
parents:
diff changeset
677 }
kono
parents:
diff changeset
678 else if (strcmp (argv[i], "-v" ) == 0
kono
parents:
diff changeset
679 || strncmp (argv[i], "-g", 2 ) == 0
kono
parents:
diff changeset
680 || strcmp (argv[i], "-static" ) == 0
kono
parents:
diff changeset
681 || strcmp (argv[i], "-map" ) == 0
kono
parents:
diff changeset
682 || strcmp (argv[i], "-save-temps") == 0
kono
parents:
diff changeset
683 || strcmp (argv[i], "--noinhibit-exec") == 0
kono
parents:
diff changeset
684 || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
kono
parents:
diff changeset
685 || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
kono
parents:
diff changeset
686 {
kono
parents:
diff changeset
687 /* Already handled. */
kono
parents:
diff changeset
688 }
kono
parents:
diff changeset
689 else if (strncmp (argv[i], "--opt=", 6) == 0)
kono
parents:
diff changeset
690 fprintf (optfile, "%s\n", argv[i] + 6);
kono
parents:
diff changeset
691 else if (arg_len > 1 && argv[i][0] == '@')
kono
parents:
diff changeset
692 {
kono
parents:
diff changeset
693 /* Read response file (in fact a single line of filenames). */
kono
parents:
diff changeset
694 FILE *atfile;
kono
parents:
diff changeset
695 char *ptr, *ptr1;
kono
parents:
diff changeset
696 struct stat statbuf;
kono
parents:
diff changeset
697 char *buff;
kono
parents:
diff changeset
698 int len;
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 if (stat (&argv[i][1], &statbuf))
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 fprintf (stderr, "Couldn't open linker response file: %s\n",
kono
parents:
diff changeset
703 &argv[i][1]);
kono
parents:
diff changeset
704 exit (EXIT_FAILURE);
kono
parents:
diff changeset
705 }
kono
parents:
diff changeset
706
kono
parents:
diff changeset
707 /* Read the line. */
kono
parents:
diff changeset
708 buff = (char *) xmalloc (statbuf.st_size + 1);
kono
parents:
diff changeset
709 atfile = fopen (&argv[i][1], "r");
kono
parents:
diff changeset
710 fgets (buff, statbuf.st_size + 1, atfile);
kono
parents:
diff changeset
711 fclose (atfile);
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 /* Remove trailing \n. */
kono
parents:
diff changeset
714 len = strlen (buff);
kono
parents:
diff changeset
715 if (buff [len - 1] == '\n')
kono
parents:
diff changeset
716 {
kono
parents:
diff changeset
717 buff [len - 1] = 0;
kono
parents:
diff changeset
718 len--;
kono
parents:
diff changeset
719 }
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 /* Put the filenames to the opt file. */
kono
parents:
diff changeset
722 ptr = buff;
kono
parents:
diff changeset
723 do
kono
parents:
diff changeset
724 {
kono
parents:
diff changeset
725 ptr1 = strchr (ptr, ' ');
kono
parents:
diff changeset
726 if (ptr1)
kono
parents:
diff changeset
727 *ptr1 = 0;
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 /* Add device name if a path is present. */
kono
parents:
diff changeset
730 ptr = to_host_file_spec (ptr);
kono
parents:
diff changeset
731 if (ptr[0] == '[')
kono
parents:
diff changeset
732 fprintf (optfile, "%s%s\n", cwdev, ptr);
kono
parents:
diff changeset
733 else
kono
parents:
diff changeset
734 fprintf (optfile, "%s\n", ptr);
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 ptr = ptr1 + 1;
kono
parents:
diff changeset
737 }
kono
parents:
diff changeset
738 while (ptr1);
kono
parents:
diff changeset
739 }
kono
parents:
diff changeset
740 else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
kono
parents:
diff changeset
741 {
kono
parents:
diff changeset
742 /* Unix style file specs and VMS style switches look alike,
kono
parents:
diff changeset
743 so assume an arg consisting of one and only one slash,
kono
parents:
diff changeset
744 and that being first, is really a switch. */
kono
parents:
diff changeset
745 addarg (argv[i]);
kono
parents:
diff changeset
746 }
kono
parents:
diff changeset
747 else if (arg_len > 4
kono
parents:
diff changeset
748 && strncasecmp (&argv[i][arg_len-4], ".opt", 4) == 0)
kono
parents:
diff changeset
749 {
kono
parents:
diff changeset
750 /* Read option file. */
kono
parents:
diff changeset
751 FILE *optfile1;
kono
parents:
diff changeset
752 char buff[256];
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 /* Disable __UNIX_FOPEN redefinition in case user supplied .opt
kono
parents:
diff changeset
755 file is not stream oriented. */
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 optfile1 = (fopen) (argv[i], "r");
kono
parents:
diff changeset
758 if (optfile1 == 0)
kono
parents:
diff changeset
759 {
kono
parents:
diff changeset
760 perror (argv[i]);
kono
parents:
diff changeset
761 status = 1;
kono
parents:
diff changeset
762 goto cleanup_and_exit;
kono
parents:
diff changeset
763 }
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 while (fgets (buff, sizeof (buff), optfile1))
kono
parents:
diff changeset
766 fputs (buff, optfile);
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 fclose (optfile1);
kono
parents:
diff changeset
769 }
kono
parents:
diff changeset
770 else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
kono
parents:
diff changeset
771 fprintf (optfile, "%s\n", argv[i]);
kono
parents:
diff changeset
772 else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
kono
parents:
diff changeset
773 {
kono
parents:
diff changeset
774 /* Comes from command line and will override pragma. */
kono
parents:
diff changeset
775 fprintf (optfile, "case_sensitive=yes\n");
kono
parents:
diff changeset
776 fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
kono
parents:
diff changeset
777 fprintf (optfile, "case_sensitive=NO\n");
kono
parents:
diff changeset
778 }
kono
parents:
diff changeset
779 else if (arg_len > 17
kono
parents:
diff changeset
780 && strncasecmp (argv[i], "--identification=", 17) == 0)
kono
parents:
diff changeset
781 {
kono
parents:
diff changeset
782 /* Already handled. */
kono
parents:
diff changeset
783 }
kono
parents:
diff changeset
784 else
kono
parents:
diff changeset
785 {
kono
parents:
diff changeset
786 /* Assume filename arg. */
kono
parents:
diff changeset
787 const char *file;
kono
parents:
diff changeset
788 const char *addswitch = NULL;
kono
parents:
diff changeset
789 char *buff;
kono
parents:
diff changeset
790 int buff_len;
kono
parents:
diff changeset
791 int is_cld = 0;
kono
parents:
diff changeset
792
kono
parents:
diff changeset
793 file = to_host_file_spec (argv[i]);
kono
parents:
diff changeset
794 arg_len = strlen (file);
kono
parents:
diff changeset
795
kono
parents:
diff changeset
796 /* Handle shareable image libraries. */
kono
parents:
diff changeset
797 if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".exe") == 0)
kono
parents:
diff changeset
798 addswitch = "/shareable";
kono
parents:
diff changeset
799 else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".cld") == 0)
kono
parents:
diff changeset
800 {
kono
parents:
diff changeset
801 addswitch = "/shareable";
kono
parents:
diff changeset
802 is_cld = 1;
kono
parents:
diff changeset
803 }
kono
parents:
diff changeset
804
kono
parents:
diff changeset
805 /* Handle object libraries. */
kono
parents:
diff changeset
806 else if (arg_len > 2 && strcasecmp (&file[arg_len - 2], ".a") == 0)
kono
parents:
diff changeset
807 addswitch = "/lib";
kono
parents:
diff changeset
808 else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".olb") == 0)
kono
parents:
diff changeset
809 addswitch = "/lib";
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 /* Absolutize file location. */
kono
parents:
diff changeset
812 if (file[0] == '[')
kono
parents:
diff changeset
813 {
kono
parents:
diff changeset
814 buff = (char *) xmalloc (cwdevlen + arg_len + 1);
kono
parents:
diff changeset
815 sprintf (buff, "%s%s", cwdev, file);
kono
parents:
diff changeset
816 }
kono
parents:
diff changeset
817 else if (strchr (file, ':'))
kono
parents:
diff changeset
818 {
kono
parents:
diff changeset
819 buff = xstrdup (file);
kono
parents:
diff changeset
820 }
kono
parents:
diff changeset
821 else
kono
parents:
diff changeset
822 {
kono
parents:
diff changeset
823 buff = (char *) xmalloc (strlen (cwd) + arg_len + 1);
kono
parents:
diff changeset
824 sprintf (buff, "%s%s", cwd, file);
kono
parents:
diff changeset
825 }
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 buff_len = strlen (buff);
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 if (buff_len >= 15
kono
parents:
diff changeset
830 && strcasecmp (&buff[buff_len - 14], "vms-dwarf2eh.o") == 0)
kono
parents:
diff changeset
831 {
kono
parents:
diff changeset
832 /* Remind of it. */
kono
parents:
diff changeset
833 vmsdwarf2ehspec = xstrdup (buff);
kono
parents:
diff changeset
834 }
kono
parents:
diff changeset
835 else if (buff_len >= 13
kono
parents:
diff changeset
836 && strcasecmp (&buff[buff_len - 12], "vms-dwarf2.o") == 0)
kono
parents:
diff changeset
837 {
kono
parents:
diff changeset
838 /* Remind of it. */
kono
parents:
diff changeset
839 vmsdwarf2spec = xstrdup (buff);
kono
parents:
diff changeset
840 }
kono
parents:
diff changeset
841 else if (is_cld)
kono
parents:
diff changeset
842 {
kono
parents:
diff changeset
843 /* Command line definition file. */
kono
parents:
diff changeset
844 addarg (buff);
kono
parents:
diff changeset
845 addarg (addswitch);
kono
parents:
diff changeset
846 addarg (",");
kono
parents:
diff changeset
847 }
kono
parents:
diff changeset
848 else
kono
parents:
diff changeset
849 {
kono
parents:
diff changeset
850 fprintf (optfile, "%s%s\n",
kono
parents:
diff changeset
851 buff, addswitch != NULL ? addswitch : "");
kono
parents:
diff changeset
852 }
kono
parents:
diff changeset
853 free (buff);
kono
parents:
diff changeset
854 }
kono
parents:
diff changeset
855 }
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 if (vmsdwarf2ehspec)
kono
parents:
diff changeset
858 {
kono
parents:
diff changeset
859 /* Sequentialize exception handling info. */
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 fprintf (optfile, "case_sensitive=yes\n");
kono
parents:
diff changeset
862 fprintf (optfile, "cluster=DWARF2eh,,,%s\n", vmsdwarf2ehspec);
kono
parents:
diff changeset
863 fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
kono
parents:
diff changeset
864 fprintf (optfile, "case_sensitive=NO\n");
kono
parents:
diff changeset
865 }
kono
parents:
diff changeset
866
kono
parents:
diff changeset
867 if (debug && vmsdwarf2spec)
kono
parents:
diff changeset
868 {
kono
parents:
diff changeset
869 /* Sequentialize the debug info. */
kono
parents:
diff changeset
870
kono
parents:
diff changeset
871 fprintf (optfile, "case_sensitive=yes\n");
kono
parents:
diff changeset
872 fprintf (optfile, "cluster=DWARF2debug,,,%s\n", vmsdwarf2spec);
kono
parents:
diff changeset
873 fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
kono
parents:
diff changeset
874 fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
kono
parents:
diff changeset
875 fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
kono
parents:
diff changeset
876 fprintf (optfile, " debug_zzzzzz\n");
kono
parents:
diff changeset
877 fprintf (optfile, "case_sensitive=NO\n");
kono
parents:
diff changeset
878 }
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 if (debug && share && vmsdwarf2spec)
kono
parents:
diff changeset
881 {
kono
parents:
diff changeset
882 /* Sequentialize the shared library debug info. */
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 fprintf (optfile, "case_sensitive=yes\n");
kono
parents:
diff changeset
885 fprintf (optfile, "symbol_vector=(-\n");
kono
parents:
diff changeset
886 fprintf (optfile,
kono
parents:
diff changeset
887 "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
kono
parents:
diff changeset
888 sharebasename);
kono
parents:
diff changeset
889 fprintf (optfile,
kono
parents:
diff changeset
890 "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
kono
parents:
diff changeset
891 sharebasename);
kono
parents:
diff changeset
892 fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
kono
parents:
diff changeset
893 sharebasename);
kono
parents:
diff changeset
894 fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
kono
parents:
diff changeset
895 sharebasename);
kono
parents:
diff changeset
896 fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
kono
parents:
diff changeset
897 sharebasename);
kono
parents:
diff changeset
898 fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
kono
parents:
diff changeset
899 sharebasename);
kono
parents:
diff changeset
900 fprintf (optfile,
kono
parents:
diff changeset
901 "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
kono
parents:
diff changeset
902 sharebasename);
kono
parents:
diff changeset
903 fprintf (optfile,
kono
parents:
diff changeset
904 "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
kono
parents:
diff changeset
905 sharebasename);
kono
parents:
diff changeset
906 fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
kono
parents:
diff changeset
907 sharebasename);
kono
parents:
diff changeset
908 fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
kono
parents:
diff changeset
909 sharebasename);
kono
parents:
diff changeset
910 fprintf (optfile, "case_sensitive=NO\n");
kono
parents:
diff changeset
911 }
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 fprintf (optfile, "PSECT_ATTR=LIB$INITIALIZE,GBL\n");
kono
parents:
diff changeset
914 fclose (optfile);
kono
parents:
diff changeset
915
kono
parents:
diff changeset
916 /* Append opt file. */
kono
parents:
diff changeset
917 addarg (" ");
kono
parents:
diff changeset
918 addarg (optfilename);
kono
parents:
diff changeset
919 addarg ("/opt");
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 if (verbose)
kono
parents:
diff changeset
922 printf ("%s\n", link_cmd);
kono
parents:
diff changeset
923
kono
parents:
diff changeset
924 status = system (link_cmd);
kono
parents:
diff changeset
925 if (verbose > 1)
kono
parents:
diff changeset
926 printf ("$!status = %d\n", status);
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 if ((status & 1) != 1)
kono
parents:
diff changeset
929 {
kono
parents:
diff changeset
930 status = 1;
kono
parents:
diff changeset
931 goto cleanup_and_exit;
kono
parents:
diff changeset
932 }
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 if (debug && !share && ld_nocall_debug)
kono
parents:
diff changeset
935 {
kono
parents:
diff changeset
936 status = set_exe ("/flags=nocall_debug");
kono
parents:
diff changeset
937 if (status != 0)
kono
parents:
diff changeset
938 goto cleanup_and_exit;
kono
parents:
diff changeset
939 }
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 if (!share && ld_mkthreads)
kono
parents:
diff changeset
942 {
kono
parents:
diff changeset
943 status = set_exe ("/flags=mkthreads");
kono
parents:
diff changeset
944 if (status != 0)
kono
parents:
diff changeset
945 goto cleanup_and_exit;
kono
parents:
diff changeset
946 }
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 if (!share && ld_upcalls)
kono
parents:
diff changeset
949 {
kono
parents:
diff changeset
950 status = set_exe ("/flags=upcalls");
kono
parents:
diff changeset
951 if (status != 0)
kono
parents:
diff changeset
952 goto cleanup_and_exit;
kono
parents:
diff changeset
953 }
kono
parents:
diff changeset
954
kono
parents:
diff changeset
955 status = 0;
kono
parents:
diff changeset
956
kono
parents:
diff changeset
957 cleanup_and_exit:
kono
parents:
diff changeset
958 if (!save_temps)
kono
parents:
diff changeset
959 remove (optfilename);
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 if (status == 0)
kono
parents:
diff changeset
962 exit (EXIT_SUCCESS);
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 if (exefullfilename && inhibit_exec == 1)
kono
parents:
diff changeset
965 remove (exefullfilename);
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 exit (EXIT_FAILURE);
kono
parents:
diff changeset
968 }