* config/ia64/ia64.md (*ptr_extend_plus_1, *ptr_extend_plus_2): New.
[official-gcc.git] / gcc / config / alpha / vms-ld.c
blob83ceaf9b031c5cf1057c59155896f3e5800f43fa
1 /* VMS linker wrapper.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
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.
13 GNU CC is distributed in the hope that it will be useful,
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.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
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. */
27 #include "config.h"
28 #include "system.h"
30 typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
32 #undef PATH_SEPARATOR
33 #undef PATH_SEPARATOR_STR
34 #define PATH_SEPARATOR ','
35 #define PATH_SEPARATOR_STR ","
37 /* Local variable declarations. */
39 /* File specification for vms-dwarf2.o. */
40 static char *vmsdwarf2spec = 0;
42 /* File specification for vms-dwarf2eh.o. */
43 static char *vmsdwarf2ehspec = 0;
45 /* verbose = 1 if -v passed. */
46 static int verbose = 0;
48 /* save_temps = 1 if -save-temps passed. */
49 static int save_temps = 0;
51 /* By default don't generate executable file if there are errors
52 in the link. Override with --noinhibit-exec. */
53 static int inhibit_exec = 1;
55 /* debug = 1 if -g passed. */
56 static int debug = 0;
58 /* By default prefer to link with shareable image libraries.
59 Override with -static. */
60 static int staticp = 0;
62 /* By default generate an executable, not a shareable image library.
63 Override with -shared. */
64 static int share = 0;
66 /* Remember if IDENTIFICATION given on command line. */
67 static int ident = 0;
69 /* Keep track of arg translations. */
70 static int link_arg_max = -1;
71 static const char **link_args = 0;
72 static int link_arg_index = -1;
74 /* Keep track of filenames */
75 static char optfilefullname [267];
76 static char *sharefilename = 0;
77 static char *exefilename = 0;
79 /* System search dir list. Leave blank since link handles this
80 internally. */
81 static char *system_search_dirs = "";
83 /* Search dir list passed on command line (with -L). */
84 static char *search_dirs;
86 /* Local function declarations. */
88 /* Add STR to the list of arguments to pass to the linker. Expand the list as
89 necessary to accommodate. */
90 static void addarg PARAMS ((const char *));
92 /* Check to see if NAME is a regular file, i.e. not a directory */
93 static int is_regular_file PARAMS ((char *));
95 /* Translate a Unix syntax file specification FILESPEC into VMS syntax.
96 If indicators of VMS syntax found, return input string. */
97 static char *to_host_file_spec PARAMS ((char *));
99 /* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
100 static char *locate_lib PARAMS ((char *, char *));
102 /* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
103 libfoo.a in the set of directories we are allowed to search in. */
104 static const char *expand_lib PARAMS ((char *));
106 /* Preprocess the number of args P_ARGC in ARGV.
107 Look for special flags, etc. that must be handled first. */
108 static void preprocess_args PARAMS ((int *, char **));
110 /* Preprocess the number of args P_ARGC in ARGV. Look for
111 special flags, etc. that must be handled for the VMS linker. */
112 static void process_args PARAMS ((int *, char **));
114 /* Action routine called by decc$to_vms. NAME is a file name or
115 directory name. TYPE is unused. */
116 static int translate_unix PARAMS ((char *, int));
118 int main PARAMS ((int, char **));
120 static void
121 addarg (str)
122 const char *str;
124 int i;
126 if (++link_arg_index >= link_arg_max)
128 const char **new_link_args
129 = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *));
131 for (i = 0; i <= link_arg_max; i++)
132 new_link_args [i] = link_args [i];
134 if (link_args)
135 free (link_args);
137 link_arg_max += 1000;
138 link_args = new_link_args;
141 link_args [link_arg_index] = str;
144 static char *
145 locate_lib (lib_name, path_val)
146 char *lib_name;
147 char *path_val;
149 int lib_len = strlen (lib_name);
150 char *eptr, *sptr;
152 for (sptr = path_val; *sptr; sptr = eptr)
154 char *buf, *ptr;
156 while (*sptr == PATH_SEPARATOR)
157 sptr ++;
159 eptr = strchr (sptr, PATH_SEPARATOR);
160 if (eptr == 0)
161 eptr = strchr (sptr, 0);
163 buf = alloca ((eptr-sptr) + lib_len + 4 + 2);
164 strncpy (buf, sptr, eptr-sptr);
165 buf [eptr-sptr] = 0;
166 strcat (buf, "/");
167 strcat (buf, lib_name);
168 ptr = strchr (buf, 0);
170 if (debug || staticp)
172 /* For debug or static links, look for shareable image libraries
173 last. */
174 strcpy (ptr, ".a");
175 if (is_regular_file (buf))
176 return xstrdup (to_host_file_spec (buf));
178 strcpy (ptr, ".olb");
179 if (is_regular_file (buf))
180 return xstrdup (to_host_file_spec (buf));
182 strcpy (ptr, ".exe");
183 if (is_regular_file (buf))
184 return xstrdup (to_host_file_spec (buf));
186 else
188 /* Otherwise look for shareable image libraries first. */
189 strcpy (ptr, ".exe");
190 if (is_regular_file (buf))
191 return xstrdup (to_host_file_spec (buf));
193 strcpy (ptr, ".a");
194 if (is_regular_file (buf))
195 return xstrdup (to_host_file_spec (buf));
197 strcpy (ptr, ".olb");
198 if (is_regular_file (buf))
199 return xstrdup (to_host_file_spec (buf));
203 return 0;
206 static const char *
207 expand_lib (name)
208 char *name;
210 char *lib, *lib_path;
212 if (strcmp (name, "c") == 0)
213 /* IEEE VAX C compatible library for non-prefixed (e.g. no DECC$)
214 C RTL functions. */
215 return "sys$library:vaxcrtltx.olb";
217 else if (strcmp (name, "m") == 0)
218 /* No separate library for math functions */
219 return "";
221 else
223 lib = xmalloc (strlen (name) + 14);
225 strcpy (lib, "lib");
226 strcat (lib, name);
227 lib_path = locate_lib (lib, search_dirs);
229 if (lib_path)
230 return lib_path;
233 fprintf (stderr,
234 "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n",
235 name, name, name);
237 exit (1);
240 static int
241 is_regular_file (name)
242 char *name;
244 int ret;
245 struct stat statbuf;
247 ret = stat (name, &statbuf);
248 return !ret && S_ISREG (statbuf.st_mode);
251 static void
252 preprocess_args (p_argc, argv)
253 int *p_argc;
254 char **argv;
256 int i;
258 for (i = 1; i < *p_argc; i++)
259 if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0)
260 share = 1;
262 for (i = 1; i < *p_argc; i++)
263 if (strcmp (argv[i], "-o") == 0)
265 char *buff, *ptr;
266 int out_len;
267 int len;
269 i++;
270 ptr = to_host_file_spec (argv[i]);
271 exefilename = xstrdup (ptr);
272 out_len = strlen (ptr);
273 buff = xmalloc (out_len + 18);
275 if (share)
276 strcpy (buff, "/share=");
277 else
278 strcpy (buff, "/exe=");
280 strcat (buff, ptr);
281 addarg (buff);
283 if (share)
285 sharefilename = xmalloc (out_len+5);
286 if (ptr == strchr (argv[i], ']'))
287 strcpy (sharefilename, ++ptr);
288 else if (ptr == strchr (argv[i], ':'))
289 strcpy (sharefilename, ++ptr);
290 else if (ptr == strrchr (argv[i], '/'))
291 strcpy (sharefilename, ++ptr);
292 else
293 strcpy (sharefilename, argv[i]);
295 len = strlen (sharefilename);
296 if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0)
297 sharefilename[len-4] = 0;
299 for (ptr = sharefilename; *ptr; ptr++)
300 *ptr = TOUPPER (*ptr);
305 static void
306 process_args (p_argc, argv)
307 int *p_argc;
308 char **argv;
310 int i;
312 for (i = 1; i < *p_argc; i++)
314 if (strlen (argv[i]) < 2)
315 continue;
317 if (strncmp (argv[i], "-L", 2) == 0)
319 char *nbuff, *ptr;
320 int new_len, search_dirs_len;
322 ptr = &argv[i][2];
323 new_len = strlen (ptr);
324 search_dirs_len = strlen (search_dirs);
326 nbuff = xmalloc (new_len + 1);
327 strcpy (nbuff, ptr);
329 /* Remove trailing slashes. */
330 while (new_len > 1 && nbuff [new_len - 1] == '/')
332 nbuff [new_len - 1] = 0;
333 new_len--;
336 search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
337 if (search_dirs_len > 0)
338 strcat (search_dirs, PATH_SEPARATOR_STR);
340 strcat (search_dirs, nbuff);
341 free (nbuff);
344 /* -v turns on verbose option here and is passed on to gcc. */
345 else if (strcmp (argv[i], "-v") == 0)
346 verbose = 1;
347 else if (strcmp (argv[i], "-g0") == 0)
348 addarg ("/notraceback");
349 else if (strncmp (argv[i], "-g", 2) == 0)
351 addarg ("/debug");
352 debug = 1;
354 else if (strcmp (argv[i], "-static") == 0)
355 staticp = 1;
356 else if (strcmp (argv[i], "-map") == 0)
358 char *buff, *ptr;
360 buff = xmalloc (strlen (exefilename) + 5);
361 strcpy (buff, exefilename);
362 ptr = strchr (buff, '.');
363 if (ptr)
364 *ptr = 0;
366 strcat (buff, ".map");
367 addarg ("/map=");
368 addarg (buff);
369 addarg ("/full");
371 else if (strcmp (argv[i], "-save-temps") == 0)
372 save_temps = 1;
373 else if (strcmp (argv[i], "--noinhibit-exec") == 0)
374 inhibit_exec = 0;
378 /* The main program. Spawn the VMS linker after fixing up the Unix-like flags
379 and args to be what the VMS linker wants. */
382 main (argc, argv)
383 int argc;
384 char **argv;
386 int i;
387 char cwdev [128], *devptr;
388 int devlen;
389 int optfd;
390 FILE *optfile;
391 char *cwd = getcwd (0, 1024);
392 char *optfilename;
394 devptr = strchr (cwd, ':');
395 devlen = (devptr - cwd) + 1;
396 strncpy (cwdev, cwd, devlen);
397 cwdev [devlen] = '\0';
399 search_dirs = xmalloc (strlen (system_search_dirs) + 1);
400 strcpy (search_dirs, system_search_dirs);
402 addarg ("link");
404 /* Pass to find args that have to be append first. */
405 preprocess_args (&argc , argv);
407 /* Pass to find the rest of the args. */
408 process_args (&argc , argv);
410 /* Create a temp file to hold args, otherwise we can easily exceed the VMS
411 command line length limits. */
412 optfilename = alloca (strlen ("LDXXXXXX") + 1);
413 strcpy (optfilename, "LDXXXXXX");
414 optfd = mkstemp (optfilename);
415 getcwd (optfilefullname, 256, 1); /* VMS style cwd. */
416 strcat (optfilefullname, optfilename);
417 strcat (optfilefullname, ".");
418 optfile = fdopen (optfd, "w");
420 /* Write out the IDENTIFICATION argument first so that it can be overridden
421 by an options file. */
422 for (i = 1; i < argc; i++)
424 int arg_len = strlen (argv[i]);
426 if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
428 /* Comes from command line. If present will always appear before
429 IDENTIFICATION=... and will override. */
431 if (!ident)
432 ident = 1;
434 else if (arg_len > 15
435 && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
437 /* Comes from pragma Ident (). */
439 if (!ident)
441 fprintf (optfile, "case_sensitive=yes\n");
442 fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]);
443 fprintf (optfile, "case_sensitive=NO\n");
444 ident = 1;
449 for (i = 1; i < argc; i++)
451 int arg_len = strlen (argv[i]);
453 if (strcmp (argv[i], "-o") == 0)
454 i++;
455 else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0)
457 const char *libname = expand_lib (&argv[i][2]);
458 const char *ext;
459 int len;
461 if ((len = strlen (libname)) > 0)
463 char buff [256];
465 if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0)
466 ext = "/shareable";
467 else
468 ext = "/library";
470 if (libname[0] == '[')
471 sprintf (buff, "%s%s", cwdev, libname);
472 else
473 sprintf (buff, "%s", libname);
475 fprintf (optfile, "%s%s\n", buff, ext);
479 else if (strcmp (argv[i], "-v" ) == 0
480 || strncmp (argv[i], "-g", 2 ) == 0
481 || strcmp (argv[i], "-static" ) == 0
482 || strcmp (argv[i], "-map" ) == 0
483 || strcmp (argv[i], "-save-temps") == 0
484 || strcmp (argv[i], "--noinhibit-exec") == 0
485 || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0)
486 || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0))
488 else if (arg_len > 1 && argv[i][0] == '@')
490 FILE *atfile;
491 char *ptr, *ptr1;
492 struct stat statbuf;
493 char *buff;
494 int len;
496 if (stat (&argv[i][1], &statbuf))
498 fprintf (stderr, "Couldn't open linker response file: %s\n",
499 &argv[i][1]);
500 exit (1);
503 buff = xmalloc (statbuf.st_size + 1);
504 atfile = fopen (&argv[i][1], "r");
505 fgets (buff, statbuf.st_size + 1, atfile);
506 fclose (atfile);
508 len = strlen (buff);
509 if (buff [len - 1] == '\n')
511 buff [len - 1] = 0;
512 len--;
515 ptr = buff;
519 ptr1 = strchr (ptr, ' ');
520 if (ptr1)
521 *ptr1 = 0;
522 ptr = to_host_file_spec (ptr);
523 if (ptr[0] == '[')
524 fprintf (optfile, "%s%s\n", cwdev, ptr);
525 else
526 fprintf (optfile, "%s\n", ptr);
527 ptr = ptr1 + 1;
528 } while (ptr1);
531 /* Unix style file specs and VMS style switches look alike, so assume an
532 arg consisting of one and only one slash, and that being first, is
533 really a switch. */
534 else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
535 addarg (argv[i]);
536 else if (arg_len > 4
537 && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0)
539 FILE *optfile1;
540 char buff [256];
542 optfile1 = fopen (argv[i], "r");
543 while (fgets (buff, 256, optfile1))
544 fputs (buff, optfile);
546 fclose (optfile1);
548 else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0)
549 fprintf (optfile, "%s\n", argv[i]);
550 else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0)
552 /* Comes from command line and will override pragma. */
553 fprintf (optfile, "case_sensitive=yes\n");
554 fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]);
555 fprintf (optfile, "case_sensitive=NO\n");
556 ident = 1;
558 else if (arg_len > 15
559 && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0)
561 else
563 /* Assume filename arg. */
564 const char *addswitch = "";
565 char buff [256];
566 int buff_len;
567 int is_cld = 0;
569 argv[i] = to_host_file_spec (argv[i]);
570 arg_len = strlen (argv[i]);
572 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0)
573 addswitch = "/shareable";
575 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0)
577 addswitch = "/shareable";
578 is_cld = 1;
581 if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0)
582 addswitch = "/lib";
584 if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0)
585 addswitch = "/lib";
587 if (argv[i][0] == '[')
588 sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch);
589 else if (strchr (argv[i], ':'))
590 sprintf (buff, "%s%s\n", argv[i], addswitch);
591 else
592 sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch);
594 buff_len = strlen (buff);
596 if (buff_len >= 15
597 && strcasecmp (&buff[buff_len - 15], "vms-dwarf2eh.o\n") == 0)
598 vmsdwarf2ehspec = xstrdup (buff);
599 else if (buff_len >= 13
600 && strcasecmp (&buff[buff_len - 13],"vms-dwarf2.o\n") == 0)
601 vmsdwarf2spec = xstrdup (buff);
602 else if (is_cld)
604 addarg (buff);
605 addarg (",");
607 else
608 fprintf (optfile, buff);
612 #if 0
613 if (share)
614 fprintf (optfile, "symbol_vector=(main=procedure)\n");
615 #endif
617 if (vmsdwarf2ehspec)
619 fprintf (optfile, "case_sensitive=yes\n");
620 fprintf (optfile, "cluster=DWARF2eh,,,%s", vmsdwarf2ehspec);
621 fprintf (optfile, "collect=DWARF2eh,eh_frame\n");
622 fprintf (optfile, "case_sensitive=NO\n");
625 if (debug && vmsdwarf2spec)
627 fprintf (optfile, "case_sensitive=yes\n");
628 fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec);
629 fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n");
630 fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n");
631 fprintf (optfile, " debug_macinfo,debug_pubnames,debug_str,-\n");
632 fprintf (optfile, " debug_zzzzzz\n");
633 fprintf (optfile, "case_sensitive=NO\n");
636 if (debug && share)
638 fprintf (optfile, "case_sensitive=yes\n");
639 fprintf (optfile, "symbol_vector=(-\n");
640 fprintf (optfile,
641 "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n",
642 sharefilename);
643 fprintf (optfile,
644 "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n",
645 sharefilename);
646 fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n",
647 sharefilename);
648 fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n",
649 sharefilename);
650 fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n",
651 sharefilename);
652 fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n",
653 sharefilename);
654 fprintf (optfile,
655 "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n",
656 sharefilename);
657 fprintf (optfile,
658 "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n",
659 sharefilename);
660 fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n",
661 sharefilename);
662 fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n",
663 sharefilename);
664 fprintf (optfile, "case_sensitive=NO\n");
667 fclose (optfile);
668 addarg (optfilefullname);
669 addarg ("/opt");
671 addarg (NULL);
673 if (verbose)
675 int i;
677 for (i = 0; i < link_arg_index; i++)
678 printf ("%s ", link_args [i]);
679 putchar ('\n');
683 int i;
684 int len = 0;
686 for (i = 0; link_args[i]; i++)
687 len = len + strlen (link_args[i]) + 1;
690 char *allargs = (char *) alloca (len + 1);
691 Descr cmd;
692 int status;
693 int status1 = 1;
695 for (i = 0; i < len + 1; i++)
696 allargs [i] = 0;
698 for (i = 0; link_args [i]; i++)
700 strcat (allargs, link_args [i]);
701 strcat (allargs, " ");
704 cmd.adr = allargs;
705 cmd.len = len;
706 cmd.mbz = 0;
708 i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);
709 if ((i & 1) != 1)
711 LIB$SIGNAL (i);
712 exit (1);
715 if (debug && !share)
717 strcpy (allargs, "@gnu:[bin]set_exe ");
718 strcat (allargs, exefilename);
719 strcat (allargs, " /nodebug /silent");
720 len = strlen (allargs);
721 cmd.adr = allargs;
722 cmd.len = len;
723 cmd.mbz = 0;
725 if (verbose)
726 printf (allargs);
728 i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1);
730 if ((i & 1) != 1)
732 LIB$SIGNAL (i);
733 exit (1);
737 if (!save_temps)
738 remove (optfilefullname);
740 if ((status & 1) == 1 && (status1 & 1) == 1)
741 exit (0);
743 if (exefilename && inhibit_exec == 1)
744 remove (exefilename);
746 exit (1);
751 static char new_host_filespec [255];
752 static char filename_buff [256];
754 static int
755 translate_unix (name, type)
756 char *name;
757 int type ATTRIBUTE_UNUSED;
759 strcpy (filename_buff, name);
760 return 0;
763 static char *
764 to_host_file_spec (filespec)
765 char *filespec;
767 strcpy (new_host_filespec, "");
768 if (strchr (filespec, ']') || strchr (filespec, ':'))
769 strcpy (new_host_filespec, filespec);
770 else
772 decc$to_vms (filespec, translate_unix, 1, 1);
773 strcpy (new_host_filespec, filename_buff);
776 return new_host_filespec;