diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1043d2d84d1..a324088cdcc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Sun Nov 25 06:22:09 2001 Douglas B. Rupp + + * config/alpha/vms-ld.c, config/alpha/vms-cc.c: New files. + * config/alpha/x-vms: New file, to compile the above. + * config.gcc (alpha*-dec-vms*): Add x-vms. + 2001-11-24 Hans-Peter Nilsson * genextract.c (main): Set ro_loc for peepholes. diff --git a/gcc/config.gcc b/gcc/config.gcc index b199dc47371..bf262a6c201 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -524,6 +524,7 @@ alpha*-dec-vms*) tm_file=alpha/vms.h xm_file=alpha/xm-vms.h tmake_file="alpha/t-alpha alpha/t-vms alpha/t-ieee" + xmake_file=alpha/x-vms ;; arc-*-elf*) tm_file="elfos.h svr4.h ${tm_file}" diff --git a/gcc/config/alpha/vms-cc.c b/gcc/config/alpha/vms-cc.c new file mode 100644 index 00000000000..a95a82eead7 --- /dev/null +++ b/gcc/config/alpha/vms-cc.c @@ -0,0 +1,379 @@ +/* VMS DEC C wrapper. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Douglas B. Rupp (rupp@gnat.com). + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* This program is a wrapper around the VMS DEC C compiler. + It translates Unix style command line options into corresponding + VMS style qualifiers and then spawns the DEC C compiler. */ + +#include "config.h" +#include "system.h" + +#undef PATH_SEPARATOR +#undef PATH_SEPARATOR_STR +#define PATH_SEPARATOR ',' +#define PATH_SEPARATOR_STR "," + +/* These can be set by command line arguments */ +int verbose = 0; +int save_temps = 0; + +int comp_arg_max = -1; +const char **comp_args = 0; +int comp_arg_index = -1; +char *objfilename = 0; + +char *system_search_dirs = (char *) ""; +char *search_dirs; + +char *default_defines = (char *) ""; +char *defines; + +/* Translate a Unix syntax directory specification into VMS syntax. + If indicators of VMS syntax found, return input string. */ +static char *to_host_dir_spec PARAMS ((char *)); + +/* Translate a Unix syntax file specification into VMS syntax. + If indicators of VMS syntax found, return input string. */ +static char *to_host_file_spec PARAMS ((char *)); + +/* Add a translated arg to the list to be passed to DEC CC */ +static void addarg PARAMS ((const char *)); + +/* Preprocess the number of args in P_ARGC and contained in ARGV. + Look for special flags, etc. that must be handled first. */ +static void preprocess_args PARAMS ((*, **)); + +/* Process the number of args in P_ARGC and contained in ARGV. Look + for special flags, etc. that must be handled for the VMS compiler. */ +static void process_args PARAMS ((int *, char **)); + +/* Action routine called by decc$to_vms */ +static int translate_unix PARAMS ((char *, int)); + +int main PARAMS ((int, char **)); + +/* Add the argument contained in STR to the list of arguments to pass to the + compiler. */ + +static void +addarg (str) + const char *str; +{ + int i; + + if (++comp_arg_index >= comp_arg_max) + { + const char **new_comp_args + = (const char **) xcalloc (comp_arg_max + 1000, sizeof (char *)); + + for (i = 0; i <= comp_arg_max; i++) + new_comp_args [i] = comp_args [i]; + + if (comp_args) + free (comp_args); + + comp_arg_max += 1000; + comp_args = new_comp_args; + } + + comp_args [comp_arg_index] = str; +} + +static void +preprocess_args (p_argc, argv) + int *p_argc; + char *argv[]; +{ + int i; + + for (i = 1; i < *p_argc; i++) + { + if (strcmp (argv[i], "-o") == 0) + { + char *buff, *ptr; + int out_len; + + i++; + ptr = to_host_file_spec (argv[i]); + objfilename = xstrdup (ptr); + out_len = strlen (ptr); + buff = xmalloc (out_len + 6); + + strcpy (buff, "/obj="); + strcat (buff, ptr); + addarg (buff); + } + } +} + +static void +process_args (p_argc, argv) + int *p_argc; + char *argv[]; +{ + int i; + + for (i = 1; i < *p_argc; i++) + { + if (strlen (argv[i]) < 2) + continue; + + if (strncmp (argv[i], "-I", 2) == 0) + { + char *ptr; + int new_len, search_dirs_len; + + ptr = to_host_dir_spec (&argv[i][2]); + new_len = strlen (ptr); + search_dirs_len = strlen (search_dirs); + + search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2); + if (search_dirs_len > 0) + strcat (search_dirs, PATH_SEPARATOR_STR); + strcat (search_dirs, ptr); + } + else if (strncmp (argv[i], "-D", 2) == 0) + { + char *ptr; + int new_len, defines_len; + + ptr = &argv[i][2]; + new_len = strlen (ptr); + defines_len = strlen (defines); + + defines = xrealloc (defines, defines_len + new_len + 4); + if (defines_len > 0) + strcat (defines, ","); + + strcat (defines, "\""); + strcat (defines, ptr); + strcat (defines, "\""); + } + else if (strcmp (argv[i], "-v") == 0) + verbose = 1; + else if (strcmp (argv[i], "-g0") == 0) + addarg ("/nodebug"); + else if (strcmp (argv[i], "-O0") == 0) + addarg ("/noopt"); + else if (strncmp (argv[i], "-g", 2) == 0) + addarg ("/debug"); + else if (strcmp (argv[i], "-E") == 0) + addarg ("/preprocess"); + else if (strcmp (argv[i], "-save-temps") == 0) + save_temps = 1; + } +} + +/* The main program. Spawn the VMS DEC C compiler after fixing up the + Unix-like flags and args to be what VMS DEC C wants. */ + +typedef struct dsc {unsigned short len, mbz; char *adr; } Descr; + +int +main (argc, argv) + int argc; + char **argv; +{ + int i; + char cwdev [128], *devptr; + int devlen; + char *cwd = getcwd (0, 1024); + + devptr = strchr (cwd, ':'); + devlen = (devptr - cwd) + 1; + strncpy (cwdev, cwd, devlen); + cwdev [devlen] = '\0'; + + search_dirs = xmalloc (strlen (system_search_dirs) + 1); + strcpy (search_dirs, system_search_dirs); + + defines = xmalloc (strlen (default_defines) + 1); + strcpy (defines, default_defines); + + addarg ("cc"); + preprocess_args (&argc , argv); + process_args (&argc , argv); + + if (strlen (search_dirs) > 0) + { + addarg ("/include=("); + addarg (search_dirs); + addarg (")"); + } + + if (strlen (defines) > 0) + { + addarg ("/define=("); + addarg (defines); + addarg (")"); + } + + for (i = 1; i < argc; i++) + { + int arg_len = strlen (argv[i]); + + if (strcmp (argv[i], "-o") == 0) + i++; + else if (strcmp (argv[i], "-v" ) == 0 + || strcmp (argv[i], "-E") == 0 + || strcmp (argv[i], "-c") == 0 + || strncmp (argv[i], "-g", 2 ) == 0 + || strncmp (argv[i], "-O", 2 ) == 0 + || strcmp (argv[i], "-save-temps") == 0 + || (arg_len > 2 && strncmp (argv[i], "-I", 2) == 0) + || (arg_len > 2 && strncmp (argv[i], "-D", 2) == 0)) + ; + + /* Unix style file specs and VMS style switches look alike, so assume + an arg consisting of one and only one slash, and that being first, is + really a switch. */ + else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0)) + addarg (argv[i]); + else + { + /* Assume filename arg */ + char buff [256], *ptr; + int buff_len; + + ptr = to_host_file_spec (argv[i]); + arg_len = strlen (ptr); + + if (ptr[0] == '[') + sprintf (buff, "%s%s", cwdev, ptr); + else if (strchr (ptr, ':')) + sprintf (buff, "%s", ptr); + else + sprintf (buff, "%s%s", cwd, ptr); + + buff_len = strlen (buff); + ptr = xmalloc (buff_len + 1); + + strcpy (ptr, buff); + addarg (ptr); + } + } + + addarg (NULL); + + if (verbose) + { + int i; + + for (i = 0; i < comp_arg_index; i++) + printf ("%s ", comp_args [i]); + + putchar ('\n'); + } + + { + int i; + int len = 0; + + for (i = 0; comp_args[i]; i++) + len = len + strlen (comp_args[i]) + 1; + + { + char *allargs = (char *) alloca (len + 1); + Descr cmd; + int status; + int status1 = 1; + + for (i = 0; i < len + 1; i++) + allargs [i] = 0; + + for (i = 0; comp_args [i]; i++) + { + strcat (allargs, comp_args [i]); + strcat (allargs, " "); + } + + cmd.adr = allargs; + cmd.len = len; + cmd.mbz = 0; + + i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status); + + if ((i & 1) != 1) + { + LIB$SIGNAL (i); + exit (1); + } + + if ((status & 1) == 1 && (status1 & 1) == 1) + exit (0); + + exit (1); + } + } +} + +static char new_host_filespec [255]; +static char new_host_dirspec [255]; +static char filename_buff [256]; + +static int +translate_unix (name, type) + char *name; + int type ATTRIBUTE_UNUSED; +{ + strcpy (filename_buff, name); + return 0; +} + +static char * +to_host_dir_spec (dirspec) + char *dirspec; +{ + int len = strlen (dirspec); + + strcpy (new_host_dirspec, dirspec); + + if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':')) + return new_host_dirspec; + + while (len > 1 && new_host_dirspec [len-1] == '/') + { + new_host_dirspec [len-1] = 0; + len--; + } + + decc$to_vms (new_host_dirspec, translate_unix, 1, 2); + strcpy (new_host_dirspec, filename_buff); + + return new_host_dirspec; + +} + +static char * +to_host_file_spec (filespec) + char *filespec; +{ + strcpy (new_host_filespec, ""); + if (strchr (filespec, ']') || strchr (filespec, ':')) + strcpy (new_host_filespec, filespec); + else + { + decc$to_vms (filespec, translate_unix, 1, 1); + strcpy (new_host_filespec, filename_buff); + } + + return new_host_filespec; +} diff --git a/gcc/config/alpha/vms-ld.c b/gcc/config/alpha/vms-ld.c new file mode 100644 index 00000000000..f28b7c79687 --- /dev/null +++ b/gcc/config/alpha/vms-ld.c @@ -0,0 +1,762 @@ +/* VMS linker wrapper. + Copyright (C) 1996-2001 Free Software Foundation, Inc. + Contributed by Douglas B. Rupp (rupp@gnat.com). + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* This program is a wrapper around the VMS linker. + It translates Unix style command line options into corresponding + VMS style qualifiers and then spawns the VMS linker. */ + +#include "config.h" +#include "system.h" + +typedef struct dsc {unsigned short len, mbz; char *adr; } Descr; + +#undef PATH_SEPARATOR +#undef PATH_SEPARATOR_STR +#define PATH_SEPARATOR ',' +#define PATH_SEPARATOR_STR "," + +/* Local variable declarations. */ + +/* File specification for vms-dwarf2.o. */ +static char *vmsdwarf2spec = 0; + +/* verbose = 1 if -v passed. */ +static int verbose = 0; + +/* save_temps = 1 if -save-temps passed. */ +static int save_temps = 0; + +/* By default don't generate executable file if there are errors + in the link. Override with --noinhibit-exec. */ +static int inhibit_exec = 1; + +/* debug = 1 if -g passed. */ +static int debug = 0; + +/* By default prefer to link with shareable image libraries. + Override with -static. */ +static int staticp = 0; + +/* By default generate an executable, not a shareable image library. + Override with -shared. */ +static int share = 0; + +/* Remember if IDENTIFICATION given on command line. */ +static int ident = 0; + +/* Keep track of arg translations. */ +static int link_arg_max = -1; +static const char **link_args = 0; +static int link_arg_index = -1; + +/* Keep track of filenames */ +static char optfilefullname [267]; +static char *sharefilename = 0; +static char *exefilename = 0; + +/* System search dir list. Leave blank since link handles this + internally. */ +static char *system_search_dirs = ""; + +/* Search dir list passed on command line (with -L). */ +static char *search_dirs; + +/* Local function declarations. */ + +/* Add STR to the list of arguments to pass to the linker. Expand the list as + necessary to accomodate. */ +static void addarg PARAMS ((const char *)); + +/* Check to see if NAME is a regular file, i.e. not a directory */ +static int is_regular_file PARAMS ((char *)); + +/* Translate a Unix syntax file specification FILESPEC into VMS syntax. + If indicators of VMS syntax found, return input string. */ +static char *to_host_file_spec PARAMS ((char *)); + +/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */ +static char *locate_lib PARAMS ((char *, char *)); + +/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then + libfoo.a in the set of directories we are allowed to search in. */ +static const char *expand_lib PARAMS ((char *)); + +/* Preprocess the number of args P_ARGC in ARGV. + Look for special flags, etc. that must be handled first. */ +static void preprocess_args PARAMS ((int *, char **)); + +/* Preprocess the number of args P_ARGC in ARGV. Look for + special flags, etc. that must be handled for the VMS linker. */ +static void process_args PARAMS ((int *, char **)); + +/* Action routine called by decc$to_vms. NAME is a file name or + directory name. TYPE is unused. */ +static int translate_unix PARAMS ((char *, int)); + +int main PARAMS ((int, char **)); + +static void +addarg (str) + const char *str; +{ + int i; + + if (++link_arg_index >= link_arg_max) + { + const char **new_link_args + = (const char **) xcalloc (link_arg_max + 1000, sizeof (char *)); + + for (i = 0; i <= link_arg_max; i++) + new_link_args [i] = link_args [i]; + + if (link_args) + free (link_args); + + link_arg_max += 1000; + link_args = new_link_args; + } + + link_args [link_arg_index] = str; +} + +static char * +locate_lib (lib_name, path_val) + char *lib_name; + char *path_val; +{ + int lib_len = strlen (lib_name); + char *eptr, *sptr; + + for (sptr = path_val; *sptr; sptr = eptr) + { + char *buf, *ptr; + + while (*sptr == PATH_SEPARATOR) + sptr ++; + + eptr = strchr (sptr, PATH_SEPARATOR); + if (eptr == 0) + eptr = strchr (sptr, 0); + + buf = alloca ((eptr-sptr) + lib_len + 4 + 2); + strncpy (buf, sptr, eptr-sptr); + buf [eptr-sptr] = 0; + strcat (buf, "/"); + strcat (buf, lib_name); + ptr = strchr (buf, 0); + + if (debug || staticp) + { + /* For debug or static links, look for shareable image libraries + last. */ + strcpy (ptr, ".a"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + + strcpy (ptr, ".olb"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + + strcpy (ptr, ".exe"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + } + else + { + /* Otherwise look for shareable image libraries first. */ + strcpy (ptr, ".exe"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + + strcpy (ptr, ".a"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + + strcpy (ptr, ".olb"); + if (is_regular_file (buf)) + return xstrdup (to_host_file_spec (buf)); + } + } + + return 0; +} + +static const char * +expand_lib (name) + char *name; +{ + char *lib, *lib_path; + + if (strcmp (name, "c") == 0) + /* IEEE VAX C compatible library for non-prefixed (e.g. no DECC$) + C RTL functions. */ + return "sys$library:vaxcrtltx.olb"; + + else if (strcmp (name, "m") == 0) + /* No separate library for math functions */ + return ""; + + else + { + lib = xmalloc (strlen (name) + 14); + + strcpy (lib, "lib"); + strcat (lib, name); + lib_path = locate_lib (lib, search_dirs); + + if (lib_path) + return lib_path; + } + + fprintf (stderr, + "Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n", + name, name, name); + + exit (1); +} + +static int +is_regular_file (name) + char *name; +{ + int ret; + struct stat statbuf; + + ret = stat (name, &statbuf); + return !ret && S_ISREG (statbuf.st_mode); +} + +static void +preprocess_args (p_argc, argv) + int *p_argc; + char **argv; +{ + int i; + + for (i = 1; i < *p_argc; i++) + if (strlen (argv[i]) >= 6 && strncmp (argv[i], "-shared", 7) == 0) + share = 1; + + for (i = 1; i < *p_argc; i++) + if (strcmp (argv[i], "-o") == 0) + { + char *buff, *ptr; + int out_len; + int len; + + i++; + ptr = to_host_file_spec (argv[i]); + exefilename = xstrdup (ptr); + out_len = strlen (ptr); + buff = xmalloc (out_len + 18); + + if (share) + strcpy (buff, "/share="); + else + strcpy (buff, "/exe="); + + strcat (buff, ptr); + addarg (buff); + + if (share) + { + sharefilename = xmalloc (out_len+5); + if (ptr == strchr (argv[i], ']')) + strcpy (sharefilename, ++ptr); + else if (ptr == strchr (argv[i], ':')) + strcpy (sharefilename, ++ptr); + else if (ptr == strrchr (argv[i], '/')) + strcpy (sharefilename, ++ptr); + else + strcpy (sharefilename, argv[i]); + + len = strlen (sharefilename); + if (strncasecmp (&sharefilename[len-4], ".exe", 4) == 0) + sharefilename[len-4] = 0; + + for (ptr = sharefilename; *ptr; ptr++) + *ptr = TOUPPER (*ptr); + } + } +} + +static void +process_args (p_argc, argv) + int *p_argc; + char **argv; +{ + int i; + + for (i = 1; i < *p_argc; i++) + { + if (strlen (argv[i]) < 2) + continue; + + if (strncmp (argv[i], "-L", 2) == 0) + { + char *nbuff, *ptr; + int new_len, search_dirs_len; + + ptr = &argv[i][2]; + new_len = strlen (ptr); + search_dirs_len = strlen (search_dirs); + + nbuff = xmalloc (new_len + 1); + strcpy (nbuff, ptr); + + /* Remove trailing slashes. */ + while (new_len > 1 && nbuff [new_len - 1] == '/') + { + nbuff [new_len - 1] = 0; + new_len--; + } + + search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2); + if (search_dirs_len > 0) + strcat (search_dirs, PATH_SEPARATOR_STR); + + strcat (search_dirs, nbuff); + free (nbuff); + } + + /* -v turns on verbose option here and is passed on to gcc. */ + else if (strcmp (argv[i], "-v") == 0) + verbose = 1; + else if (strcmp (argv[i], "-g0") == 0) + addarg ("/notraceback"); + else if (strncmp (argv[i], "-g", 2) == 0) + { + addarg ("/debug"); + debug = 1; + } + else if (strcmp (argv[i], "-static") == 0) + staticp = 1; + else if (strcmp (argv[i], "-map") == 0) + { + char *buff, *ptr; + + buff = xmalloc (strlen (exefilename) + 5); + strcpy (buff, exefilename); + ptr = strchr (buff, '.'); + if (ptr) + *ptr = 0; + + strcat (buff, ".map"); + addarg ("/map="); + addarg (buff); + addarg ("/full"); + } + else if (strcmp (argv[i], "-save-temps") == 0) + save_temps = 1; + else if (strcmp (argv[i], "--noinhibit-exec") == 0) + inhibit_exec = 0; + } +} + +/* The main program. Spawn the VMS linker after fixing up the Unix-like flags + and args to be what the VMS linker wants. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int i; + char cwdev [128], *devptr; + int devlen; + int optfd; + FILE *optfile; + char *cwd = getcwd (0, 1024); + char *optfilename; + + devptr = strchr (cwd, ':'); + devlen = (devptr - cwd) + 1; + strncpy (cwdev, cwd, devlen); + cwdev [devlen] = '\0'; + + search_dirs = xmalloc (strlen (system_search_dirs) + 1); + strcpy (search_dirs, system_search_dirs); + + addarg ("link"); + + /* Pass to find args that have to be append first. */ + preprocess_args (&argc , argv); + + /* Pass to find the rest of the args. */ + process_args (&argc , argv); + + /* Create a temp file to hold args, otherwise we can easily exceed the VMS + command line length limits. */ + optfilename = alloca (strlen ("LDXXXXXX") + 1); + strcpy (optfilename, "LDXXXXXX"); + optfd = mkstemp (optfilename); + getcwd (optfilefullname, 256, 1); /* VMS style cwd. */ + strcat (optfilefullname, optfilename); + strcat (optfilefullname, "."); + optfile = fdopen (optfd, "w"); + + /* Write out the IDENTIFICATION argument first so that it can be overridden + by an options file. */ + for (i = 1; i < argc; i++) + { + int arg_len = strlen (argv[i]); + + if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) + { + /* Comes from command line. If present will always appear before + IDENTIFICATION=... and will override. */ + + if (!ident) + ident = 1; + } + else if (arg_len > 15 + && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) + { + /* Comes from pragma Ident (). */ + + if (!ident) + { + fprintf (optfile, "case_sensitive=yes\n"); + fprintf (optfile, "IDENTIFICATION=\"%15.15s\"\n", &argv[i][15]); + fprintf (optfile, "case_sensitive=NO\n"); + ident = 1; + } + } + } + + for (i = 1; i < argc; i++) + { + int arg_len = strlen (argv[i]); + + if (strcmp (argv[i], "-o") == 0) + i++; + else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0) + { + const char *libname = expand_lib (&argv[i][2]); + const char *ext; + int len; + + if ((len = strlen (libname)) > 0) + { + char buff [256]; + + if (len > 4 && strcasecmp (&libname [len-4], ".exe") == 0) + ext = "/shareable"; + else + ext = "/library"; + + if (libname[0] == '[') + sprintf (buff, "%s%s", cwdev, libname); + else + sprintf (buff, "%s", libname); + + fprintf (optfile, "%s%s\n", buff, ext); + } + } + + else if (strcmp (argv[i], "-v" ) == 0 + || strncmp (argv[i], "-g", 2 ) == 0 + || strcmp (argv[i], "-static" ) == 0 + || strcmp (argv[i], "-map" ) == 0 + || strcmp (argv[i], "-save-temps") == 0 + || strcmp (argv[i], "--noinhibit-exec") == 0 + || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0) + || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0)) + ; + else if (arg_len > 1 && argv[i][0] == '@') + { + FILE *atfile; + char *ptr, *ptr1; + struct stat statbuf; + char *buff; + int len; + + if (stat (&argv[i][1], &statbuf)) + { + fprintf (stderr, "Couldn't open linker response file: %s\n", + &argv[i][1]); + exit (1); + } + + buff = xmalloc (statbuf.st_size + 1); + atfile = fopen (&argv[i][1], "r"); + fgets (buff, statbuf.st_size + 1, atfile); + fclose (atfile); + + len = strlen (buff); + if (buff [len - 1] == '\n') + { + buff [len - 1] = 0; + len--; + } + + ptr = buff; + + do + { + ptr1 = strchr (ptr, ' '); + if (ptr1) + *ptr1 = 0; + ptr = to_host_file_spec (ptr); + if (ptr[0] == '[') + fprintf (optfile, "%s%s\n", cwdev, ptr); + else + fprintf (optfile, "%s\n", ptr); + ptr = ptr1 + 1; + } while (ptr1); + } + + /* Unix style file specs and VMS style switches look alike, so assume an + arg consisting of one and only one slash, and that being first, is + really a switch. */ + else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0)) + addarg (argv[i]); + else if (arg_len > 4 + && strncasecmp (&argv[i][arg_len-4], ".OPT", 4) == 0) + { + FILE *optfile1; + char buff [256]; + + optfile1 = fopen (argv[i], "r"); + while (fgets (buff, 256, optfile1)) + fputs (buff, optfile); + + fclose (optfile1); + } + else if (arg_len > 7 && strncasecmp (argv[i], "GSMATCH", 7) == 0) + fprintf (optfile, "%s\n", argv[i]); + else if (arg_len > 6 && strncasecmp (argv[i], "IDENT=", 6) == 0) + { + /* Comes from command line and will override pragma. */ + fprintf (optfile, "case_sensitive=yes\n"); + fprintf (optfile, "IDENT=\"%15.15s\"\n", &argv[i][6]); + fprintf (optfile, "case_sensitive=NO\n"); + ident = 1; + } + else if (arg_len > 15 + && strncasecmp (argv[i], "IDENTIFICATION=", 15) == 0) + ; + else + { + /* Assume filename arg. */ + const char *addswitch = ""; + char buff [256]; + int buff_len; + int is_cld = 0; + + argv[i] = to_host_file_spec (argv[i]); + arg_len = strlen (argv[i]); + + if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".exe") == 0) + addswitch = "/shareable"; + + if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".cld") == 0) + { + addswitch = "/shareable"; + is_cld = 1; + } + + if (arg_len > 2 && strcasecmp (&argv[i][arg_len-2], ".a") == 0) + addswitch = "/lib"; + + if (arg_len > 4 && strcasecmp (&argv[i][arg_len-4], ".olb") == 0) + addswitch = "/lib"; + + if (argv[i][0] == '[') + sprintf (buff, "%s%s%s\n", cwdev, argv[i], addswitch); + else if (strchr (argv[i], ':')) + sprintf (buff, "%s%s\n", argv[i], addswitch); + else + sprintf (buff, "%s%s%s\n", cwd, argv[i], addswitch); + + buff_len = strlen (buff); + + if (buff_len >= 13 + && strcasecmp (&buff[buff_len-13],"vms-dwarf2.o\n") == 0) + vmsdwarf2spec = xstrdup (buff); + else if (is_cld) + { + addarg (buff); + addarg (","); + } + else + fprintf (optfile, buff); + } + } + +#if 0 + if (share) + fprintf (optfile, "symbol_vector=(main=procedure)\n"); +#endif + + if (debug && vmsdwarf2spec) + { + fprintf (optfile, "case_sensitive=yes\n"); + fprintf (optfile, "cluster=DWARF2debug,,,%s", vmsdwarf2spec); + fprintf (optfile, "collect=DWARF2debug,debug_abbrev,debug_aranges,-\n"); + fprintf (optfile, " debug_frame,debug_info,debug_line,debug_loc,-\n"); + fprintf (optfile, + " debug_macinfo,debug_pubnames,debug_str,debug_zzzzzz\n"); + fprintf (optfile, "case_sensitive=NO\n"); + } + + if (debug && share) + { + fprintf (optfile, "case_sensitive=yes\n"); + fprintf (optfile, "symbol_vector=(-\n"); + fprintf (optfile, + "%s$DWARF2.DEBUG_ABBREV/$dwarf2.debug_abbrev=DATA,-\n", + sharefilename); + fprintf (optfile, + "%s$DWARF2.DEBUG_ARANGES/$dwarf2.debug_aranges=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_FRAME/$dwarf2.debug_frame=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_INFO/$dwarf2.debug_info=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_LINE/$dwarf2.debug_line=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_LOC/$dwarf2.debug_loc=DATA,-\n", + sharefilename); + fprintf (optfile, + "%s$DWARF2.DEBUG_MACINFO/$dwarf2.debug_macinfo=DATA,-\n", + sharefilename); + fprintf (optfile, + "%s$DWARF2.DEBUG_PUBNAMES/$dwarf2.debug_pubnames=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_STR/$dwarf2.debug_str=DATA,-\n", + sharefilename); + fprintf (optfile, "%s$DWARF2.DEBUG_ZZZZZZ/$dwarf2.debug_zzzzzz=DATA)\n", + sharefilename); + fprintf (optfile, "case_sensitive=NO\n"); + } + + fclose (optfile); + addarg (optfilefullname); + addarg ("/opt"); + + addarg (NULL); + + if (verbose) + { + int i; + + for (i = 0; i < link_arg_index; i++) + printf ("%s ", link_args [i]); + putchar ('\n'); + } + + { + int i; + int len = 0; + + for (i = 0; link_args[i]; i++) + len = len + strlen (link_args[i]) + 1; + + { + char *allargs = (char *) alloca (len + 1); + Descr cmd; + int status; + int status1 = 1; + + for (i = 0; i < len + 1; i++) + allargs [i] = 0; + + for (i = 0; link_args [i]; i++) + { + strcat (allargs, link_args [i]); + strcat (allargs, " "); + } + + cmd.adr = allargs; + cmd.len = len; + cmd.mbz = 0; + + i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status); + if ((i & 1) != 1) + { + LIB$SIGNAL (i); + exit (1); + } + + if (debug && !share) + { + strcpy (allargs, "@gnu:[bin]set_exe "); + strcat (allargs, exefilename); + strcat (allargs, " /nodebug /silent"); + len = strlen (allargs); + cmd.adr = allargs; + cmd.len = len; + cmd.mbz = 0; + + if (verbose) + printf (allargs); + + i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status1); + + if ((i & 1) != 1) + { + LIB$SIGNAL (i); + exit (1); + } + } + + if (!save_temps) + remove (optfilefullname); + + if ((status & 1) == 1 && (status1 & 1) == 1) + exit (0); + + if (exefilename && inhibit_exec == 1) + remove (exefilename); + + exit (1); + } + } +} + +static char new_host_filespec [255]; +static char filename_buff [256]; + +static int +translate_unix (name, type) + char *name; + int type ATTRIBUTE_UNUSED; +{ + strcpy (filename_buff, name); + return 0; +} + +static char * +to_host_file_spec (filespec) + char *filespec; +{ + strcpy (new_host_filespec, ""); + if (strchr (filespec, ']') || strchr (filespec, ':')) + strcpy (new_host_filespec, filespec); + else + { + decc$to_vms (filespec, translate_unix, 1, 1); + strcpy (new_host_filespec, filename_buff); + } + + return new_host_filespec; +} diff --git a/gcc/config/alpha/x-vms b/gcc/config/alpha/x-vms new file mode 100644 index 00000000000..49338c152b6 --- /dev/null +++ b/gcc/config/alpha/x-vms @@ -0,0 +1,11 @@ +vms-ld.o : $(srcdir)/config/alpha/vms-ld.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) +ld.exe : vms-ld.o + $(CC) -o $@ vms-ld.o ../libiberty/libiberty.a + +vms-cc.o : $(srcdir)/config/alpha/vms-cc.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) +decc.exe : vms-cc.o + $(CC) -o $@ vms-cc.o ../libiberty/libiberty.a + +EXTRA_PROGRAMS=ld.exe decc.exe