1/* VMS linker wrapper.
2   Copyright (C) 2011-2015 Free Software Foundation, Inc.
3   Contributed by AdaCore
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3.  If not see
19<http://www.gnu.org/licenses/>.  */
20
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.
24
25   It is possible to build this program on UNIX but only for the purpose of
26   checking for errors.  */
27
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31#include <stdio.h>
32
33#include "libiberty.h"
34#include <safe-ctype.h>
35#include <sys/stat.h>
36
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
42
43/* Local variable declarations.  */
44static int ld_nocall_debug = 0;
45static int ld_mkthreads = 0;
46static int ld_upcalls = 0;
47
48/* verbose = 1 if -v passed.  */
49static int verbose = 0;
50
51/* save_temps = 1 if -save-temps passed.  */
52static int save_temps = 0;
53
54/* By default don't generate executable file if there are errors
55   in the link.  Override with --noinhibit-exec.  */
56static int inhibit_exec = 1;
57
58/* debug = 1 if -g passed.  */
59static int debug = 0;
60
61/* By default prefer to link with static libraries.  */
62static int staticp = 1;
63
64/* By default generate an executable, not a shareable image library.
65   Override with -shared.  */
66static int share = 0;
67
68/* Linker command line.  */
69static int link_cmd_maxlen = 0;
70static char *link_cmd = 0;
71static int link_cmd_len = 0;
72
73/* Keep track of filenames.  */
74static char *sharebasename;
75static const char *exefullfilename;
76static const char *exefilename;
77
78/* Search dir list passed on command line (with -L).  */
79static const char **search_dirs;
80static int search_dirs_len;
81
82/* Local function declarations.  */
83static void addarg (const char *);
84static int is_regular_file (char *);
85static char *to_host_file_spec (char *);
86static char *locate_lib (char *);
87static const char *expand_lib (char *);
88static void preprocess_args (int, char **);
89static void process_args (int, char **);
90static void maybe_set_link_compat (void);
91static int set_exe (const char *);
92#ifdef VMS
93static int translate_unix (char *, int);
94#endif
95
96
97/* Append STR to the command line to invoke the linker.
98   Expand the line as necessary to accommodate.  */
99
100static void
101addarg (const char *str)
102{
103  int l = strlen (str);
104
105  /* Extend the line.  */
106  if (link_cmd_len + l >= link_cmd_maxlen)
107    {
108      link_cmd_maxlen = link_cmd_len + l + 1024;
109      link_cmd = XRESIZEVEC (char, link_cmd, link_cmd_maxlen);
110    }
111
112  memcpy (link_cmd + link_cmd_len, str, l);
113  link_cmd_len += l;
114}
115
116/* Check to see if NAME is a regular file, i.e. not a directory.  */
117
118static int
119is_regular_file (char *name)
120{
121  int ret;
122  struct stat statbuf;
123
124  ret = stat (name, &statbuf);
125  return !ret && S_ISREG (statbuf.st_mode);
126}
127
128#ifdef VMS
129static char new_host_filespec [255];
130static char filename_buff [256];
131
132/* Action routine called by decc$to_vms.  NAME is a file name or
133   directory name.  TYPE is unused.  */
134
135static int
136translate_unix (char *name, int type ATTRIBUTE_UNUSED)
137{
138  strcpy (filename_buff, name);
139  return 0;
140}
141#endif
142
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.  */
146
147static char *
148to_host_file_spec (char *filespec)
149{
150#ifdef VMS
151  if (strchr (filespec, ']') || strchr (filespec, ':'))
152    {
153      /* Looks like a VMS path.  */
154      return filespec;
155    }
156  else
157    {
158
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;
163    }
164#else
165  return filespec;
166#endif
167}
168
169/* Locate library LIB_NAME on the library path.  */
170
171static char *
172locate_lib (char *lib_name)
173{
174  int lib_len = strlen (lib_name);
175  const char *exts[3];
176  int i;
177
178  if (staticp)
179    {
180      /* For static links, look for shareable image libraries last.  */
181      exts[0] = ".a";
182      exts[1] = ".olb";
183      exts[2] = ".exe";
184    }
185  else
186    {
187      exts[0] = ".exe";
188      exts[1] = ".a";
189      exts[2] = ".olb";
190    }
191
192  for (i = 0; i < search_dirs_len; i++)
193    {
194      char *buf;
195      int l;
196      int j;
197
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;
206
207      /* Look for files with the extensions.  */
208      for (j = 0; j < 3; j++)
209        {
210	  strcpy (buf + l, exts[j]);
211	  if (is_regular_file (buf))
212	    return xstrdup (to_host_file_spec (buf));
213        }
214    }
215
216  return NULL;
217}
218
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.  */
222
223static const char *
224expand_lib (char *name)
225{
226  char *lib_path;
227
228  /* Discard libc.  */
229  if (strcmp (name, "c") == 0)
230    return NULL;
231
232  /* Discard libm.  No separate library for math functions.  */
233  if (strcmp (name, "m") == 0)
234    return NULL;
235
236  /* Search on path.  */
237  lib_path = locate_lib (name);
238  if (lib_path)
239    return lib_path;
240
241  fprintf (stderr,
242	   "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
243	   name, name, name);
244
245  exit (EXIT_FAILURE);
246}
247
248/* Preprocess the number of args P_ARGC in ARGV.
249   Look for special flags, etc. that must be handled first.  */
250
251static void
252preprocess_args (int argc, char **argv)
253{
254  int i;
255
256  /* Scan for -shared.  */
257  for (i = 1; i < argc; i++)
258    if (strcmp (argv[i], "-shared") == 0)
259      {
260        share = 1;
261        break;
262      }
263
264  for (i = 1; i < argc; i++)
265    if (strcmp (argv[i], "-o") == 0)
266      {
267	int len;
268
269	i++;
270        exefilename = lbasename (argv[i]);
271	exefullfilename = xstrdup (to_host_file_spec (argv[i]));
272
273	if (share)
274          addarg(" /share=");
275	else
276	  addarg (" /exe=");
277        addarg (exefullfilename);
278
279	if (share)
280	  {
281            char *ptr;
282
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);
293
294	    len = strlen (sharebasename);
295	    if (strncasecmp (&sharebasename[len-4], ".exe", 4) == 0)
296	      sharebasename[len - 4] = 0;
297
298            /* Convert to uppercase.  */
299	    for (ptr = sharebasename; *ptr; ptr++)
300	      *ptr = TOUPPER (*ptr);
301	  }
302      }
303
304  if (exefullfilename == NULL && !share)
305    {
306      exefilename = "a_out.exe";
307      exefullfilename = "a_out.exe";
308      addarg (xstrdup (" /exe=a_out.exe"));
309    }
310}
311
312/* Preprocess the number of args ARGC in ARGV.  Look for
313   special flags, etc. that must be handled for the VMS linker.  */
314
315static void
316process_args (int argc, char **argv)
317{
318  int i;
319
320  for (i = 1; i < argc; i++)
321    {
322      if (strncmp (argv[i], "-L", 2) == 0)
323	{
324          search_dirs = XRESIZEVEC(const char *, search_dirs,
325                                   search_dirs_len + 1);
326          search_dirs[search_dirs_len++] = &argv[i][2];
327	}
328
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)
333	{
334	  fprintf (stdout, "VMS Linker\n");
335          exit (EXIT_SUCCESS);
336	}
337      else if (strcmp (argv[i], "--help") == 0)
338	{
339	  fprintf (stdout, "VMS Linker\n");
340          exit (EXIT_SUCCESS);
341	}
342      else if (strcmp (argv[i], "-g0") == 0)
343	addarg ("/notraceback");
344      else if (strncmp (argv[i], "-g", 2) == 0)
345	{
346	  addarg ("/debug");
347	  debug = 1;
348	}
349      else if (strcmp (argv[i], "-static") == 0)
350	staticp = 1;
351      else if (strcmp (argv[i], "-map") == 0)
352	{
353	  char *buff, *ptr;
354
355	  buff = (char *) xstrdup (exefullfilename);
356	  ptr = strrchr (buff, '.');
357	  if (ptr)
358	    *ptr = 0;
359
360	  strcat (buff, ".map");
361	  addarg ("/map=");
362	  addarg (buff);
363          addarg (".map");
364	  addarg ("/full");
365
366          free (buff);
367	}
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;
372    }
373}
374
375#ifdef VMS
376typedef struct dsc
377{
378  unsigned short len, mbz;
379  const char *adr;
380} Descriptor;
381
382struct lst
383{
384  unsigned short buflen, item_code;
385  const void *bufaddr;
386  void *retlenaddr;
387};
388
389static struct
390{
391  struct lst items [1];
392  unsigned int terminator;
393} item_lst1;
394
395static struct
396{
397  struct lst items [2];
398  unsigned int terminator;
399} item_lst2;
400
401/* Checks if logical names are defined for setting system library path and
402   linker program to enable compatibility with earlier VMS versions.  */
403
404static void
405maybe_set_link_compat (void)
406{
407  char lnm_buff [LNM_C_NAMLENGTH];
408  unsigned int lnm_buff_len;
409  int status;
410  Descriptor tabledsc, linkdsc;
411
412  tabledsc.adr = "LNM$JOB";
413  tabledsc.len = strlen (tabledsc.adr);
414  tabledsc.mbz = 0;
415
416  linkdsc.adr = "GCC_LD_SYS$LIBRARY";
417  linkdsc.len = strlen (linkdsc.adr);
418  linkdsc.mbz = 0;
419
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;
425
426  status = SYS$TRNLNM
427    (0,          /* attr */
428     &tabledsc,  /* tabnam */
429     &linkdsc,   /* lognam */
430     0,          /* acmode */
431     &item_lst1);
432
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 */
436
437  if ((status & 1) == 1)
438    {
439      unsigned char acmode = PSL_C_USER; /* Don't retain after image exit */
440      const char *syslib = "SYS$SYSROOT:[SYSLIB]"; /* Default SYS$LIBRARY */
441
442      /* Only visible to current and child processes */
443      tabledsc.adr = "LNM$PROCESS";
444      tabledsc.len = strlen (tabledsc.adr);
445      tabledsc.mbz = 0;
446
447      linkdsc.adr = "SYS$LIBRARY";
448      linkdsc.len = strlen (linkdsc.adr);
449      linkdsc.mbz = 0;
450
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;
455
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;
461
462      status = SYS$CRELNM
463	(0,          /* attr */
464	 &tabledsc,  /* tabnam */
465	 &linkdsc,   /* lognam */
466	 &acmode,    /* acmode */
467	 &item_lst2);
468
469    }
470
471  tabledsc.adr = "LNM$JOB";
472  tabledsc.len = strlen (tabledsc.adr);
473  tabledsc.mbz = 0;
474
475  linkdsc.adr = "GCC_LD_LINK";
476  linkdsc.len = strlen (linkdsc.adr);
477  linkdsc.mbz = 0;
478
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;
484
485  status = SYS$TRNLNM
486    (0,          /* attr */
487     &tabledsc,  /* tabnam */
488     &linkdsc,   /* lognam */
489     0,          /* acmode */
490     &item_lst1);
491
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).  */
495
496  if ((status & 1) == 1)
497    {
498      unsigned char acmode = PSL_C_USER; /* Don't retain after image exit.  */
499
500      /* Only visible to current and child processes.  */
501      tabledsc.adr = "LNM$PROCESS";
502      tabledsc.len = strlen (tabledsc.adr);
503      tabledsc.mbz = 0;
504
505      linkdsc.adr = "LINK";
506      linkdsc.len = strlen (linkdsc.adr);
507      linkdsc.mbz = 0;
508
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;
514
515      status = SYS$CRELNM
516	(0,          /* attr */
517	 &tabledsc,  /* tabnam */
518	 &linkdsc,   /* lognam */
519	 &acmode,    /* acmode */
520	 &item_lst1);
521    }
522}
523#else
524static void
525maybe_set_link_compat (void)
526{
527}
528#endif
529
530/* Set environment defined executable attributes.  */
531
532static int
533set_exe (const char *arg)
534{
535  char allargs [1024];
536  int res;
537
538  snprintf (allargs, sizeof (allargs),
539            "$@gnu:[bin]set_exe %s %s", exefullfilename, arg);
540  if (verbose)
541    printf ("%s\n", allargs);
542
543  res = system (allargs);
544  if (verbose > 1)
545    printf ("$!status = %d\n", res);
546
547  if ((res & 1) != 1)
548    {
549      fprintf (stderr, "ld error: popen set_exe\n");
550      return 1;
551    }
552  return 0;
553}
554
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.  */
557
558int
559main (int argc, char **argv)
560{
561  /* File specification for vms-dwarf2.o.  */
562  char *vmsdwarf2spec = 0;
563
564  /* File specification for vms-dwarf2eh.o.  */
565  char *vmsdwarf2ehspec = 0;
566
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;
574
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;
584
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
592
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';
601
602  maybe_set_link_compat ();
603
604  /* Linker command starts with the command name.  */
605  addarg ("$ link");
606
607  /* Pass to find args that have to be append first.  */
608  preprocess_args (argc , argv);
609
610  /* Pass to find the rest of the args.  */
611  process_args (argc , argv);
612
613  if (!verbose)
614    addarg ("/noinform");
615
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");
625
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++)
629    {
630      int arg_len = strlen (argv[i]);
631
632      if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
633	{
634	  /* Comes from command line. If present will always appear before
635	     --identification=... and will override.  */
636          break;
637	}
638      else if (arg_len > 17
639	       && strncasecmp (argv[i], "--identification=", 17) == 0)
640	{
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");
645	}
646    }
647
648  for (i = 1; i < argc; i++)
649    {
650      int arg_len = strlen (argv[i]);
651
652      if (strcmp (argv[i], "-o") == 0)
653        {
654          /* Already handled.  */
655          i++;
656        }
657      else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
658	{
659	  const char *libname;
660
661          libname = expand_lib (&argv[i][2]);
662	  if (libname != NULL)
663	    {
664              int len = strlen (libname);
665              const char *ext;
666
667	      if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
668		ext = "/shareable";
669	      else
670		ext = "/library";
671
672	      if (libname[0] == '[')
673                fprintf (optfile, "%s%s%s\n", cwdev, libname, ext);
674	      else
675                fprintf (optfile, "%s%s\n", libname, ext);
676	    }
677	}
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))
686        {
687          /* Already handled.  */
688        }
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] == '@')
692	{
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;
699
700	  if (stat (&argv[i][1], &statbuf))
701	    {
702	      fprintf (stderr, "Couldn't open linker response file: %s\n",
703		       &argv[i][1]);
704	      exit (EXIT_FAILURE);
705	    }
706
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);
712
713          /* Remove trailing \n.  */
714	  len = strlen (buff);
715	  if (buff [len - 1] == '\n')
716	    {
717	      buff [len - 1] = 0;
718	      len--;
719	    }
720
721          /* Put the filenames to the opt file.  */
722	  ptr = buff;
723	  do
724	  {
725	     ptr1 = strchr (ptr, ' ');
726	     if (ptr1)
727	       *ptr1 = 0;
728
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);
735
736	     ptr = ptr1 + 1;
737	  }
738          while (ptr1);
739	}
740      else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
741        {
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]);
746        }
747      else if (arg_len > 4
748	       && strncasecmp (&argv[i][arg_len-4], ".opt", 4) == 0)
749	{
750          /* Read option file.  */
751	  FILE *optfile1;
752	  char buff[256];
753
754	  /* Disable __UNIX_FOPEN redefinition in case user supplied .opt
755	     file is not stream oriented. */
756
757	  optfile1 = (fopen) (argv[i], "r");
758	  if (optfile1 == 0)
759	    {
760	      perror (argv[i]);
761	      status = 1;
762	      goto cleanup_and_exit;
763	    }
764
765	  while (fgets (buff, sizeof (buff), optfile1))
766	    fputs (buff, optfile);
767
768	  fclose (optfile1);
769	}
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)
773	{
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");
778	}
779      else if (arg_len > 17
780	       && strncasecmp (argv[i], "--identification=", 17) == 0)
781        {
782          /* Already handled.  */
783        }
784      else
785	{
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;
792
793	  file = to_host_file_spec (argv[i]);
794	  arg_len = strlen (file);
795
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)
800	    {
801	      addswitch = "/shareable";
802	      is_cld = 1;
803	    }
804
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";
810
811	  /* Absolutize file location.  */
812	  if (file[0] == '[')
813	    {
814	      buff = (char *) xmalloc (cwdevlen + arg_len + 1);
815	      sprintf (buff, "%s%s", cwdev, file);
816	    }
817	  else if (strchr (file, ':'))
818	    {
819	      buff = xstrdup (file);
820	    }
821	  else
822	    {
823	      buff = (char *) xmalloc (strlen (cwd) + arg_len + 1);
824	      sprintf (buff, "%s%s", cwd, file);
825	    }
826
827	  buff_len = strlen (buff);
828
829	  if (buff_len >= 15
830	      && strcasecmp (&buff[buff_len - 14], "vms-dwarf2eh.o") == 0)
831	    {
832              /* Remind of it.  */
833              vmsdwarf2ehspec = xstrdup (buff);
834	    }
835	  else if (buff_len >= 13
836                   && strcasecmp (&buff[buff_len - 12], "vms-dwarf2.o") == 0)
837            {
838              /* Remind of it.  */
839              vmsdwarf2spec = xstrdup (buff);
840            }
841	  else if (is_cld)
842	    {
843              /* Command line definition file.  */
844              addarg (buff);
845              addarg (addswitch);
846	      addarg (",");
847	    }
848	  else
849	    {
850              fprintf (optfile, "%s%s\n",
851                       buff, addswitch != NULL ? addswitch : "");
852	    }
853          free (buff);
854	}
855    }
856
857  if (vmsdwarf2ehspec)
858    {
859      /* Sequentialize exception handling info.  */
860
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");
865    }
866
867  if (debug && vmsdwarf2spec)
868    {
869      /* Sequentialize the debug info.  */
870
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");
878    }
879
880  if (debug && share && vmsdwarf2spec)
881    {
882      /* Sequentialize the shared library debug info.  */
883
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");
911    }
912
913  fprintf (optfile, "PSECT_ATTR=LIB$INITIALIZE,GBL\n");
914  fclose (optfile);
915
916  /* Append opt file.  */
917  addarg (" ");
918  addarg (optfilename);
919  addarg ("/opt");
920
921  if (verbose)
922    printf ("%s\n", link_cmd);
923
924  status = system (link_cmd);
925  if (verbose > 1)
926    printf ("$!status = %d\n", status);
927
928  if ((status & 1) != 1)
929    {
930      status = 1;
931      goto cleanup_and_exit;
932    }
933
934  if (debug && !share && ld_nocall_debug)
935    {
936      status = set_exe ("/flags=nocall_debug");
937      if (status != 0)
938        goto cleanup_and_exit;
939    }
940
941  if (!share && ld_mkthreads)
942    {
943      status = set_exe ("/flags=mkthreads");
944      if (status != 0)
945        goto cleanup_and_exit;
946    }
947
948  if (!share && ld_upcalls)
949    {
950      status = set_exe ("/flags=upcalls");
951      if (status != 0)
952        goto cleanup_and_exit;
953    }
954
955  status = 0;
956
957 cleanup_and_exit:
958  if (!save_temps)
959    remove (optfilename);
960
961  if (status == 0)
962    exit (EXIT_SUCCESS);
963
964  if (exefullfilename && inhibit_exec == 1)
965    remove (exefullfilename);
966
967  exit (EXIT_FAILURE);
968}
969