]>
Commit | Line | Data |
---|---|---|
d133777f | 1 | /* VMS linker wrapper. |
a5c24926 | 2 | Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 |
16b61764 | 3 | Free Software Foundation, Inc. |
d133777f DR |
4 | Contributed by Douglas B. Rupp (rupp@gnat.com). |
5 | ||
7ec022b2 | 6 | This file is part of GCC. |
d133777f | 7 | |
7ec022b2 | 8 | GCC is free software; you can redistribute it and/or modify |
d133777f DR |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
7ec022b2 | 13 | GCC is distributed in the hope that it will be useful, |
d133777f DR |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
7ec022b2 | 19 | along with GCC; see the file COPYING. If not, write to |
d133777f DR |
20 | the Free Software Foundation, 59 Temple Place - Suite 330, |
21 | Boston, MA 02111-1307, USA. */ | |
22 | ||
23 | /* This program is a wrapper around the VMS linker. | |
24 | It translates Unix style command line options into corresponding | |
25 | VMS style qualifiers and then spawns the VMS linker. */ | |
26 | ||
27 | #include "config.h" | |
28 | #include "system.h" | |
4977bab6 ZW |
29 | #include "coretypes.h" |
30 | #include "tm.h" | |
d133777f DR |
31 | |
32 | typedef struct dsc {unsigned short len, mbz; char *adr; } Descr; | |
33 | ||
34 | #undef PATH_SEPARATOR | |
35 | #undef PATH_SEPARATOR_STR | |
36 | #define PATH_SEPARATOR ',' | |
37 | #define PATH_SEPARATOR_STR "," | |
38 | ||
39 | /* Local variable declarations. */ | |
40 | ||
41 | /* File specification for vms-dwarf2.o. */ | |
42 | static char *vmsdwarf2spec = 0; | |
43 | ||
16b61764 DR |
44 | /* File specification for vms-dwarf2eh.o. */ |
45 | static char *vmsdwarf2ehspec = 0; | |
46 | ||
d133777f DR |
47 | /* verbose = 1 if -v passed. */ |
48 | static int verbose = 0; | |
49 | ||
50 | /* save_temps = 1 if -save-temps passed. */ | |
51 | static int save_temps = 0; | |
52 | ||
53 | /* By default don't generate executable file if there are errors | |
54 | in the link. Override with --noinhibit-exec. */ | |
55 | static int inhibit_exec = 1; | |
56 | ||
57 | /* debug = 1 if -g passed. */ | |
58 | static int debug = 0; | |
59 | ||
60 | /* By default prefer to link with shareable image libraries. | |
61 | Override with -static. */ | |
62 | static int staticp = 0; | |
63 | ||
64 | /* By default generate an executable, not a shareable image library. | |
65 | Override with -shared. */ | |
66 | static int share = 0; | |
67 | ||
68 | /* Remember if IDENTIFICATION given on command line. */ | |
69 | static int ident = 0; | |
70 | ||
71 | /* Keep track of arg translations. */ | |
72 | static int link_arg_max = -1; | |
73 | static const char **link_args = 0; | |
74 | static int link_arg_index = -1; | |
75 | ||
76 | /* Keep track of filenames */ | |
77 | static char optfilefullname [267]; | |
78 | static char *sharefilename = 0; | |
79 | static char *exefilename = 0; | |
80 | ||
81 | /* System search dir list. Leave blank since link handles this | |
82 | internally. */ | |
83 | static char *system_search_dirs = ""; | |
84 | ||
85 | /* Search dir list passed on command line (with -L). */ | |
86 | static char *search_dirs; | |
87 | ||
88 | /* Local function declarations. */ | |
89 | ||
90 | /* Add STR to the list of arguments to pass to the linker. Expand the list as | |
d6a7951f | 91 | necessary to accommodate. */ |
a5c24926 | 92 | static void addarg (const char *); |
d133777f DR |
93 | |
94 | /* Check to see if NAME is a regular file, i.e. not a directory */ | |
a5c24926 | 95 | static int is_regular_file (char *); |
d133777f DR |
96 | |
97 | /* Translate a Unix syntax file specification FILESPEC into VMS syntax. | |
98 | If indicators of VMS syntax found, return input string. */ | |
a5c24926 | 99 | static char *to_host_file_spec (char *); |
d133777f DR |
100 | |
101 | /* Locate the library named LIB_NAME in the set of paths PATH_VAL. */ | |
a5c24926 | 102 | static char *locate_lib (char *, char *); |
d133777f DR |
103 | |
104 | /* Given a library name NAME, i.e. foo, Look for libfoo.lib and then | |
105 | libfoo.a in the set of directories we are allowed to search in. */ | |
a5c24926 | 106 | static const char *expand_lib (char *); |
d133777f DR |
107 | |
108 | /* Preprocess the number of args P_ARGC in ARGV. | |
109 | Look for special flags, etc. that must be handled first. */ | |
a5c24926 | 110 | static void preprocess_args (int *, char **); |
d133777f DR |
111 | |
112 | /* Preprocess the number of args P_ARGC in ARGV. Look for | |
113 | special flags, etc. that must be handled for the VMS linker. */ | |
a5c24926 | 114 | static void process_args (int *, char **); |
d133777f DR |
115 | |
116 | /* Action routine called by decc$to_vms. NAME is a file name or | |
117 | directory name. TYPE is unused. */ | |
a5c24926 | 118 | static int translate_unix (char *, int); |
d133777f | 119 | |
a5c24926 | 120 | int main (int, char **); |
d133777f DR |
121 | \f |
122 | static void | |
a5c24926 | 123 | addarg (const char *str) |
d133777f DR |
124 | { |
125 | int i; | |
126 | ||
127 | if (++link_arg_index >= link_arg_max) | |
128 | { | |
129 | const char **new_link_args | |
130 | = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *)); | |
131 | ||
132 | for (i = 0; i <= link_arg_max; i++) | |
133 | new_link_args [i] = link_args [i]; | |
134 | ||
135 | if (link_args) | |
136 | free (link_args); | |
137 | ||
138 | link_arg_max += 1000; | |
139 | link_args = new_link_args; | |
140 | } | |
141 | ||
142 | link_args [link_arg_index] = str; | |
143 | } | |
144 | ||
145 | static char * | |
a5c24926 | 146 | locate_lib (char *lib_name, char *path_val) |
d133777f DR |
147 | { |
148 | int lib_len = strlen (lib_name); | |
149 | char *eptr, *sptr; | |
150 | ||
151 | for (sptr = path_val; *sptr; sptr = eptr) | |
152 | { | |
153 | char *buf, *ptr; | |
154 | ||
155 | while (*sptr == PATH_SEPARATOR) | |
156 | sptr ++; | |
157 | ||
158 | eptr = strchr (sptr, PATH_SEPARATOR); | |
159 | if (eptr == 0) | |
160 | eptr = strchr (sptr, 0); | |
161 | ||
162 | buf = alloca ((eptr-sptr) + lib_len + 4 + 2); | |
163 | strncpy (buf, sptr, eptr-sptr); | |
164 | buf [eptr-sptr] = 0; | |
165 | strcat (buf, "/"); | |
166 | strcat (buf, lib_name); | |
167 | ptr = strchr (buf, 0); | |
168 | ||
169 | if (debug || staticp) | |
170 | { | |
171 | /* For debug or static links, look for shareable image libraries | |
172 | last. */ | |
173 | strcpy (ptr, ".a"); | |
174 | if (is_regular_file (buf)) | |
175 | return xstrdup (to_host_file_spec (buf)); | |
176 | ||
177 | strcpy (ptr, ".olb"); | |
178 | if (is_regular_file (buf)) | |
179 | return xstrdup (to_host_file_spec (buf)); | |
180 | ||
181 | strcpy (ptr, ".exe"); | |
182 | if (is_regular_file (buf)) | |
183 | return xstrdup (to_host_file_spec (buf)); | |
184 | } | |
185 | else | |
186 | { | |
187 | /* Otherwise look for shareable image libraries first. */ | |
188 | strcpy (ptr, ".exe"); | |
189 | if (is_regular_file (buf)) | |
190 | return xstrdup (to_host_file_spec (buf)); | |
191 | ||
192 | strcpy (ptr, ".a"); | |
193 | if (is_regular_file (buf)) | |
194 | return xstrdup (to_host_file_spec (buf)); | |
195 | ||
196 | strcpy (ptr, ".olb"); | |
197 | if (is_regular_file (buf)) | |
198 | return xstrdup (to_host_file_spec (buf)); | |
199 | } | |
200 | } | |
201 | ||
202 | return 0; | |
203 | } | |
204 | ||
205 | static const char * | |
a5c24926 | 206 | expand_lib (char *name) |
d133777f DR |
207 | { |
208 | char *lib, *lib_path; | |
209 | ||
210 | if (strcmp (name, "c") == 0) | |
211 | /* IEEE VAX C compatible library for non-prefixed (e.g. no DECC$) | |
212 | C RTL functions. */ | |
213 | return "sys$library:vaxcrtltx.olb"; | |
214 | ||
215 | else if (strcmp (name, "m") == 0) | |
216 | /* No separate library for math functions */ | |
217 | return ""; | |
218 | ||
219 | else | |
220 | { | |
221 | lib = xmalloc (strlen (name) + 14); | |
222 | ||
223 | strcpy (lib, "lib"); | |
224 | strcat (lib, name); | |
225 | lib_path = locate_lib (lib, search_dirs); | |
226 | ||
227 | if (lib_path) | |
228 | return lib_path; | |
229 | } | |
230 | ||
231 | fprintf (stderr, | |
232 | "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n", | |
233 | name, name, name); | |
234 | ||
235 | exit (1); | |
236 | } | |
237 | ||
238 | static int | |
a5c24926 | 239 | is_regular_file (char *name) |
d133777f DR |
240 | { |
241 | int ret; | |
242 | struct stat statbuf; | |
243 | ||
244 | ret = stat (name, &statbuf); | |
245 | return !ret && S_ISREG (statbuf.st_mode); | |
246 | } | |
247 | ||
248 | static void | |
a5c24926 | 249 | preprocess_args (int *p_argc, char **argv) |
d133777f DR |
250 | { |
251 | int i; | |
252 | ||
253 | for (i = 1; i < *p_argc; i++) | |
254 | if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0) | |
255 | share = 1; | |
256 | ||
257 | for (i = 1; i < *p_argc; i++) | |
258 | if (strcmp (argv[i], "-o") == 0) | |
259 | { | |
260 | char *buff, *ptr; | |
261 | int out_len; | |
262 | int len; | |
263 | ||
264 | i++; | |
265 | ptr = to_host_file_spec (argv[i]); | |
266 | exefilename = xstrdup (ptr); | |
267 | out_len = strlen (ptr); | |
268 | buff = xmalloc (out_len + 18); | |
269 | ||
270 | if (share) | |
271 | strcpy (buff, "/share="); | |
272 | else | |
273 | strcpy (buff, "/exe="); | |
274 | ||
275 | strcat (buff, ptr); | |
276 | addarg (buff); | |
277 | ||
278 | if (share) | |
279 | { | |
280 | sharefilename = xmalloc (out_len+5); | |
281 | if (ptr == strchr (argv[i], ']')) | |
282 | strcpy (sharefilename, ++ptr); | |
283 | else if (ptr == strchr (argv[i], ':')) | |
284 | strcpy (sharefilename, ++ptr); | |
285 | else if (ptr == strrchr (argv[i], '/')) | |
286 | strcpy (sharefilename, ++ptr); | |
287 | else | |
288 | strcpy (sharefilename, argv[i]); | |
289 | ||
290 | len = strlen (sharefilename); | |
291 | if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0) | |
292 | sharefilename[len-4] = 0; | |
293 | ||
294 | for (ptr = sharefilename; *ptr; ptr++) | |
295 | *ptr = TOUPPER (*ptr); | |
296 | } | |
297 | } | |
298 | } | |
299 | ||
300 | static void | |
a5c24926 | 301 | process_args (int *p_argc, char **argv) |
d133777f DR |
302 | { |
303 | int i; | |
304 | ||
305 | for (i = 1; i < *p_argc; i++) | |
306 | { | |
307 | if (strlen (argv[i]) < 2) | |
308 | continue; | |
309 | ||
310 | if (strncmp (argv[i], "-L", 2) == 0) | |
311 | { | |
312 | char *nbuff, *ptr; | |
313 | int new_len, search_dirs_len; | |
314 | ||
315 | ptr = &argv[i][2]; | |
316 | new_len = strlen (ptr); | |
317 | search_dirs_len = strlen (search_dirs); | |
318 | ||
319 | nbuff = xmalloc (new_len + 1); | |
320 | strcpy (nbuff, ptr); | |
321 | ||
322 | /* Remove trailing slashes. */ | |
323 | while (new_len > 1 && nbuff [new_len - 1] == '/') | |
324 | { | |
325 | nbuff [new_len - 1] = 0; | |
326 | new_len--; | |
327 | } | |
328 | ||
329 | search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2); | |
330 | if (search_dirs_len > 0) | |
331 | strcat (search_dirs, PATH_SEPARATOR_STR); | |
332 | ||
333 | strcat (search_dirs, nbuff); | |
334 | free (nbuff); | |
335 | } | |
336 | ||
337 | /* -v turns on verbose option here and is passed on to gcc. */ | |
338 | else if (strcmp (argv[i], "-v") == 0) | |
339 | verbose = 1; | |
340 | else if (strcmp (argv[i], "-g0") == 0) | |
341 | addarg ("/notraceback"); | |
342 | else if (strncmp (argv[i], "-g", 2) == 0) | |
343 | { | |
344 | addarg ("/debug"); | |
345 | debug = 1; | |
346 | } | |
347 | else if (strcmp (argv[i], "-static") == 0) | |
348 | staticp = 1; | |
349 | else if (strcmp (argv[i], "-map") == 0) | |
350 | { | |
351 | char *buff, *ptr; | |
352 | ||
353 | buff = xmalloc (strlen (exefilename) + 5); | |
354 | strcpy (buff, exefilename); | |
355 | ptr = strchr (buff, '.'); | |
356 | if (ptr) | |
357 | *ptr = 0; | |
358 | ||
359 | strcat (buff, ".map"); | |
360 | addarg ("/map="); | |
361 | addarg (buff); | |
362 | addarg ("/full"); | |
363 | } | |
364 | else if (strcmp (argv[i], "-save-temps") == 0) | |
365 | save_temps = 1; | |
366 | else if (strcmp (argv[i], "--noinhibit-exec") == 0) | |
367 | inhibit_exec = 0; | |
368 | } | |
369 | } | |
370 | ||
371 | /* The main program. Spawn the VMS linker after fixing up the Unix-like flags | |
372 | and args to be what the VMS linker wants. */ | |
373 | ||
374 | int | |
a5c24926 | 375 | main (int argc, char **argv) |
d133777f DR |
376 | { |
377 | int i; | |
378 | char cwdev [128], *devptr; | |
379 | int devlen; | |
380 | int optfd; | |
381 | FILE *optfile; | |
382 | char *cwd = getcwd (0, 1024); | |
383 | char *optfilename; | |
384 | ||
385 | devptr = strchr (cwd, ':'); | |
386 | devlen = (devptr - cwd) + 1; | |
387 | strncpy (cwdev, cwd, devlen); | |
388 | cwdev [devlen] = '\0'; | |
389 | ||
1dcd444b | 390 | search_dirs = xstrdup (system_search_dirs); |
d133777f DR |
391 | |
392 | addarg ("link"); | |
393 | ||
394 | /* Pass to find args that have to be append first. */ | |
395 | preprocess_args (&argc , argv); | |
396 | ||
397 | /* Pass to find the rest of the args. */ | |
398 | process_args (&argc , argv); | |
399 | ||
400 | /* Create a temp file to hold args, otherwise we can easily exceed the VMS | |
401 | command line length limits. */ | |
402 | optfilename = alloca (strlen ("LDXXXXXX") + 1); | |
403 | strcpy (optfilename, "LDXXXXXX"); | |
404 | optfd = mkstemp (optfilename); | |
405 | getcwd (optfilefullname, 256, 1); /* VMS style cwd. */ | |
406 | strcat (optfilefullname, optfilename); | |
407 | strcat (optfilefullname, "."); | |
408 | optfile = fdopen (optfd, "w"); | |
409 | ||
410 | /* Write out the IDENTIFICATION argument first so that it can be overridden | |
411 | by an options file. */ | |
412 | for (i = 1; i < argc; i++) | |
413 | { | |
414 | int arg_len = strlen (argv[i]); | |
415 | ||
416 | if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) | |
417 | { | |
418 | /* Comes from command line. If present will always appear before | |
419 | IDENTIFICATION=... and will override. */ | |
420 | ||
421 | if (!ident) | |
422 | ident = 1; | |
423 | } | |
424 | else if (arg_len > 15 | |
425 | && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) | |
426 | { | |
427 | /* Comes from pragma Ident (). */ | |
428 | ||
429 | if (!ident) | |
430 | { | |
431 | fprintf (optfile, "case_sensitive=yes\n"); | |
432 | fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]); | |
433 | fprintf (optfile, "case_sensitive=NO\n"); | |
434 | ident = 1; | |
435 | } | |
436 | } | |
437 | } | |
438 | ||
439 | for (i = 1; i < argc; i++) | |
440 | { | |
441 | int arg_len = strlen (argv[i]); | |
442 | ||
443 | if (strcmp (argv[i], "-o") == 0) | |
444 | i++; | |
445 | else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0) | |
446 | { | |
447 | const char *libname = expand_lib (&argv[i][2]); | |
448 | const char *ext; | |
449 | int len; | |
450 | ||
451 | if ((len = strlen (libname)) > 0) | |
452 | { | |
453 | char buff [256]; | |
454 | ||
455 | if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0) | |
456 | ext = "/shareable"; | |
457 | else | |
458 | ext = "/library"; | |
459 | ||
460 | if (libname[0] == '[') | |
461 | sprintf (buff, "%s%s", cwdev, libname); | |
462 | else | |
463 | sprintf (buff, "%s", libname); | |
464 | ||
465 | fprintf (optfile, "%s%s\n", buff, ext); | |
466 | } | |
467 | } | |
468 | ||
469 | else if (strcmp (argv[i], "-v" ) == 0 | |
470 | || strncmp (argv[i], "-g", 2 ) == 0 | |
471 | || strcmp (argv[i], "-static" ) == 0 | |
472 | || strcmp (argv[i], "-map" ) == 0 | |
473 | || strcmp (argv[i], "-save-temps") == 0 | |
474 | || strcmp (argv[i], "--noinhibit-exec") == 0 | |
475 | || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0) | |
476 | || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0)) | |
477 | ; | |
478 | else if (arg_len > 1 && argv[i][0] == '@') | |
479 | { | |
480 | FILE *atfile; | |
481 | char *ptr, *ptr1; | |
482 | struct stat statbuf; | |
483 | char *buff; | |
484 | int len; | |
485 | ||
486 | if (stat (&argv[i][1], &statbuf)) | |
487 | { | |
488 | fprintf (stderr, "Couldn't open linker response file: %s\n", | |
489 | &argv[i][1]); | |
490 | exit (1); | |
491 | } | |
492 | ||
493 | buff = xmalloc (statbuf.st_size + 1); | |
494 | atfile = fopen (&argv[i][1], "r"); | |
495 | fgets (buff, statbuf.st_size + 1, atfile); | |
496 | fclose (atfile); | |
497 | ||
498 | len = strlen (buff); | |
499 | if (buff [len - 1] == '\n') | |
500 | { | |
501 | buff [len - 1] = 0; | |
502 | len--; | |
503 | } | |
504 | ||
505 | ptr = buff; | |
506 | ||
507 | do | |
508 | { | |
509 | ptr1 = strchr (ptr, ' '); | |
510 | if (ptr1) | |
511 | *ptr1 = 0; | |
512 | ptr = to_host_file_spec (ptr); | |
513 | if (ptr[0] == '[') | |
514 | fprintf (optfile, "%s%s\n", cwdev, ptr); | |
515 | else | |
516 | fprintf (optfile, "%s\n", ptr); | |
517 | ptr = ptr1 + 1; | |
518 | } while (ptr1); | |
519 | } | |
520 | ||
521 | /* Unix style file specs and VMS style switches look alike, so assume an | |
522 | arg consisting of one and only one slash, and that being first, is | |
523 | really a switch. */ | |
524 | else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0)) | |
525 | addarg (argv[i]); | |
526 | else if (arg_len > 4 | |
527 | && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0) | |
528 | { | |
529 | FILE *optfile1; | |
530 | char buff [256]; | |
531 | ||
532 | optfile1 = fopen (argv[i], "r"); | |
533 | while (fgets (buff, 256, optfile1)) | |
534 | fputs (buff, optfile); | |
535 | ||
536 | fclose (optfile1); | |
537 | } | |
538 | else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0) | |
539 | fprintf (optfile, "%s\n", argv[i]); | |
540 | else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) | |
541 | { | |
542 | /* Comes from command line and will override pragma. */ | |
543 | fprintf (optfile, "case_sensitive=yes\n"); | |
544 | fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]); | |
545 | fprintf (optfile, "case_sensitive=NO\n"); | |
546 | ident = 1; | |
547 | } | |
548 | else if (arg_len > 15 | |
549 | && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) | |
550 | ; | |
551 | else | |
552 | { | |
553 | /* Assume filename arg. */ | |
554 | const char *addswitch = ""; | |
555 | char buff [256]; | |
556 | int buff_len; | |
557 | int is_cld = 0; | |
558 | ||
559 | argv[i] = to_host_file_spec (argv[i]); | |
560 | arg_len = strlen (argv[i]); | |
561 | ||
562 | if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0) | |
563 | addswitch = "/shareable"; | |
564 | ||
565 | if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0) | |
566 | { | |
567 | addswitch = "/shareable"; | |
568 | is_cld = 1; | |
569 | } | |
570 | ||
571 | if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0) | |
572 | addswitch = "/lib"; | |
573 | ||
574 | if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0) | |
575 | addswitch = "/lib"; | |
576 | ||
577 | if (argv[i][0] == '[') | |
578 | sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch); | |
579 | else if (strchr (argv[i], ':')) | |
580 | sprintf (buff, "%s%s\n", argv[i], addswitch); | |
581 | else | |
582 | sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch); | |
583 | ||
584 | buff_len = strlen (buff); | |
585 | ||
16b61764 DR |
586 | if (buff_len >= 15 |
587 | && strcasecmp (&buff[buff_len - 15], "vms-dwarf2eh.o\n") == 0) | |
588 | vmsdwarf2ehspec = xstrdup (buff); | |
589 | else if (buff_len >= 13 | |
590 | && strcasecmp (&buff[buff_len - 13],"vms-dwarf2.o\n") == 0) | |
d133777f DR |
591 | vmsdwarf2spec = xstrdup (buff); |
592 | else if (is_cld) | |
593 | { | |
594 | addarg (buff); | |
595 | addarg (","); | |
596 | } | |
597 | else | |
598 | fprintf (optfile, buff); | |
599 | } | |
600 | } | |
601 | ||
602 | #if 0 | |
603 | if (share) | |
604 | fprintf (optfile, "symbol_vector=(main=procedure)\n"); | |
605 | #endif | |
606 | ||
16b61764 DR |
607 | if (vmsdwarf2ehspec) |
608 | { | |
609 | fprintf (optfile, "case_sensitive=yes\n"); | |
610 | fprintf (optfile, "cluster=DWARF2eh,,,%s", vmsdwarf2ehspec); | |
611 | fprintf (optfile, "collect=DWARF2eh,eh_frame\n"); | |
612 | fprintf (optfile, "case_sensitive=NO\n"); | |
613 | } | |
614 | ||
d133777f DR |
615 | if (debug && vmsdwarf2spec) |
616 | { | |
617 | fprintf (optfile, "case_sensitive=yes\n"); | |
618 | fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec); | |
619 | fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n"); | |
620 | fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n"); | |
16b61764 DR |
621 | fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n"); |
622 | fprintf (optfile, " debug_zzzzzz\n"); | |
d133777f DR |
623 | fprintf (optfile, "case_sensitive=NO\n"); |
624 | } | |
625 | ||
626 | if (debug && share) | |
627 | { | |
628 | fprintf (optfile, "case_sensitive=yes\n"); | |
629 | fprintf (optfile, "symbol_vector=(-\n"); | |
630 | fprintf (optfile, | |
631 | "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n", | |
632 | sharefilename); | |
633 | fprintf (optfile, | |
634 | "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n", | |
635 | sharefilename); | |
636 | fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n", | |
637 | sharefilename); | |
638 | fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n", | |
639 | sharefilename); | |
640 | fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n", | |
641 | sharefilename); | |
642 | fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n", | |
643 | sharefilename); | |
644 | fprintf (optfile, | |
645 | "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n", | |
646 | sharefilename); | |
647 | fprintf (optfile, | |
648 | "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n", | |
649 | sharefilename); | |
650 | fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n", | |
651 | sharefilename); | |
652 | fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n", | |
653 | sharefilename); | |
654 | fprintf (optfile, "case_sensitive=NO\n"); | |
655 | } | |
656 | ||
657 | fclose (optfile); | |
658 | addarg (optfilefullname); | |
659 | addarg ("/opt"); | |
660 | ||
661 | addarg (NULL); | |
662 | ||
663 | if (verbose) | |
664 | { | |
665 | int i; | |
666 | ||
667 | for (i = 0; i < link_arg_index; i++) | |
668 | printf ("%s ", link_args [i]); | |
669 | putchar ('\n'); | |
670 | } | |
671 | ||
672 | { | |
673 | int i; | |
674 | int len = 0; | |
675 | ||
676 | for (i = 0; link_args[i]; i++) | |
677 | len = len + strlen (link_args[i]) + 1; | |
678 | ||
679 | { | |
680 | char *allargs = (char *) alloca (len + 1); | |
681 | Descr cmd; | |
682 | int status; | |
683 | int status1 = 1; | |
684 | ||
685 | for (i = 0; i < len + 1; i++) | |
686 | allargs [i] = 0; | |
687 | ||
688 | for (i = 0; link_args [i]; i++) | |
689 | { | |
690 | strcat (allargs, link_args [i]); | |
691 | strcat (allargs, " "); | |
692 | } | |
693 | ||
694 | cmd.adr = allargs; | |
695 | cmd.len = len; | |
696 | cmd.mbz = 0; | |
697 | ||
698 | i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status); | |
699 | if ((i & 1) != 1) | |
700 | { | |
701 | LIB$SIGNAL (i); | |
702 | exit (1); | |
703 | } | |
704 | ||
705 | if (debug && !share) | |
706 | { | |
707 | strcpy (allargs, "@gnu:[bin]set_exe "); | |
708 | strcat (allargs, exefilename); | |
709 | strcat (allargs, " /nodebug /silent"); | |
710 | len = strlen (allargs); | |
711 | cmd.adr = allargs; | |
712 | cmd.len = len; | |
713 | cmd.mbz = 0; | |
714 | ||
715 | if (verbose) | |
716 | printf (allargs); | |
717 | ||
718 | i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1); | |
719 | ||
720 | if ((i & 1) != 1) | |
721 | { | |
722 | LIB$SIGNAL (i); | |
723 | exit (1); | |
724 | } | |
725 | } | |
726 | ||
727 | if (!save_temps) | |
728 | remove (optfilefullname); | |
729 | ||
730 | if ((status & 1) == 1 && (status1 & 1) == 1) | |
731 | exit (0); | |
732 | ||
733 | if (exefilename && inhibit_exec == 1) | |
734 | remove (exefilename); | |
735 | ||
736 | exit (1); | |
737 | } | |
738 | } | |
739 | } | |
740 | ||
741 | static char new_host_filespec [255]; | |
742 | static char filename_buff [256]; | |
743 | ||
744 | static int | |
a5c24926 | 745 | translate_unix (char *name, int type ATTRIBUTE_UNUSED) |
d133777f DR |
746 | { |
747 | strcpy (filename_buff, name); | |
748 | return 0; | |
749 | } | |
750 | ||
751 | static char * | |
a5c24926 | 752 | to_host_file_spec (char *filespec) |
d133777f DR |
753 | { |
754 | strcpy (new_host_filespec, ""); | |
755 | if (strchr (filespec, ']') || strchr (filespec, ':')) | |
756 | strcpy (new_host_filespec, filespec); | |
757 | else | |
758 | { | |
759 | decc$to_vms (filespec, translate_unix, 1, 1); | |
760 | strcpy (new_host_filespec, filename_buff); | |
761 | } | |
762 | ||
763 | return new_host_filespec; | |
764 | } |