📄 vms-ld.c
字号:
/* VMS linker wrapper. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe 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;/* File specification for vms-dwarf2eh.o. */static char *vmsdwarf2ehspec = 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 accommodate. */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 voidaddarg (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 intis_regular_file (name) char *name;{ int ret; struct stat statbuf; ret = stat (name, &statbuf); return !ret && S_ISREG (statbuf.st_mode);}static voidpreprocess_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 voidprocess_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. */intmain (argc, argv) int argc; char **argv;{ int i; char cwdev [128], *devptr; int devlen; int optfd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -