/* Forward declaration for prototypes. */
struct path_prefix;
+struct prefix_list;
static void init_spec (void);
static void store_arg (const char *, int, int);
static const char *handle_spec_function (const char *);
static char *save_string (const char *, int);
static void set_collect_gcc_options (void);
+static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);
static int do_spec_1 (const char *, int, const char *);
static int do_spec_2 (const char *);
static void do_option_spec (const char *, const char *);
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
+/* mudflap specs */
+#ifndef MFWRAP_SPEC
+/* XXX: valid only for GNU ld */
+/* XXX: should exactly match hooks provided by libmudflap.a */
+#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
+ --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
+ --wrap=mmap --wrap=munmap --wrap=alloca\
+} %{fmudflapth: --wrap=pthread_create --wrap=pthread_join --wrap=pthread_exit\
+}} %{fmudflap|fmudflapth: --wrap=main}"
+#endif
+#ifndef MFLIB_SPEC
+#define MFLIB_SPEC "%{fmudflap|fmudflapth: -export-dynamic}"
+#endif
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
%{!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*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov}\
+ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\
+ %{fprofile-arcs|fprofile-generate:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
static const char *asm_final_spec = ASM_FINAL_SPEC;
static const char *link_spec = LINK_SPEC;
static const char *lib_spec = LIB_SPEC;
+static const char *mfwrap_spec = MFWRAP_SPEC;
+static const char *mflib_spec = MFLIB_SPEC;
static const char *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
%{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
+ %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
+ %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}\
+ %{save-temps:-fpch-preprocess}";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
- %{fsyntax-only:-o %j} %{-param*}";
+ %{fsyntax-only:-o %j} %{-param*}\
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
const char *cpp_spec; /* If non-NULL, substitute this spec
for `%C', rather than the usual
cpp_spec. */
- const int combinable; /* If non-zero, compiler can deal with
+ const int combinable; /* If nonzero, compiler can deal with
multiple source files at once (IMA). */
- const int needs_preprocessing; /* If non-zero, source files need to
+ const int needs_preprocessing; /* If nonzero, source files need to
be run through a preprocessor. */
};
{".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
{".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
{".f", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0},
+ {".F", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
+ {".FPP", "#Fortran", 0, 0, 0},
+ {".f90", "#Fortran 95", 0, 0, 0}, {".f95", "#Fortran 95", 0, 0, 0},
{".fpp", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
{".FOR", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
{".r", "#Ratfor", 0, 0, 0},
/* Default prefixes to attach to command names. */
+#ifndef STANDARD_STARTFILE_PREFIX_1
+#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
+#endif
+#ifndef STANDARD_STARTFILE_PREFIX_2
+#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
+#endif
+
#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_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 = "/lib/";
-static const char *const standard_startfile_prefix_2 = "/usr/lib/";
+static const char *const standard_startfile_prefix_1
+ = STANDARD_STARTFILE_PREFIX_1;
+static const char *const standard_startfile_prefix_2
+ = STANDARD_STARTFILE_PREFIX_2;
static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
static const char *tooldir_prefix;
INIT_STATIC_SPEC ("endfile", &endfile_spec),
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
+ INIT_STATIC_SPEC ("mfwrap", &mfwrap_spec),
+ INIT_STATIC_SPEC ("mflib", &mflib_spec),
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
nstore[endp - startp] = 0;
add_prefix (&exec_prefixes, nstore, 0,
PREFIX_PRIORITY_LAST, 0, NULL, 0);
- add_prefix (&include_prefixes,
- concat (nstore, "include", NULL),
- 0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ add_prefix (&include_prefixes, nstore, 0,
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
if (*endp == 0)
break;
endp = startp = endp + 1;
&& (IS_DIR_SEPARATOR (value[len - 1])))
{
if (len == 7)
- add_prefix (&include_prefixes, "include", NULL,
+ add_prefix (&include_prefixes, "./", NULL,
PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
else
{
- char * string = xmalloc (len + 1);
-
- strncpy (string, value, len - 7);
- strcpy (string + len - 7, "include");
- add_prefix (&include_prefixes, string, NULL,
+ char *string = xmalloc (len - 6);
+ memcpy (string, value, len - 7);
+ string[len - 7] = 0;
+ add_prefix (&include_prefixes, string, NULL,
PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
}
}
PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
add_prefix (&startfile_prefixes, value, NULL,
PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
- add_prefix (&include_prefixes, concat (value, "include", NULL),
- NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ add_prefix (&include_prefixes, value, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
n_switches++;
}
break;
}
}
+void
+do_spec_path (struct prefix_list *pl, const char *option,
+ int omit_if_relative, int separate_options,
+ int only_subdir,
+ const char *dir_for_machine_suffix,
+ const char *dir_for_no_suffix)
+{
+ static size_t bufsize = 0;
+ static char *buffer;
+ int idx;
+
+ /* Used on systems which record the specified -L dirs
+ and use them to search for dynamic linking. */
+ /* Relative directories always come from -B,
+ and it is better not to use them for searching
+ at run time. In particular, stage1 loses. */
+ if (omit_if_relative
+ && !IS_ABSOLUTE_PATH (pl->prefix))
+ return;
+
+ /* Try subdirectory if there is one. */
+ if (machine_suffix && dir_for_machine_suffix)
+ {
+ if (strlen (pl->prefix) + strlen (machine_suffix)
+ >= bufsize)
+ bufsize = (strlen (pl->prefix)
+ + strlen (machine_suffix)) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ strcat (buffer, machine_suffix);
+ if (is_directory (buffer, dir_for_machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (buffer, 1, NULL);
+ do_spec_1 (dir_for_machine_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix && dir_for_no_suffix)
+ {
+ if (is_directory (pl->prefix, dir_for_no_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ do_spec_1 (dir_for_no_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+
+ if (only_subdir)
+ return;
+
+ if (machine_suffix)
+ {
+ if (is_directory (pl->prefix, machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ /* Remove slash from machine_suffix. */
+ if (strlen (machine_suffix) >= bufsize)
+ bufsize = strlen (machine_suffix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, machine_suffix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix)
+ {
+ if (is_directory (pl->prefix, "", 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ /* Remove slash from pl->prefix. */
+ if (strlen (pl->prefix) >= bufsize)
+ bufsize = strlen (pl->prefix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+}
+
/* Process the sub-spec SPEC as a portion of a larger spec.
This is like processing a whole spec except that we do
not initialize at the beginning and we do not supply a
case 'D':
{
struct prefix_list *pl = startfile_prefixes.plist;
- size_t bufsize = 100;
- char *buffer = xmalloc (bufsize);
- int idx;
for (; pl; pl = pl->next)
{
-#ifdef RELATIVE_PREFIX_NOT_LINKDIR
- /* Used on systems which record the specified -L dirs
- and use them to search for dynamic linking. */
- /* Relative directories always come from -B,
- and it is better not to use them for searching
- at run time. In particular, stage1 loses. */
- if (!IS_ABSOLUTE_PATH (pl->prefix))
- continue;
-#endif
- /* Try subdirectory if there is one. */
- if (multilib_dir != NULL
- || (pl->os_multilib && multilib_os_dir != NULL))
- {
- const char *multi_dir;
+ const char *no_suffix_multilib_dir;
- multi_dir = pl->os_multilib ? multilib_os_dir
- : multilib_dir;
- if (machine_suffix && multilib_dir)
- {
- if (strlen (pl->prefix) + strlen (machine_suffix)
- >= bufsize)
- bufsize = (strlen (pl->prefix)
- + strlen (machine_suffix)) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- strcat (buffer, machine_suffix);
- if (is_directory (buffer, multilib_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (buffer, 1, NULL);
- do_spec_1 (multilib_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, multi_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (multi_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- }
- if (machine_suffix)
- {
- if (is_directory (pl->prefix, machine_suffix, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- /* Remove slash from machine_suffix. */
- if (strlen (machine_suffix) >= bufsize)
- bufsize = strlen (machine_suffix) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, machine_suffix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, "", 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
+ no_suffix_multilib_dir = pl->os_multilib ? multilib_os_dir
+ : multilib_dir;
+ /* Do not separate options, include non-multilibbed variant. */
+ do_spec_path (pl, "-L",
+#ifdef RELATIVE_PREFIX_NOT_LINKDIR
+ 1,
+#else
+ 0,
#endif
- /* Remove slash from pl->prefix. */
- if (strlen (pl->prefix) >= bufsize)
- bufsize = strlen (pl->prefix) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
+ 0, 0, multilib_dir, no_suffix_multilib_dir);
}
- free (buffer);
}
break;
}
for (; pl; pl = pl->next)
- {
- do_spec_1 ("-isystem", 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (" ", 0, NULL);
- }
+ /* Separate options, don't include non-suffixed variant. */
+ do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
}
break;
NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
}
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_1,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_2,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ if (*standard_startfile_prefix_1)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_1, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ if (*standard_startfile_prefix_2)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
#if 0 /* Can cause surprises, and one can use -B./ instead. */
add_prefix (&startfile_prefixes, "./", NULL,
PREFIX_PRIORITY_LAST, 1, NULL, 0);
else
{
/* Since there is no compiler for this input file, assume it is a
- linker file. */
+ linker file. */
explicit_link_files[i] = 1;
infiles[i].incompiler = NULL;
}