PR rtl-optimization/88018
[official-gcc.git] / gcc / config / vms / vms-ld.c
blobed2b26b950b0fa60fb7f618832bcd3f0dc8fb2b8
1 /* VMS linker wrapper.
2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
3 Contributed by AdaCore
5 This file is part of GCC.
7 GCC 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.
12 GCC 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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This program is a wrapper around the VMS linker.
22 It translates Unix style command line options into corresponding
23 VMS style qualifiers and then spawns the VMS linker.
25 It is possible to build this program on UNIX but only for the purpose of
26 checking for errors. */
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <stdio.h>
33 #include "libiberty.h"
34 #include <safe-ctype.h>
35 #include <sys/stat.h>
37 /* Macro for logicals. */
38 #define LNM__STRING 2
39 #define LNM_C_NAMLENGTH 255
40 #define PSL_C_SUPER 2
41 #define PSL_C_USER 3
43 /* Local variable declarations. */
44 static int ld_nocall_debug = 0;
45 static int ld_mkthreads = 0;
46 static int ld_upcalls = 0;
48 /* verbose = 1 if -v passed. */
49 static int verbose = 0;
51 /* save_temps = 1 if -save-temps passed. */
52 static int save_temps = 0;
54 /* By default don't generate executable file if there are errors
55 in the link. Override with --noinhibit-exec. */
56 static int inhibit_exec = 1;
58 /* debug = 1 if -g passed. */
59 static int debug = 0;
61 /* By default prefer to link with static libraries. */
62 static int staticp = 1;
64 /* By default generate an executable, not a shareable image library.
65 Override with -shared. */
66 static int share = 0;
68 /* Linker command line. */
69 static int link_cmd_maxlen = 0;
70 static char *link_cmd = 0;
71 static int link_cmd_len = 0;
73 /* Keep track of filenames. */
74 static char *sharebasename;
75 static const char *exefullfilename;
76 static const char *exefilename;
78 /* Search dir list passed on command line (with -L). */
79 static const char **search_dirs;
80 static int search_dirs_len;
82 /* Local function declarations. */
83 static void addarg (const char *);
84 static int is_regular_file (char *);
85 static char *to_host_file_spec (char *);
86 static char *locate_lib (char *);
87 static const char *expand_lib (char *);
88 static void preprocess_args (int, char **);
89 static void process_args (int, char **);
90 static void maybe_set_link_compat (void);
91 static int set_exe (const char *);
92 #ifdef VMS
93 static int translate_unix (char *, int);
94 #endif
97 /* Append STR to the command line to invoke the linker.
98 Expand the line as necessary to accommodate. */
100 static void
101 addarg (const char *str)
103 int l = strlen (str);
105 /* Extend the line. */
106 if (link_cmd_len + l >= link_cmd_maxlen)
108 link_cmd_maxlen = link_cmd_len + l + 1024;
109 link_cmd = XRESIZEVEC (char, link_cmd, link_cmd_maxlen);
112 memcpy (link_cmd + link_cmd_len, str, l);
113 link_cmd_len += l;
116 /* Check to see if NAME is a regular file, i.e. not a directory. */
118 static int
119 is_regular_file (char *name)
121 int ret;
122 struct stat statbuf;
124 ret = stat (name, &statbuf);
125 return !ret && S_ISREG (statbuf.st_mode);
128 #ifdef VMS
129 static char new_host_filespec [255];
130 static char filename_buff [256];
132 /* Action routine called by decc$to_vms. NAME is a file name or
133 directory name. TYPE is unused. */
135 static int
136 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
138 strcpy (filename_buff, name);
139 return 0;
141 #endif
143 /* Translate a Unix syntax file specification FILESPEC into VMS syntax.
144 If indicators of VMS syntax found, return input string.
145 Return a pointer to a static buffer. */
147 static char *
148 to_host_file_spec (char *filespec)
150 #ifdef VMS
151 if (strchr (filespec, ']') || strchr (filespec, ':'))
153 /* Looks like a VMS path. */
154 return filespec;
156 else
159 strcpy (filename_buff, filespec);
160 decc$to_vms (filespec, translate_unix, 1, 1);
161 strcpy (new_host_filespec, filename_buff);
162 return new_host_filespec;
164 #else
165 return filespec;
166 #endif
169 /* Locate library LIB_NAME on the library path. */
171 static char *
172 locate_lib (char *lib_name)
174 int lib_len = strlen (lib_name);
175 const char *exts[3];
176 int i;
178 if (staticp)
180 /* For static links, look for shareable image libraries last. */
181 exts[0] = ".a";
182 exts[1] = ".olb";
183 exts[2] = ".exe";
185 else
187 exts[0] = ".exe";
188 exts[1] = ".a";
189 exts[2] = ".olb";
192 for (i = 0; i < search_dirs_len; i++)
194 char *buf;
195 int l;
196 int j;
198 l = strlen (search_dirs[i]);
199 buf = (char *)alloca (l + 4 + lib_len + 4 + 1);
200 /* Put PATH/libLIB. */
201 memcpy (buf, search_dirs[i], l);
202 memcpy (buf + l, "/lib", 4);
203 l += 4;
204 memcpy (buf + l, lib_name, lib_len);
205 l += lib_len;
207 /* Look for files with the extensions. */
208 for (j = 0; j < 3; j++)
210 strcpy (buf + l, exts[j]);
211 if (is_regular_file (buf))
212 return xstrdup (to_host_file_spec (buf));
216 return NULL;
219 /* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
220 libfoo.a in the set of directories we are allowed to search in.
221 May return NULL if the library can be discarded. */
223 static const char *
224 expand_lib (char *name)
226 char *lib_path;
228 /* Discard libc. */
229 if (strcmp (name, "c") == 0)
230 return NULL;
232 /* Discard libm. No separate library for math functions. */
233 if (strcmp (name, "m") == 0)
234 return NULL;
236 /* Search on path. */
237 lib_path = locate_lib (name);
238 if (lib_path)
239 return lib_path;
241 fprintf (stderr,
242 "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
243 name, name, name);
245 exit (EXIT_FAILURE);
248 /* Preprocess the number of args P_ARGC in ARGV.
249 Look for special flags, etc. that must be handled first. */
251 static void
252 preprocess_args (int argc, char **argv)
254 int i;
256 /* Scan for -shared. */
257 for (i = 1; i < argc; i++)
258 if (strcmp (argv[i], "-shared") == 0)
260 share = 1;
261 break;
264 for (i = 1; i < argc; i++)
265 if (strcmp (argv[i], "-o") == 0)
267 int len;
269 i++;
270 exefilename = lbasename (argv[i]);
271 exefullfilename = xstrdup (to_host_file_spec (argv[i]));
273 if (share)
274 addarg(" /share=");
275 else
276 addarg (" /exe=");
277 addarg (exefullfilename);
279 if (share)
281 char *ptr;
283 /* Extract the basename. */
284 ptr = strchr (argv[i], ']');
285 if (ptr == NULL)
286 ptr = strchr (argv[i], ':');
287 if (ptr == NULL)
288 ptr = strchr (argv[i], '/');
289 if (ptr == NULL)
290 sharebasename = xstrdup (argv[i]);
291 else
292 sharebasename = xstrdup (ptr + 1);
294 len = strlen (sharebasename);
295 if (strncasecmp (&sharebasename[len-4], ".exe", 4) == 0)
296 sharebasename[len - 4] = 0;
298 /* Convert to uppercase. */
299 for (ptr = sharebasename; *ptr; ptr++)
300 *ptr = TOUPPER (*ptr);
304 if (exefullfilename == NULL && !share)
306 exefilename = "a_out.exe";
307 exefullfilename = "a_out.exe";
308 addarg (xstrdup (" /exe=a_out.exe"));
312 /* Preprocess the number of args ARGC in ARGV. Look for
313 special flags, etc. that must be handled for the VMS linker. */
315 static void
316 process_args (int argc, char **argv)
318 int i;
320 for (i = 1; i < argc; i++)
322 if (strncmp (argv[i], "-L", 2) == 0)
324 search_dirs = XRESIZEVEC(const char *, search_dirs,
325 search_dirs_len + 1);
326 search_dirs[search_dirs_len++] = &argv[i][2];
329 /* -v turns on verbose option here and is passed on to gcc. */
330 else if (strcmp (argv[i], "-v") == 0)
331 verbose++;
332 else if (strcmp (argv[i], "--version") == 0)
334 fprintf (stdout, "VMS Linker\n");
335 exit (EXIT_SUCCESS);
337 else if (strcmp (argv[i], "--help") == 0)
339 fprintf (stdout, "VMS Linker\n");
340 exit (EXIT_SUCCESS);
342 else if (strcmp (argv[i], "-g0") == 0)
343 addarg ("/notraceback");
344 else if (strncmp (argv[i], "-g", 2) == 0)
346 addarg ("/debug");
347 debug = 1;
349 else if (strcmp (argv[i], "-static") == 0)
350 staticp = 1;
351 else if (strcmp (argv[i], "-map") == 0)
353 char *buff, *ptr;
355 buff = (char *) xstrdup (exefullfilename);
356 ptr = strrchr (buff, '.');
357 if (ptr)
358 *ptr = 0;
360 strcat (buff, ".map");
361 addarg ("/map=");
362 addarg (buff);
363 addarg (".map");
364 addarg ("/full");
366 free (buff);
368 else if (strcmp (argv[i], "-save-temps") == 0)
369 save_temps = 1;
370 else if (strcmp (argv[i], "--noinhibit-exec") == 0)
371 inhibit_exec = 0;
375 #ifdef VMS
376 typedef struct dsc
378 unsigned short len, mbz;
379 const char *adr;
380 } Descriptor;
382 struct lst
384 unsigned short buflen, item_code;
385 const void *bufaddr;
386 void *retlenaddr;
389 static struct
391 struct lst items [1];
392 unsigned int terminator;
393 } item_lst1;
395 static struct
397 struct lst items [2];
398 unsigned int terminator;
399 } item_lst2;
401 /* Checks if logical names are defined for setting system library path and
402 linker program to enable compatibility with earlier VMS versions. */
404 static void
405 maybe_set_link_compat (void)
407 char lnm_buff [LNM_C_NAMLENGTH];
408 unsigned int lnm_buff_len;
409 int status;
410 Descriptor tabledsc, linkdsc;
412 tabledsc.adr = "LNM$JOB";
413 tabledsc.len = strlen (tabledsc.adr);
414 tabledsc.mbz = 0;
416 linkdsc.adr = "GCC_LD_SYS$LIBRARY";
417 linkdsc.len = strlen (linkdsc.adr);
418 linkdsc.mbz = 0;
420 item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
421 item_lst1.items[0].item_code = LNM__STRING;
422 item_lst1.items[0].bufaddr = lnm_buff;
423 item_lst1.items[0].retlenaddr = &lnm_buff_len;
424 item_lst1.terminator = 0;
426 status = SYS$TRNLNM
427 (0, /* attr */
428 &tabledsc, /* tabnam */
429 &linkdsc, /* lognam */
430 0, /* acmode */
431 &item_lst1);
433 /* If GCC_LD_SYS$LIBRARY is defined, redefine SYS$LIBRARY to search
434 the equivalence name first for system libraries, then the default
435 system library directory */
437 if ((status & 1) == 1)
439 unsigned char acmode = PSL_C_USER; /* Don't retain after image exit */
440 const char *syslib = "SYS$SYSROOT:[SYSLIB]"; /* Default SYS$LIBRARY */
442 /* Only visible to current and child processes */
443 tabledsc.adr = "LNM$PROCESS";
444 tabledsc.len = strlen (tabledsc.adr);
445 tabledsc.mbz = 0;
447 linkdsc.adr = "SYS$LIBRARY";
448 linkdsc.len = strlen (linkdsc.adr);
449 linkdsc.mbz = 0;
451 item_lst2.items[0].buflen = lnm_buff_len;
452 item_lst2.items[0].item_code = LNM__STRING;
453 item_lst2.items[0].bufaddr = lnm_buff;
454 item_lst2.items[0].retlenaddr = 0;
456 item_lst2.items[1].buflen = strlen (syslib);
457 item_lst2.items[1].item_code = LNM__STRING;
458 item_lst2.items[1].bufaddr = syslib;
459 item_lst2.items[1].retlenaddr = 0;
460 item_lst2.terminator = 0;
462 status = SYS$CRELNM
463 (0, /* attr */
464 &tabledsc, /* tabnam */
465 &linkdsc, /* lognam */
466 &acmode, /* acmode */
467 &item_lst2);
471 tabledsc.adr = "LNM$JOB";
472 tabledsc.len = strlen (tabledsc.adr);
473 tabledsc.mbz = 0;
475 linkdsc.adr = "GCC_LD_LINK";
476 linkdsc.len = strlen (linkdsc.adr);
477 linkdsc.mbz = 0;
479 item_lst1.items[0].buflen = LNM_C_NAMLENGTH;
480 item_lst1.items[0].item_code = LNM__STRING;
481 item_lst1.items[0].bufaddr = lnm_buff;
482 item_lst1.items[0].retlenaddr = &lnm_buff_len;
483 item_lst1.terminator = 0;
485 status = SYS$TRNLNM
486 (0, /* attr */
487 &tabledsc, /* tabnam */
488 &linkdsc, /* lognam */
489 0, /* acmode */
490 &item_lst1);
492 /* If GCC_LD_LINK is defined, redefine LINK to use the equivalence name
493 (sometimes the LINK program version is used by VMS to determine
494 compatibility). */
496 if ((status & 1) == 1)
498 unsigned char acmode = PSL_C_USER; /* Don't retain after image exit. */
500 /* Only visible to current and child processes. */
501 tabledsc.adr = "LNM$PROCESS";
502 tabledsc.len = strlen (tabledsc.adr);
503 tabledsc.mbz = 0;
505 linkdsc.adr = "LINK";
506 linkdsc.len = strlen (linkdsc.adr);
507 linkdsc.mbz = 0;
509 item_lst1.items[0].buflen = lnm_buff_len;
510 item_lst1.items[0].item_code = LNM__STRING;
511 item_lst1.items[0].bufaddr = lnm_buff;
512 item_lst1.items[0].retlenaddr = 0;
513 item_lst1.terminator = 0;
515 status = SYS$CRELNM
516 (0, /* attr */
517 &tabledsc, /* tabnam */
518 &linkdsc, /* lognam */
519 &acmode, /* acmode */
520 &item_lst1);
523 #else
524 static void
525 maybe_set_link_compat (void)
528 #endif
530 /* Set environment defined executable attributes. */
532 static int
533 set_exe (const char *arg)
535 char allargs [1024];
536 int res;
538 snprintf (allargs, sizeof (allargs),
539 "$@gnu:[bin]set_exe %s %s", exefullfilename, arg);
540 if (verbose)
541 printf ("%s\n", allargs);
543 res = system (allargs);
544 if (verbose > 1)
545 printf ("$!status = %d\n", res);
547 if ((res & 1) != 1)
549 fprintf (stderr, "ld error: popen set_exe\n");
550 return 1;
552 return 0;
555 /* The main program. Spawn the VMS linker after fixing up the Unix-like flags
556 and args to be what the VMS linker wants. */
559 main (int argc, char **argv)
561 /* File specification for vms-dwarf2.o. */
562 char *vmsdwarf2spec = 0;
564 /* File specification for vms-dwarf2eh.o. */
565 char *vmsdwarf2ehspec = 0;
567 int i;
568 char cwdev[128], *devptr;
569 int cwdevlen;
570 FILE *optfile;
571 char *cwd, *ptr;
572 char *optfilename;
573 int status = 0;
575 /* Some linker options can be set with logicals. */
576 if (getenv ("GNAT$LD_NOCALL_DEBUG"))
577 ld_nocall_debug = 1;
578 if (getenv ("GNAT$LD_MKTHREADS"))
579 ld_mkthreads = 1;
580 if (getenv ("GNAT$LD_UPCALLS"))
581 ld_upcalls = 1;
582 if (getenv ("GNAT$LD_SHARED_LIBS"))
583 staticp = 0;
585 /* Get current dir. */
586 #ifdef VMS
587 cwd = getcwd (0, 1024, 1);
588 #else
589 cwd = getcwd (0, 1024);
590 strcat (cwd, "/");
591 #endif
593 /* Extract device part of the path. */
594 devptr = strchr (cwd, ':');
595 if (devptr)
596 cwdevlen = (devptr - cwd) + 1;
597 else
598 cwdevlen = 0;
599 memcpy (cwdev, cwd, cwdevlen);
600 cwdev [cwdevlen] = '\0';
602 maybe_set_link_compat ();
604 /* Linker command starts with the command name. */
605 addarg ("$ link");
607 /* Pass to find args that have to be append first. */
608 preprocess_args (argc , argv);
610 /* Pass to find the rest of the args. */
611 process_args (argc , argv);
613 if (!verbose)
614 addarg ("/noinform");
616 /* Create a temp file to hold args, otherwise we can easily exceed the VMS
617 command line length limits. */
618 optfilename = (char *) xmalloc (strlen (exefilename) + 13);
619 strcpy (optfilename, exefilename);
620 ptr = strrchr (optfilename, '.');
621 if (ptr)
622 *ptr = 0;
623 strcat (optfilename, ".opt_tmpfile");
624 optfile = fopen (optfilename, "w");
626 /* Write out the IDENTIFICATION argument first so that it can be overridden
627 by an options file. */
628 for (i = 1; i < argc; i++)
630 int arg_len = strlen (argv[i]);
632 if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
634 /* Comes from command line. If present will always appear before
635 --identification=... and will override. */
636 break;
638 else if (arg_len > 17
639 && strncasecmp (argv[i], "--identification=", 17) == 0)
641 /* Comes from pragma Ident (). */
642 fprintf (optfile, "case_sensitive=yes\n");
643 fprintf (optfile, "IDENTIFICATION=\"%-.15s\"\n", &argv[i][17]);
644 fprintf (optfile, "case_sensitive=NO\n");
648 for (i = 1; i < argc; i++)
650 int arg_len = strlen (argv[i]);
652 if (strcmp (argv[i], "-o") == 0)
654 /* Already handled. */
655 i++;
657 else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
659 const char *libname;
661 libname = expand_lib (&argv[i][2]);
662 if (libname != NULL)
664 int len = strlen (libname);
665 const char *ext;
667 if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
668 ext = "/shareable";
669 else
670 ext = "/library";
672 if (libname[0] == '[')
673 fprintf (optfile, "%s%s%s\n", cwdev, libname, ext);
674 else
675 fprintf (optfile, "%s%s\n", libname, ext);
678 else if (strcmp (argv[i], "-v" ) == 0
679 || strncmp (argv[i], "-g", 2 ) == 0
680 || strcmp (argv[i], "-static" ) == 0
681 || strcmp (argv[i], "-map" ) == 0
682 || strcmp (argv[i], "-save-temps") == 0
683 || strcmp (argv[i], "--noinhibit-exec") == 0
684 || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
685 || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
687 /* Already handled. */
689 else if (strncmp (argv[i], "--opt=", 6) == 0)
690 fprintf (optfile, "%s\n", argv[i] + 6);
691 else if (arg_len > 1 && argv[i][0] == '@')
693 /* Read response file (in fact a single line of filenames). */
694 FILE *atfile;
695 char *ptr, *ptr1;
696 struct stat statbuf;
697 char *buff;
698 int len;
700 if (stat (&argv[i][1], &statbuf))
702 fprintf (stderr, "Couldn't open linker response file: %s\n",
703 &argv[i][1]);
704 exit (EXIT_FAILURE);
707 /* Read the line. */
708 buff = (char *) xmalloc (statbuf.st_size + 1);
709 atfile = fopen (&argv[i][1], "r");
710 fgets (buff, statbuf.st_size + 1, atfile);
711 fclose (atfile);
713 /* Remove trailing \n. */
714 len = strlen (buff);
715 if (buff [len - 1] == '\n')
717 buff [len - 1] = 0;
718 len--;
721 /* Put the filenames to the opt file. */
722 ptr = buff;
725 ptr1 = strchr (ptr, ' ');
726 if (ptr1)
727 *ptr1 = 0;
729 /* Add device name if a path is present. */
730 ptr = to_host_file_spec (ptr);
731 if (ptr[0] == '[')
732 fprintf (optfile, "%s%s\n", cwdev, ptr);
733 else
734 fprintf (optfile, "%s\n", ptr);
736 ptr = ptr1 + 1;
738 while (ptr1);
740 else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
742 /* Unix style file specs and VMS style switches look alike,
743 so assume an arg consisting of one and only one slash,
744 and that being first, is really a switch. */
745 addarg (argv[i]);
747 else if (arg_len > 4
748 && strncasecmp (&argv[i][arg_len-4], ".opt", 4) == 0)
750 /* Read option file. */
751 FILE *optfile1;
752 char buff[256];
754 /* Disable __UNIX_FOPEN redefinition in case user supplied .opt
755 file is not stream oriented. */
757 optfile1 = (fopen) (argv[i], "r");
758 if (optfile1 == 0)
760 perror (argv[i]);
761 status = 1;
762 goto cleanup_and_exit;
765 while (fgets (buff, sizeof (buff), optfile1))
766 fputs (buff, optfile);
768 fclose (optfile1);
770 else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
771 fprintf (optfile, "%s\n", argv[i]);
772 else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
774 /* Comes from command line and will override pragma. */
775 fprintf (optfile, "case_sensitive=yes\n");
776 fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
777 fprintf (optfile, "case_sensitive=NO\n");
779 else if (arg_len > 17
780 && strncasecmp (argv[i], "--identification=", 17) == 0)
782 /* Already handled. */
784 else
786 /* Assume filename arg. */
787 const char *file;
788 const char *addswitch = NULL;
789 char *buff;
790 int buff_len;
791 int is_cld = 0;
793 file = to_host_file_spec (argv[i]);
794 arg_len = strlen (file);
796 /* Handle shareable image libraries. */
797 if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".exe") == 0)
798 addswitch = "/shareable";
799 else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".cld") == 0)
801 addswitch = "/shareable";
802 is_cld = 1;
805 /* Handle object libraries. */
806 else if (arg_len > 2 && strcasecmp (&file[arg_len - 2], ".a") == 0)
807 addswitch = "/lib";
808 else if (arg_len > 4 && strcasecmp (&file[arg_len - 4], ".olb") == 0)
809 addswitch = "/lib";
811 /* Absolutize file location. */
812 if (file[0] == '[')
814 buff = (char *) xmalloc (cwdevlen + arg_len + 1);
815 sprintf (buff, "%s%s", cwdev, file);
817 else if (strchr (file, ':'))
819 buff = xstrdup (file);
821 else
823 buff = (char *) xmalloc (strlen (cwd) + arg_len + 1);
824 sprintf (buff, "%s%s", cwd, file);
827 buff_len = strlen (buff);
829 if (buff_len >= 15
830 && strcasecmp (&buff[buff_len - 14], "vms-dwarf2eh.o") == 0)
832 /* Remind of it. */
833 vmsdwarf2ehspec = xstrdup (buff);
835 else if (buff_len >= 13
836 && strcasecmp (&buff[buff_len - 12], "vms-dwarf2.o") == 0)
838 /* Remind of it. */
839 vmsdwarf2spec = xstrdup (buff);
841 else if (is_cld)
843 /* Command line definition file. */
844 addarg (buff);
845 addarg (addswitch);
846 addarg (",");
848 else
850 fprintf (optfile, "%s%s\n",
851 buff, addswitch != NULL ? addswitch : "");
853 free (buff);
857 if (vmsdwarf2ehspec)
859 /* Sequentialize exception handling info. */
861 fprintf (optfile, "case_sensitive=yes\n");
862 fprintf (optfile, "cluster=DWARF2eh,,,%s\n", vmsdwarf2ehspec);
863 fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
864 fprintf (optfile, "case_sensitive=NO\n");
867 if (debug && vmsdwarf2spec)
869 /* Sequentialize the debug info. */
871 fprintf (optfile, "case_sensitive=yes\n");
872 fprintf (optfile, "cluster=DWARF2debug,,,%s\n", vmsdwarf2spec);
873 fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
874 fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
875 fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
876 fprintf (optfile, " debug_zzzzzz\n");
877 fprintf (optfile, "case_sensitive=NO\n");
880 if (debug && share && vmsdwarf2spec)
882 /* Sequentialize the shared library debug info. */
884 fprintf (optfile, "case_sensitive=yes\n");
885 fprintf (optfile, "symbol_vector=(-\n");
886 fprintf (optfile,
887 "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
888 sharebasename);
889 fprintf (optfile,
890 "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
891 sharebasename);
892 fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
893 sharebasename);
894 fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
895 sharebasename);
896 fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
897 sharebasename);
898 fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
899 sharebasename);
900 fprintf (optfile,
901 "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
902 sharebasename);
903 fprintf (optfile,
904 "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
905 sharebasename);
906 fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
907 sharebasename);
908 fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
909 sharebasename);
910 fprintf (optfile, "case_sensitive=NO\n");
913 fprintf (optfile, "PSECT_ATTR=LIB$INITIALIZE,GBL\n");
914 fclose (optfile);
916 /* Append opt file. */
917 addarg (" ");
918 addarg (optfilename);
919 addarg ("/opt");
921 if (verbose)
922 printf ("%s\n", link_cmd);
924 status = system (link_cmd);
925 if (verbose > 1)
926 printf ("$!status = %d\n", status);
928 if ((status & 1) != 1)
930 status = 1;
931 goto cleanup_and_exit;
934 if (debug && !share && ld_nocall_debug)
936 status = set_exe ("/flags=nocall_debug");
937 if (status != 0)
938 goto cleanup_and_exit;
941 if (!share && ld_mkthreads)
943 status = set_exe ("/flags=mkthreads");
944 if (status != 0)
945 goto cleanup_and_exit;
948 if (!share && ld_upcalls)
950 status = set_exe ("/flags=upcalls");
951 if (status != 0)
952 goto cleanup_and_exit;
955 status = 0;
957 cleanup_and_exit:
958 if (!save_temps)
959 remove (optfilename);
961 if (status == 0)
962 exit (EXIT_SUCCESS);
964 if (exefullfilename && inhibit_exec == 1)
965 remove (exefullfilename);
967 exit (EXIT_FAILURE);