#include "prefix.h"
#include "gcc.h"
#include "flags.h"
+#include "opts.h"
/* By default there is no special suffix for target executables. */
/* FIXME: when autoconf is fixed, remove the host check - dj */
/* Nonzero if cross-compiling.
When -b is used, the value comes from the `specs' file. */
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
static const char *cross_compile = "1";
#else
static const char *cross_compile = "0";
static void set_multilib_dir (void);
static void print_multilib_info (void);
static void perror_with_name (const char *);
+static void fatal_ice (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
static void display_help (void);
static void add_preprocessor_option (const char *, int);
#endif
#endif
-#ifndef LINK_GCC_MATH_SPEC
-#define LINK_GCC_MATH_SPEC ""
-#endif
-
#ifndef LINK_PIE_SPEC
#ifdef HAVE_LD_PIE
#define LINK_PIE_SPEC "%{pie:-pie} "
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
- %{static:} %{L*} %(mfwrap) %{fopenmp:%:include(libgomp.spec)%(link_gomp)}\
- %(link_libgcc) %o %(mflib)\
+ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
+ %{fopenmp:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
%{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
- %{!nostdlib:%{!nodefaultlibs:%(link_gcc_math) %(link_ssp) %(link_gcc_c_sequence)}}\
+ %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
static const char *cc1plus_spec = CC1PLUS_SPEC;
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
static const char *link_ssp_spec = LINK_SSP_SPEC;
-static const char *link_gcc_math_spec = LINK_GCC_MATH_SPEC;
static const char *asm_spec = ASM_SPEC;
static const char *asm_final_spec = ASM_FINAL_SPEC;
static const char *link_spec = LINK_SPEC;
#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
#endif
-#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
+#ifdef CROSS_DIRECTORY_STRUCTURE /* Don't use these prefixes for a cross compiler. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
#undef MD_STARTFILE_PREFIX_1
#define MD_STARTFILE_PREFIX_1 ""
#endif
+/* These directories are locations set at configure-time based on the
+ --prefix option provided to configure. Their initializers are
+ defined in Makefile.in. These paths are not *directly* used when
+ gcc_exec_prefix is set because, in that case, we know where the
+ compiler has been installed, and use paths relative to that
+ location instead. */
static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
+static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+
+/* For native compilers, these are well-known paths containing
+ components that may be provided by the system. For cross
+ compilers, these paths are not used. */
static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
static const char *md_exec_prefix = MD_EXEC_PREFIX;
-
static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
-static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
-static const char *const standard_startfile_prefix_1
+static const char *const standard_startfile_prefix_1
= STANDARD_STARTFILE_PREFIX_1;
static const char *const standard_startfile_prefix_2
= STANDARD_STARTFILE_PREFIX_2;
+/* A relative path to be used in finding the location of tools
+ relative to the driver. */
static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
-static const char *tooldir_prefix;
-
-static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
-
-static const char *standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
/* Subdirectory to use for locating libraries. Set by
set_multilib_dir based on the compilation options. */
INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec),
INIT_STATIC_SPEC ("link_gcc_c_sequence", &link_gcc_c_sequence_spec),
INIT_STATIC_SPEC ("link_ssp", &link_ssp_spec),
- INIT_STATIC_SPEC ("link_gcc_math", &link_gcc_math_spec),
INIT_STATIC_SPEC ("endfile", &endfile_spec),
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
{ "replace-outfile", replace_outfile_spec_function },
{ "version-compare", version_compare_spec_function },
{ "include", include_spec_function },
+#ifdef EXTRA_SPEC_FUNCTIONS
+ EXTRA_SPEC_FUNCTIONS
+#endif
{ 0, 0 }
};
if (!sl)
{
/* Not found - make it. */
- sl = xmalloc (sizeof (struct spec_list));
+ sl = XNEW (struct spec_list);
sl->name = xstrdup (name);
sl->name_len = name_len;
sl->ptr_spec = &sl->ptr;
alloc_args (void)
{
argbuf_length = 10;
- argbuf = xmalloc (argbuf_length * sizeof (const char *));
+ argbuf = XNEWVEC (const char *, argbuf_length);
}
/* Clear out the vector of arguments (after a command is executed). */
pfatal_with_name (filename);
/* Read contents of file into BUFFER. */
- buffer = xmalloc ((unsigned) statbuf.st_size + 1);
+ buffer = XNEWVEC (char, statbuf.st_size + 1);
readlen = read (desc, buffer, (unsigned) statbuf.st_size);
if (readlen < 0)
pfatal_with_name (filename);
buffer[readlen] = 0;
close (desc);
- specs = xmalloc (readlen + 1);
+ specs = XNEWVEC (char, readlen + 1);
specs_p = specs;
for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
{
if (! strcmp (name, temp->name))
goto already1;
- temp = xmalloc (sizeof (struct temp_file));
+ temp = XNEW (struct temp_file);
temp->next = always_delete_queue;
temp->name = name;
always_delete_queue = temp;
if (! strcmp (name, temp->name))
goto already2;
- temp = xmalloc (sizeof (struct temp_file));
+ temp = XNEW (struct temp_file);
temp->next = failure_delete_queue;
temp->name = name;
failure_delete_queue = temp;
len += suffix_len;
else
len += multi_os_dir_len;
- path = xmalloc (len);
+ path = XNEWVEC (char, len);
}
for (pl = paths->plist; pl != 0; pl = pl->next)
if (len > pprefix->max_len)
pprefix->max_len = len;
- pl = xmalloc (sizeof (struct prefix_list));
+ pl = XNEW (struct prefix_list);
pl->prefix = prefix;
pl->require_machine_suffix = require_machine_suffix;
pl->priority = priority;
}
/* Same as add_prefix, but prepending target_system_root to prefix. */
+/* The target_system_root prefix has been relocated by gcc_exec_prefix. */
static void
add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
const char *component,
}
else
#endif
- fatal ("\
+ fatal_ice ("\
Internal error: %s (program %s)\n\
Please submit a full bug report.\n\
See %s for instructions.",
- strsignal (WTERMSIG (status)), commands[i].prog,
- bug_report_url);
+ strsignal (WTERMSIG (status)), commands[i].prog,
+ bug_report_url);
}
else if (WIFEXITED (status)
&& WEXITSTATUS (status) >= MIN_FATAL_STATUS)
fputs (_(" -std=<standard> Assume that the input sources are for <standard>\n"), stdout);
fputs (_("\
--sysroot=<directory> Use <directory> as the root directory for headers\n\
- for headers and libraries\n"), stdout);
+ and libraries\n"), stdout);
fputs (_(" -B <directory> Add <directory> to the compiler's search paths\n"), stdout);
fputs (_(" -b <machine> Run gcc for target <machine>, if installed\n"), stdout);
fputs (_(" -V <version> Run gcc version number <version>, if installed\n"), stdout);
n_preprocessor_options++;
if (! preprocessor_options)
- preprocessor_options = xmalloc (n_preprocessor_options * sizeof (char *));
+ preprocessor_options = XNEWVEC (char *, n_preprocessor_options);
else
preprocessor_options = xrealloc (preprocessor_options,
n_preprocessor_options * sizeof (char *));
n_assembler_options++;
if (! assembler_options)
- assembler_options = xmalloc (n_assembler_options * sizeof (char *));
+ assembler_options = XNEWVEC (char *, n_assembler_options);
else
assembler_options = xrealloc (assembler_options,
n_assembler_options * sizeof (char *));
n_linker_options++;
if (! linker_options)
- linker_options = xmalloc (n_linker_options * sizeof (char *));
+ linker_options = XNEWVEC (char *, n_linker_options);
else
linker_options = xrealloc (linker_options,
n_linker_options * sizeof (char *));
int lang_n_infiles = 0;
#ifdef MODIFY_TARGET_NAME
int is_modify_target_name;
- int j;
+ unsigned int j;
#endif
+ const char *tooldir_prefix;
GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
}
else
- gcc_libexec_prefix = make_relative_prefix (gcc_exec_prefix,
- standard_exec_prefix,
- standard_libexec_prefix);
+ {
+ /* make_relative_prefix requires a program name, but
+ GCC_EXEC_PREFIX is typically a directory name with a trailing
+ / (which is ignored by make_relative_prefix), so append a
+ program name. */
+ char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
+ gcc_libexec_prefix = make_relative_prefix (tmp_prefix,
+ standard_exec_prefix,
+ standard_libexec_prefix);
+
+ /* The path is unrelocated, so fallback to the original setting. */
+ if (!gcc_libexec_prefix)
+ gcc_libexec_prefix = standard_libexec_prefix;
+
+ free (tmp_prefix);
+ }
#else
#endif
+ /* From this point onward, gcc_exec_prefix is non-null if the toolchain
+ is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
+ or an automatically created GCC_EXEC_PREFIX from argv[0]. */
if (gcc_exec_prefix)
{
}
else if (strcmp (argv[i], "-specs") == 0)
{
- struct user_specs *user = xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = XNEW (struct user_specs);
if (++i >= argc)
fatal ("argument to '-specs' is missing");
}
else if (strncmp (argv[i], "-specs=", 7) == 0)
{
- struct user_specs *user = xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = XNEW (struct user_specs);
if (strlen (argv[i]) == 7)
fatal ("argument to '-specs=' is missing");
switch (c)
{
case 'b':
- if (NULL == strchr(argv[i] + 2, '-')) break;
+ if (NULL == strchr(argv[i] + 2, '-'))
+ goto normal_switch;
+
+ /* Fall through. */
case 'V':
fatal ("'-%c' must come at the start of the command line", c);
break;
if (! IS_DIR_SEPARATOR (value [len - 1])
&& is_directory (value, false))
{
- char *tmp = xmalloc (len + 2);
+ char *tmp = XNEWVEC (char, len + 2);
strcpy (tmp, value);
tmp[len] = DIR_SEPARATOR;
tmp[++ len] = 0;
use_pipes = 0;
}
- /* Set up the search paths before we go looking for config files. */
+ /* Set up the search paths. We add directories that we expect to
+ contain GNU Toolchain components before directories specified by
+ the machine description so that we will find GNU components (like
+ the GNU assembler) before those of the host system. */
- /* These come before the md prefixes so that we will find gcc's subcommands
- (such as cpp) rather than those of the host system. */
- /* Use 2 as fourth arg meaning try just the machine as a suffix,
- as well as trying the machine and the version. */
+ /* If we don't know where the toolchain has been installed, use the
+ configured-in locations. */
+ if (!gcc_exec_prefix)
+ {
#ifndef OS2
- add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 1, 0);
- add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, 0);
- add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, 0);
- add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, 0);
- add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, 0);
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
+ PREFIX_PRIORITY_LAST, 1, 0);
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
+ add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
#endif
+ add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 1, 0);
+ }
- add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, 0);
- add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, 0);
+ /* If not cross-compiling, search well-known system locations. */
+ if (*cross_compile == '0')
+ {
+#ifndef OS2
+ add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
+ add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
+#endif
+ add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 1, 0);
+ }
+ gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
dir_separator_str, NULL);
- /* If tooldir is relative, base it on exec_prefixes. A relative
- tooldir lets us move the installed tree as a unit.
-
- If GCC_EXEC_PREFIX is defined, then we want to add two relative
- directories, so that we can search both the user specified directory
- and the standard place. */
-
- if (!IS_ABSOLUTE_PATH (tooldir_prefix))
- {
- if (gcc_exec_prefix)
- {
- char *gcc_exec_tooldir_prefix
- = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
- spec_version, dir_separator_str, tooldir_prefix, NULL);
-
- add_prefix (&exec_prefixes,
- concat (gcc_exec_tooldir_prefix, "bin",
- dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, 0);
- add_prefix (&startfile_prefixes,
- concat (gcc_exec_tooldir_prefix, "lib",
- dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, 1);
- }
-
- tooldir_prefix = concat (standard_exec_prefix, spec_machine,
- dir_separator_str, spec_version,
- dir_separator_str, tooldir_prefix, NULL);
- }
+ /* Look for tools relative to the location from which the driver is
+ running, or, if that is not available, the configured prefix. */
+ tooldir_prefix
+ = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
+ spec_machine, dir_separator_str,
+ spec_version, dir_separator_str, tooldir_prefix, NULL);
add_prefix (&exec_prefixes,
concat (tooldir_prefix, "bin", dir_separator_str, NULL),
/* Then create the space for the vectors and scan again. */
- switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr));
- infiles = xmalloc ((n_infiles + 1) * sizeof (struct infile));
+ switches = XNEWVEC (struct switchstr, n_switches + 1);
+ infiles = XNEWVEC (struct infile, n_infiles + 1);
n_switches = 0;
n_infiles = 0;
last_language_n_infiles = -1;
if (i + n_args >= argc)
fatal ("argument to '-%s' is missing", p);
switches[n_switches].args
- = xmalloc ((n_args + 1) * sizeof(const char *));
+ = XNEWVEC (const char *, n_args + 1);
while (j < n_args)
switches[n_switches].args[j++] = argv[++i];
/* Null-terminate the vector. */
{
/* On some systems, ld cannot handle some options without
a space. So split the option from its argument. */
- char *part1 = xmalloc (2);
+ char *part1 = XNEWVEC (char, 2);
part1[0] = c;
part1[1] = '\0';
switches[n_switches].part1 = part1;
- switches[n_switches].args = xmalloc (2 * sizeof (const char *));
+ switches[n_switches].args = XNEWVEC (const char *, 2);
switches[n_switches].args[0] = xstrdup (p+1);
switches[n_switches].args[1] = 0;
}
else
{
saved_suffix
- = xmalloc (suffix_length
+ = XNEWVEC (char, suffix_length
+ strlen (TARGET_OBJECT_SUFFIX));
strncpy (saved_suffix, suffix, suffix_length);
strcpy (saved_suffix + suffix_length,
expandargv (&argc, &argv);
+ prune_options (&argc, &argv);
+
#ifdef GCC_DRIVER_HOST_INITIALIZATION
/* Perform host dependent initialization when needed. */
GCC_DRIVER_HOST_INITIALIZATION;
PREFIX_PRIORITY_LAST, 0, 1);
else if (*cross_compile == '0')
{
- if (gcc_exec_prefix)
- add_prefix (&startfile_prefixes,
- concat (gcc_exec_prefix, machine_suffix,
- standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, 1);
add_prefix (&startfile_prefixes,
- concat (standard_exec_prefix,
- machine_suffix,
+ concat (gcc_exec_prefix
+ ? gcc_exec_prefix : standard_exec_prefix,
+ machine_suffix,
standard_startfile_prefix, NULL),
NULL, PREFIX_PRIORITY_LAST, 0, 1);
}
+ /* Sysrooted prefixes are relocated because target_system_root is
+ also relocated by gcc_exec_prefix. */
if (*standard_startfile_prefix_1)
add_sysrooted_prefix (&startfile_prefixes,
standard_startfile_prefix_1, "BINUTILS",
if (print_search_dirs)
{
- printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
+ printf (_("install: %s%s\n"),
+ gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
+ gcc_exec_prefix ? "" : machine_suffix);
printf (_("programs: %s\n"),
build_search_list (&exec_prefixes, "", false, false));
printf (_("libraries: %s\n"),
i = n_infiles;
i += lang_specific_extra_outfiles;
- outfiles = xcalloc (i, sizeof (char *));
+ outfiles = XCNEWVEC (const char *, i);
/* Record which files were specified explicitly as link input. */
- explicit_link_files = xcalloc (1, n_infiles);
+ explicit_link_files = XCNEWVEC (char, n_infiles);
if (combine_flag)
combine_inputs = true;
static char *
save_string (const char *s, int len)
{
- char *result = xmalloc (len + 1);
+ char *result = XNEWVEC (char, len + 1);
memcpy (result, s, len);
result[len] = 0;
void
fancy_abort (const char *file, int line, const char *func)
{
- fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
+ fatal_ice ("internal gcc abort in %s, at %s:%d", func, file, line);
}
\f
/* Output an error message and exit. */
void
+fatal_ice (const char *cmsgid, ...)
+{
+ va_list ap;
+
+ va_start (ap, cmsgid);
+
+ fprintf (stderr, "%s: ", programname);
+ vfprintf (stderr, _(cmsgid), ap);
+ va_end (ap);
+ fprintf (stderr, "\n");
+ delete_temp_files ();
+ exit (pass_exit_codes ? ICE_EXIT_CODE : 1);
+}
+
+void
fatal (const char *cmsgid, ...)
{
va_list ap;
xmalloc from calling fatal, and prevents us from re-executing this
block of code. */
mswitches
- = xmalloc (sizeof (struct mswitchstr)
- * (n_mdswitches + (n_switches ? n_switches : 1)));
+ = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
for (i = 0; i < n_switches; i++)
if (switches[i].live_cond != SWITCH_IGNORE)
{
{
int i = 0;
- mdswitches = xmalloc (sizeof (struct mdswitchstr) * n_mdswitches);
+ mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
for (start = multilib_defaults; *start != '\0'; start = end + 1)
{
while (*start == ' ' || *start == '\t')
if (this_path_len != 1
|| this_path[0] != '.')
{
- char *new_multilib_dir = xmalloc (this_path_len + 1);
+ char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
char *q;
strncpy (new_multilib_dir, this_path, this_path_len);
q++;
if (q < end)
{
- char *new_multilib_os_dir = xmalloc (end - q);
+ char *new_multilib_os_dir = XNEWVEC (char, end - q);
memcpy (new_multilib_os_dir, q + 1, end - q - 1);
new_multilib_os_dir[end - q - 1] = '\0';
multilib_os_dir = new_multilib_os_dir;