X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fgcc.c;h=1941aed2751d7dff8abae731def47436c80b5556;hb=76b4b31ead81f9c957962ab76df73c59a0650f14;hp=c558de3beac0b87bac2cbda7684f8a86ddf2e97b;hpb=e29ef9202e54f4572c345540e4de17b2b9ff19e1;p=gcc.git diff --git a/gcc/gcc.c b/gcc/gcc.c index c558de3beac..1941aed2751 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -33,17 +33,16 @@ compilation is specified by a string called a "spec". */ #include "config.h" -#include "gansidecl.h" -#include "system.h" - -#include -#include #ifdef __STDC__ #include #else #include #endif +#include "system.h" +#include +#include +#include "gansidecl.h" #include "obstack.h" @@ -52,6 +51,7 @@ extern int pexecute PROTO ((const char *, char * const *, const char *, const char *, char **, char **, int)); extern int pwait PROTO ((int, int *, int)); extern char *update_path PROTO((char *, char *)); +extern void set_std_prefix PROTO((char *, int)); /* Flag arguments to pexecute. */ #define PEXECUTE_FIRST 1 #define PEXECUTE_LAST 2 @@ -75,11 +75,6 @@ extern char *update_path PROTO((char *, char *)); #define exit __posix_exit #endif -/* Define O_RDONLY if the system hasn't defined it for us. */ -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - #ifdef USG #define vfork fork #endif /* USG */ @@ -122,6 +117,10 @@ static char dir_separator_str[] = {DIR_SEPARATOR, 0}; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free +#ifndef GET_ENVIRONMENT +#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME) +#endif + extern char *choose_temp_base PROTO((void)); #ifndef HAVE_STRERROR @@ -247,21 +246,15 @@ static void print_multilib_info PROTO((void)); static void pfatal_with_name PROTO((char *)); static void perror_with_name PROTO((char *)); static void pfatal_pexecute PROTO((char *, char *)); -#ifdef HAVE_VPRINTF static void fatal PVPROTO((char *, ...)); static void error PVPROTO((char *, ...)); -#else -/* We must not provide any prototype here, even if ANSI C. */ -static void fatal PROTO(()); -static void error PROTO(()); -#endif void fancy_abort (); char *xmalloc (); char *xrealloc (); #ifdef LANG_SPECIFIC_DRIVER -extern void lang_specific_driver PROTO ((void (*) (), int *, char ***)); +extern void lang_specific_driver PROTO ((void (*) PVPROTO((char *, ...)), int *, char ***, int *)); #endif /* Specs are strings containing lines, each of which (if not blank) @@ -473,6 +466,10 @@ proper position among the other output files. */ #endif #endif +#ifndef LINKER_NAME +#define LINKER_NAME "collect2" +#endif + static char *cpp_spec = CPP_SPEC; static char *cpp_predefines = CPP_PREDEFINES; static char *cc1_spec = CC1_SPEC; @@ -486,6 +483,7 @@ static char *libgcc_spec = LIBGCC_SPEC; static char *endfile_spec = ENDFILE_SPEC; static char *startfile_spec = STARTFILE_SPEC; static char *switches_need_spaces = SWITCHES_NEED_SPACES; +static char *linker_name_spec = LINKER_NAME; /* Some compilers have limits on line lengths, and the multilib_select and/or multilib_matches strings can be very long, so we build them at @@ -704,7 +702,7 @@ static int n_default_compilers /* Don't generate -L options. */ static char *link_command_spec = "\ %{!fsyntax-only: \ - %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ + %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ %{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\ %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ %{static:} %{L*} %o\ @@ -716,7 +714,7 @@ static char *link_command_spec = "\ /* Use -L. */ static char *link_command_spec = "\ %{!fsyntax-only: \ - %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ + %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ %{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\ %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ %{static:} %{L*} %D %o\ @@ -1089,6 +1087,7 @@ static struct spec_list static_specs[] = { INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults), INIT_STATIC_SPEC ("multilib_extra", &multilib_extra), INIT_STATIC_SPEC ("multilib_matches", &multilib_matches), + INIT_STATIC_SPEC ("linker", &linker_name_spec), }; #ifdef EXTRA_SPECS /* additional specs needed */ @@ -2126,6 +2125,7 @@ execute () commands[0].prog = argbuf[0]; /* first command. */ commands[0].argv = &argbuf[0]; string = find_a_file (&exec_prefixes, commands[0].prog, X_OK); + if (string) commands[0].argv[0] = string; @@ -2280,6 +2280,11 @@ static struct infile *infiles; static int n_infiles; +/* This counts the number of libraries added by LANG_SPECIFIC_DRIVER, so that + we can tell if there were any user supplied any files or libraries. */ + +static int added_libraries; + /* And a vector of corresponding output files is made up later. */ static char **outfiles; @@ -2358,10 +2363,11 @@ process_command (argc, argv) int have_o = 0; int lang_n_infiles = 0; - gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX"); + GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); n_switches = 0; n_infiles = 0; + added_libraries = 0; /* Figure compiler version from version string. */ @@ -2379,6 +2385,20 @@ process_command (argc, argv) if (gcc_exec_prefix) { + int len = strlen (gcc_exec_prefix); + if (len > sizeof ("/lib/gcc-lib/")-1 + && (gcc_exec_prefix[len-1] == '/' + || gcc_exec_prefix[len-1] == DIR_SEPARATOR)) + { + temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1; + if ((*temp == '/' || *temp == DIR_SEPARATOR) + && strncmp (temp+1, "lib", 3) == 0 + && (temp[4] == '/' || temp[4] == DIR_SEPARATOR) + && strncmp (temp+5, "gcc-lib", 7) == 0) + len -= sizeof ("/lib/gcc-lib/") - 1; + } + + set_std_prefix (gcc_exec_prefix, len); add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC", 0, 0, NULL_PTR); add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC", 0, 0, NULL_PTR); } @@ -2386,7 +2406,7 @@ process_command (argc, argv) /* COMPILER_PATH and LIBRARY_PATH have values that are lists of directory names with colons. */ - temp = getenv ("COMPILER_PATH"); + GET_ENVIRONMENT (temp, "COMPILER_PATH"); if (temp) { char *startp, *endp; @@ -2420,7 +2440,7 @@ process_command (argc, argv) } } - temp = getenv ("LIBRARY_PATH"); + GET_ENVIRONMENT (temp, "LIBRARY_PATH"); if (temp && *cross_compile == '0') { char *startp, *endp; @@ -2453,7 +2473,7 @@ process_command (argc, argv) } /* Use LPATH like LIBRARY_PATH (for the CMU build program). */ - temp = getenv ("LPATH"); + GET_ENVIRONMENT (temp, "LPATH"); if (temp && *cross_compile == '0') { char *startp, *endp; @@ -2490,7 +2510,7 @@ process_command (argc, argv) #ifdef LANG_SPECIFIC_DRIVER /* Do language-specific adjustment/addition of flags. */ - lang_specific_driver (fatal, &argc, &argv); + lang_specific_driver (fatal, &argc, &argv, &added_libraries); #endif /* Scan argv twice. Here, the first time, just count how many switches @@ -2509,7 +2529,7 @@ process_command (argc, argv) } else if (! strcmp (argv[i], "-dumpversion")) { - printf ("%s\n", version_string); + printf ("%s\n", spec_version); exit (0); } else if (! strcmp (argv[i], "-dumpmachine")) @@ -2728,6 +2748,36 @@ process_command (argc, argv) spec_version = p + 1; compiler_version = spec_version; warn_std_ptr = &warn_std; + + /* Validate the version number. Use the same checks + done when inserting it into a spec. + + The format of the version string is + ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */ + { + char *v = compiler_version; + + /* Ignore leading non-digits. i.e. "foo-" in "foo-2.7.2". */ + while (! ISDIGIT (*v)) + v++; + + if (v > compiler_version && v[-1] != '-') + fatal ("invalid version number format"); + + /* Set V after the first period. */ + while (ISDIGIT (*v)) + v++; + + if (*v != '.') + fatal ("invalid version number format"); + + v++; + while (ISDIGIT (*v)) + v++; + + if (*v != 0 && *v != ' ' && *v != '.' && *v != '-') + fatal ("invalid version number format"); + } break; case 'c': @@ -2766,7 +2816,7 @@ process_command (argc, argv) } if (have_c && have_o && lang_n_infiles > 1) - fatal ("cannot specify -o with -c and multiple compilations"); + fatal ("cannot specify -o with -c or -S and multiple compilations"); /* Set up the search paths before we go looking for config files. */ @@ -2883,23 +2933,23 @@ process_command (argc, argv) for (j = 4; argv[i][j]; j++) if (argv[i][j] == ',') { - infiles[n_infiles].language = 0; + infiles[n_infiles].language = "*"; infiles[n_infiles++].name = save_string (argv[i] + prev, j - prev); prev = j + 1; } /* Record the part after the last comma. */ - infiles[n_infiles].language = 0; + infiles[n_infiles].language = "*"; infiles[n_infiles++].name = argv[i] + prev; } else if (strcmp (argv[i], "-Xlinker") == 0) { - infiles[n_infiles].language = 0; + infiles[n_infiles].language = "*"; infiles[n_infiles++].name = argv[++i]; } else if (strncmp (argv[i], "-l", 2) == 0) { - infiles[n_infiles].language = 0; + infiles[n_infiles].language = "*"; infiles[n_infiles++].name = argv[i]; } else if (strcmp (argv[i], "-specs") == 0) @@ -3804,13 +3854,12 @@ do_spec_1 (spec, inswitch, soft_matched_part) char *x = (char *) alloca (strlen (name) * 2 + 1); char *buf = x; char *y = name; + int flag = 0; /* Copy all of NAME into BUF, but put __ after every -D and at the end of each arg, */ while (1) { - int flag; - if (! strncmp (y, "-D", 2)) { *x++ = '-'; @@ -4416,7 +4465,7 @@ main (argc, argv) first_time = FALSE; obstack_grow (&collect_obstack, "'-", 2); q = switches[i].part1; - while ((p = (char *) index (q,'\''))) + while ((p = index (q,'\''))) { obstack_grow (&collect_obstack, q, p-q); obstack_grow (&collect_obstack, "'\\''", 4); @@ -4429,7 +4478,7 @@ main (argc, argv) { obstack_grow (&collect_obstack, " '", 2); q = *args; - while ((p = (char *) index (q,'\''))) + while ((p = index (q,'\''))) { obstack_grow (&collect_obstack, q, p-q); obstack_grow (&collect_obstack, "'\\''", 4); @@ -4510,7 +4559,15 @@ main (argc, argv) as a unit. If GCC_EXEC_PREFIX is defined, base standard_startfile_prefix on that as well. */ if (*standard_startfile_prefix == '/' - || *standard_startfile_prefix == DIR_SEPARATOR) + || *standard_startfile_prefix == DIR_SEPARATOR + || *standard_startfile_prefix == '$' +#ifdef __MSDOS__ + /* Check for disk name on MS-DOS-based systems. */ + || (standard_startfile_prefix[1] == ':' + && (standard_startfile_prefix[2] == DIR_SEPARATOR + || standard_startfile_prefix[2] == '/')) +#endif + ) add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS", 0, 0, NULL_PTR); else @@ -4633,7 +4690,7 @@ main (argc, argv) exit (0); } - if (n_infiles == 0) + if (n_infiles == added_libraries) fatal ("No input files"); /* Make a place to record the compiler output file names @@ -4741,6 +4798,13 @@ main (argc, argv) { int tmp = execution_count; + /* We'll use ld if we can't find collect2. */ + if (! strcmp (linker_name_spec, "collect2")) + { + char *s = find_a_file (&exec_prefixes, "collect2", X_OK); + if (s == NULL) + linker_name_spec = "ld"; + } /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */ putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH="); @@ -4778,7 +4842,7 @@ main (argc, argv) /* Find the proper compilation spec for the file name NAME, whose length is LENGTH. LANGUAGE is the specified language, - or 0 if none specified. */ + or 0 if this file is to be passed to the linker. */ static struct compiler * lookup_compiler (name, length, language) @@ -4788,19 +4852,19 @@ lookup_compiler (name, length, language) { struct compiler *cp; - /* Look for the language, if one is spec'd. */ + /* If this was specified by the user to be a linker input, indicate that. */ + if (language != 0 && language[0] == '*') + return 0; + + /* Otherwise, look for the language, if one is spec'd. */ if (language != 0) { for (cp = compilers + n_compilers - 1; cp >= compilers; cp--) - { - if (language != 0) - { - if (cp->suffix[0] == '@' - && !strcmp (cp->suffix + 1, language)) - return cp; - } - } + if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language)) + return cp; + error ("language %s not recognized", language); + return 0; } /* Look for a suffix. */ @@ -4808,23 +4872,24 @@ lookup_compiler (name, length, language) { if (/* The suffix `-' matches only the file name `-'. */ (!strcmp (cp->suffix, "-") && !strcmp (name, "-")) - || - (strlen (cp->suffix) < length - /* See if the suffix matches the end of NAME. */ + || (strlen (cp->suffix) < length + /* See if the suffix matches the end of NAME. */ #ifdef OS2 - && (!strcmp (cp->suffix, - name + length - strlen (cp->suffix)) - || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") - && !strcasecmp (cp->suffix, - name + length - strlen (cp->suffix))))) + && ((!strcmp (cp->suffix, + name + length - strlen (cp->suffix)) + || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) + && !strcasecmp (cp->suffix, + name + length - strlen (cp->suffix))) #else - && !strcmp (cp->suffix, - name + length - strlen (cp->suffix)))) + && !strcmp (cp->suffix, + name + length - strlen (cp->suffix)) #endif + )) { if (cp->spec[0][0] == '@') { struct compiler *new; + /* An alias entry maps a suffix to a language. Search for the language; pass 0 for NAME and LENGTH to avoid infinite recursion if language not found. @@ -4836,6 +4901,7 @@ lookup_compiler (name, length, language) (char *) new->spec, sizeof new->spec); return new; } + /* A non-alias entry: return it. */ return cp; } @@ -4950,6 +5016,8 @@ pfatal_pexecute (errmsg_fmt, errmsg_arg) char *errmsg_fmt; char *errmsg_arg; { + int save_errno = errno; + if (errmsg_arg) { /* Space for trailing '\0' is in %s. */ @@ -4958,7 +5026,7 @@ pfatal_pexecute (errmsg_fmt, errmsg_arg) errmsg_fmt = msg; } - fatal ("%s: %s", errmsg_fmt, my_strerror (errno)); + fatal ("%s: %s", errmsg_fmt, my_strerror (save_errno)); } /* More 'friendly' abort that prints the line and file. @@ -4970,8 +5038,6 @@ fancy_abort () fatal ("Internal gcc abort."); } -#ifdef HAVE_VPRINTF - /* Output an error message and exit */ static void @@ -5016,29 +5082,6 @@ error VPROTO((char *format, ...)) fprintf (stderr, "\n"); } - -#else /* not HAVE_VPRINTF */ - -static void -fatal (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - error (msg, arg1, arg2); - delete_temp_files (); - exit (1); -} - -static void -error (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - fprintf (stderr, "%s: ", programname); - fprintf (stderr, msg, arg1, arg2); - fprintf (stderr, "\n"); -} - -#endif /* not HAVE_VPRINTF */ - static void validate_all_switches ()