re PR driver/20425 (-print-search-dirs doesn't honor mutil-os/multilib settings)

PR driver/20425
	* gcc.c (for_each_path): New function.
	(add_to_obstack, file_at_path): New functions.
	(struct file_at_path_info, struct add_to_obstack_info): New.
	(build_search_list): Rewrite using for_each_path.  Constify struct
	path_prefix pointer.  Add do_multi param.  Adjust all callers.
	(find_a_file): Similarly, but just change existing param to bool.
	(putenv_from_prefixes): Add do_multi param, make "paths" const.
	(do_spec_path): Delete.
	(struct spec_path_info): New.
	(spec_path): New function.
	(do_spec_1): Use for_each_path for %D and %I.
	(find_file): Adjust for find_a_file changes.
	(main): Search multilibs for specs.  Print multilib lib path for
	-print-search-dirs.  Likewise add multilibs to LIBRARY_PATH_ENV.
	(read_specs): Search multilibs for %include and %include_noerr.
	(is_directory): Remove second string param.  Change last param
	to a bool.  Don't use concat.  Remove SMALL_ARG_MAX test, always
	check path is a dir.  Update all callers.
	* doc/hostconfig.texi (SMALL_ARG_MAX): Remove mention.
	* system.h (SMALL_ARG_MAX): Poison.
	* config.gcc: Don't define SMALL_ARG_MAX.
	* config.host: Likewise.
	* config.build: Likewise.

From-SVN: r108635
This commit is contained in:
Alan Modra 2005-12-16 09:46:22 +00:00 committed by Alan Modra
parent bd1ef75776
commit 00dcee0c2b
7 changed files with 377 additions and 340 deletions

View File

@ -1,3 +1,30 @@
2005-12-16 Alan Modra <amodra@bigpond.net.au>
PR driver/20425
* gcc.c (for_each_path): New function.
(add_to_obstack, file_at_path): New functions.
(struct file_at_path_info, struct add_to_obstack_info): New.
(build_search_list): Rewrite using for_each_path. Constify struct
path_prefix pointer. Add do_multi param. Adjust all callers.
(find_a_file): Similarly, but just change existing param to bool.
(putenv_from_prefixes): Add do_multi param, make "paths" const.
(do_spec_path): Delete.
(struct spec_path_info): New.
(spec_path): New function.
(do_spec_1): Use for_each_path for %D and %I.
(find_file): Adjust for find_a_file changes.
(main): Search multilibs for specs. Print multilib lib path for
-print-search-dirs. Likewise add multilibs to LIBRARY_PATH_ENV.
(read_specs): Search multilibs for %include and %include_noerr.
(is_directory): Remove second string param. Change last param
to a bool. Don't use concat. Remove SMALL_ARG_MAX test, always
check path is a dir. Update all callers.
* doc/hostconfig.texi (SMALL_ARG_MAX): Remove mention.
* system.h (SMALL_ARG_MAX): Poison.
* config.gcc: Don't define SMALL_ARG_MAX.
* config.host: Likewise.
* config.build: Likewise.
2005-12-16 Paolo Bonzini <bonzini@gnu.org>
* combine.c (combine_simplify_rtx <case NOT, NEG, TRUNCATE,

View File

@ -90,15 +90,10 @@ case $build in
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
build_xm_defines="SMALL_ARG_MAX"
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-*-solaris2*)
build_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-*-sysv4*)
# Intel x86 running system V r4
build_xm_defines="SMALL_ARG_MAX"
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-*-udk*)

View File

@ -984,7 +984,6 @@ i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*)
then
tm_file="${tm_file} usegas.h"
fi
xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ptx4.h i386/ptx4-i.h"
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
@ -1115,7 +1114,6 @@ i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5
use_fixproto=yes
;;
i[34567]86-*-solaris2*)
xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h"
case ${target} in
*-*-solaris2.[0-6] | *-*-solaris2.[0-6].*)
@ -1182,7 +1180,6 @@ i[34567]86-*-sysv5*) # Intel x86 on System V Release 5
use_fixproto=yes
;;
i[34567]86-*-sysv4*) # Intel 80386's running system V.4
xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
if test x$stabs = xyes
then

View File

@ -132,17 +132,10 @@ case ${host} in
i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
host_xm_defines='FATAL_EXIT_CODE=12'
;;
i[34567]86-sequent-ptx4*)
host_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-*-solaris2*)
host_xm_defines="SMALL_ARG_MAX"
out_host_hook_obj=host-solaris.o
host_xmake_file=x-solaris
;;
i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
host_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-pc-msdosdjgpp*)
host_xm_file=i386/xm-djgpp.h
host_exeext=.exe

View File

@ -208,11 +208,6 @@ initialization when @code{collect2} is being initialized.
If defined, a C statement (sans semicolon) that performs host-dependent
initialization when a compilation driver is being initialized.
@item SMALL_ARG_MAX
Define this macro if the host system has a small limit on the total
size of an argument vector. This causes the driver to take more care
not to pass unnecessary arguments to subprocesses.
@item HOST_LONG_LONG_FORMAT
If defined, the string used to indicate an argument of type @code{long
long} to functions like @code{printf}. The default value is

667
gcc/gcc.c
View File

@ -287,10 +287,12 @@ static char *load_specs (const char *);
static void read_specs (const char *, int);
static void set_spec (const char *, const char *);
static struct compiler *lookup_compiler (const char *, size_t, const char *);
static char *build_search_list (struct path_prefix *, const char *, int);
static void putenv_from_prefixes (struct path_prefix *, const char *);
static char *build_search_list (const struct path_prefix *, const char *,
bool, bool);
static void putenv_from_prefixes (const struct path_prefix *, const char *,
bool);
static int access_check (const char *, int);
static char *find_a_file (struct path_prefix *, const char *, int, int);
static char *find_a_file (const struct path_prefix *, const char *, int, bool);
static void add_prefix (struct path_prefix *, const char *, const char *,
int, int, int);
static void add_sysrooted_prefix (struct path_prefix *, const char *,
@ -313,13 +315,12 @@ static const char *eval_spec_function (const char *, const char *);
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 *);
static void do_self_spec (const char *);
static const char *find_file (const char *);
static int is_directory (const char *, const char *, int);
static int is_directory (const char *, bool);
static const char *validate_switches (const char *);
static void validate_all_switches (void);
static inline void validate_switches_from_spec (const char *);
@ -2041,7 +2042,7 @@ read_specs (const char *filename, int main_p)
(long) (p1 - buffer + 1));
p[-2] = '\0';
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
read_specs (new_filename ? new_filename : p1, FALSE);
continue;
}
@ -2060,7 +2061,7 @@ read_specs (const char *filename, int main_p)
(long) (p1 - buffer + 1));
p[-2] = '\0';
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
if (new_filename)
read_specs (new_filename, FALSE);
else if (verbose_flag)
@ -2357,64 +2358,213 @@ clear_failure_queue (void)
failure_delete_queue = 0;
}
/* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
returns non-NULL.
If DO_MULTI is true iterate over the paths twice, first with multilib
suffix then without, otherwise iterate over the paths once without
adding a multilib suffix. When DO_MULTI is true, some attempt is made
to avoid visiting the same path twice, but we could do better. For
instance, /usr/lib/../lib is considered different from /usr/lib.
At least EXTRA_SPACE chars past the end of the path passed to
CALLBACK are available for use by the callback.
CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
Returns the value returned by CALLBACK. */
static void *
for_each_path (const struct path_prefix *paths,
bool do_multi,
size_t extra_space,
void *(*callback) (char *, void *),
void *callback_info)
{
struct prefix_list *pl;
const char *multi_dir = NULL;
const char *multi_os_dir = NULL;
const char *multi_suffix;
const char *just_multi_suffix;
char *path = NULL;
void *ret = NULL;
bool skip_multi_dir = false;
bool skip_multi_os_dir = false;
multi_suffix = machine_suffix;
just_multi_suffix = just_machine_suffix;
if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
{
multi_dir = concat (multilib_dir, dir_separator_str, NULL);
multi_suffix = concat (multi_suffix, multi_dir, NULL);
just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
}
if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
while (1)
{
size_t multi_dir_len = 0;
size_t multi_os_dir_len = 0;
size_t suffix_len;
size_t just_suffix_len;
size_t len;
if (multi_dir)
multi_dir_len = strlen (multi_dir);
if (multi_os_dir)
multi_os_dir_len = strlen (multi_os_dir);
suffix_len = strlen (multi_suffix);
just_suffix_len = strlen (just_multi_suffix);
if (path == NULL)
{
len = paths->max_len + extra_space + 1;
if (suffix_len > multi_os_dir_len)
len += suffix_len;
else
len += multi_os_dir_len;
path = xmalloc (len);
}
for (pl = paths->plist; pl != 0; pl = pl->next)
{
len = strlen (pl->prefix);
memcpy (path, pl->prefix, len);
/* Look first in MACHINE/VERSION subdirectory. */
if (!skip_multi_dir)
{
memcpy (path + len, multi_suffix, suffix_len + 1);
ret = callback (path, callback_info);
if (ret)
break;
}
/* Some paths are tried with just the machine (ie. target)
subdir. This is used for finding as, ld, etc. */
if (!skip_multi_dir
&& pl->require_machine_suffix == 2)
{
memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
ret = callback (path, callback_info);
if (ret)
break;
}
/* Now try the base path. */
if (!pl->require_machine_suffix
&& !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
{
const char *this_multi;
size_t this_multi_len;
if (pl->os_multilib)
{
this_multi = multi_os_dir;
this_multi_len = multi_os_dir_len;
}
else
{
this_multi = multi_dir;
this_multi_len = multi_dir_len;
}
if (this_multi_len)
memcpy (path + len, this_multi, this_multi_len + 1);
else
path[len] = '\0';
ret = callback (path, callback_info);
if (ret)
break;
}
}
if (pl)
break;
if (multi_dir == NULL && multi_os_dir == NULL)
break;
/* Run through the paths again, this time without multilibs.
Don't repeat any we have already seen. */
if (multi_dir)
{
free ((char *) multi_dir);
multi_dir = NULL;
free ((char *) multi_suffix);
multi_suffix = machine_suffix;
free ((char *) just_multi_suffix);
just_multi_suffix = just_machine_suffix;
}
else
skip_multi_dir = true;
if (multi_os_dir)
{
free ((char *) multi_os_dir);
multi_os_dir = NULL;
}
else
skip_multi_os_dir = true;
}
if (multi_dir)
{
free ((char *) multi_dir);
free ((char *) multi_suffix);
free ((char *) just_multi_suffix);
}
if (multi_os_dir)
free ((char *) multi_os_dir);
if (ret != path)
free (path);
return ret;
}
/* Callback for build_search_list. Adds path to obstack being built. */
struct add_to_obstack_info {
struct obstack *ob;
bool check_dir;
bool first_time;
};
static void *
add_to_obstack (char *path, void *data)
{
struct add_to_obstack_info *info = data;
if (info->check_dir && !is_directory (path, false))
return NULL;
if (!info->first_time)
obstack_1grow (info->ob, PATH_SEPARATOR);
obstack_grow (info->ob, path, strlen (path));
info->first_time = false;
return NULL;
}
/* Build a list of search directories from PATHS.
PREFIX is a string to prepend to the list.
If CHECK_DIR_P is nonzero we ensure the directory exists.
If CHECK_DIR_P is true we ensure the directory exists.
If DO_MULTI is true, multilib paths are output first, then
non-multilib paths.
This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
It is also used by the --print-search-dirs flag. */
static char *
build_search_list (struct path_prefix *paths, const char *prefix,
int check_dir_p)
build_search_list (const struct path_prefix *paths, const char *prefix,
bool check_dir, bool do_multi)
{
int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
int just_suffix_len
= (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
int first_time = TRUE;
struct prefix_list *pprefix;
struct add_to_obstack_info info;
info.ob = &collect_obstack;
info.check_dir = check_dir;
info.first_time = true;
obstack_grow (&collect_obstack, prefix, strlen (prefix));
obstack_1grow (&collect_obstack, '=');
for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
{
int len = strlen (pprefix->prefix);
if (machine_suffix
&& (! check_dir_p
|| is_directory (pprefix->prefix, machine_suffix, 0)))
{
if (!first_time)
obstack_1grow (&collect_obstack, PATH_SEPARATOR);
first_time = FALSE;
obstack_grow (&collect_obstack, pprefix->prefix, len);
obstack_grow (&collect_obstack, machine_suffix, suffix_len);
}
if (just_machine_suffix
&& pprefix->require_machine_suffix == 2
&& (! check_dir_p
|| is_directory (pprefix->prefix, just_machine_suffix, 0)))
{
if (! first_time)
obstack_1grow (&collect_obstack, PATH_SEPARATOR);
first_time = FALSE;
obstack_grow (&collect_obstack, pprefix->prefix, len);
obstack_grow (&collect_obstack, just_machine_suffix,
just_suffix_len);
}
if (! pprefix->require_machine_suffix)
{
if (! first_time)
obstack_1grow (&collect_obstack, PATH_SEPARATOR);
first_time = FALSE;
obstack_grow (&collect_obstack, pprefix->prefix, len);
}
}
for_each_path (paths, do_multi, 0, add_to_obstack, &info);
obstack_1grow (&collect_obstack, '\0');
return XOBFINISH (&collect_obstack, char *);
@ -2424,9 +2574,10 @@ build_search_list (struct path_prefix *paths, const char *prefix,
for collect. */
static void
putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
bool do_multi)
{
putenv (build_search_list (paths, env_var, 1));
putenv (build_search_list (paths, env_var, true, do_multi));
}
/* Check whether NAME can be accessed in MODE. This is like access,
@ -2447,20 +2598,53 @@ access_check (const char *name, int mode)
return access (name, mode);
}
/* Callback for find_a_file. Appends the file name to the directory
path. If the resulting file exists in the right mode, return the
full pathname to the file. */
struct file_at_path_info {
const char *name;
const char *suffix;
int name_len;
int suffix_len;
int mode;
};
static void *
file_at_path (char *path, void *data)
{
struct file_at_path_info *info = data;
size_t len = strlen (path);
memcpy (path + len, info->name, info->name_len);
len += info->name_len;
/* Some systems have a suffix for executable files.
So try appending that first. */
if (info->suffix_len)
{
memcpy (path + len, info->suffix, info->suffix_len + 1);
if (access_check (path, info->mode) == 0)
return path;
}
path[len] = '\0';
if (access_check (path, info->mode) == 0)
return path;
return NULL;
}
/* Search for NAME using the prefix list PREFIXES. MODE is passed to
access to check permissions.
access to check permissions. If DO_MULTI is true, search multilib
paths then non-multilib paths, otherwise do not search multilib paths.
Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
find_a_file (struct path_prefix *pprefix, const char *name, int mode,
int multilib)
find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
bool do_multi)
{
char *temp;
const char *const file_suffix =
((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
struct prefix_list *pl;
int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
const char *multilib_name, *multilib_os_name;
struct file_at_path_info info;
#ifdef DEFAULT_ASSEMBLER
if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
@ -2472,112 +2656,24 @@ find_a_file (struct path_prefix *pprefix, const char *name, int mode,
return xstrdup (DEFAULT_LINKER);
#endif
if (machine_suffix)
len += strlen (machine_suffix);
multilib_name = name;
multilib_os_name = name;
if (multilib && multilib_os_dir)
{
int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
int len2 = strlen (multilib_os_dir) + 1;
len += len1 > len2 ? len1 : len2;
if (multilib_dir)
multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
NULL));
if (strcmp (multilib_os_dir, ".") != 0)
multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
NULL));
}
temp = xmalloc (len);
/* Determine the filename to execute (special case for absolute paths). */
if (IS_ABSOLUTE_PATH (name))
{
if (access (name, mode) == 0)
{
strcpy (temp, name);
return temp;
}
return xstrdup (name);
return NULL;
}
else
for (pl = pprefix->plist; pl; pl = pl->next)
{
const char *this_name
= pl->os_multilib ? multilib_os_name : multilib_name;
if (machine_suffix)
{
/* Some systems have a suffix for executable files.
So try appending that first. */
if (file_suffix[0] != 0)
{
strcpy (temp, pl->prefix);
strcat (temp, machine_suffix);
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
return temp;
}
info.name = name;
info.suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
info.name_len = strlen (info.name);
info.suffix_len = strlen (info.suffix);
info.mode = mode;
/* Now try just the multilib_name. */
strcpy (temp, pl->prefix);
strcat (temp, machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
return temp;
}
/* Certain prefixes are tried with just the machine type,
not the version. This is used for finding as, ld, etc. */
if (just_machine_suffix && pl->require_machine_suffix == 2)
{
/* Some systems have a suffix for executable files.
So try appending that first. */
if (file_suffix[0] != 0)
{
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
return temp;
}
/* Certain prefixes can't be used without the machine suffix
when the machine or version is explicitly specified. */
if (! pl->require_machine_suffix)
{
/* Some systems have a suffix for executable files.
So try appending that first. */
if (file_suffix[0] != 0)
{
strcpy (temp, pl->prefix);
strcat (temp, this_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, this_name);
if (access_check (temp, mode) == 0)
return temp;
}
}
free (temp);
return 0;
return for_each_path (pprefix, do_multi, info.name_len + info.suffix_len,
file_at_path, &info);
}
/* Ranking of prefixes in the sort list. -B prefixes are put before
@ -2696,7 +2792,7 @@ execute (void)
commands[0].prog = argbuf[0]; /* first command. */
commands[0].argv = &argbuf[0];
string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, false);
if (string)
commands[0].argv[0] = string;
@ -2711,7 +2807,7 @@ execute (void)
commands[n_commands].prog = argbuf[i + 1];
commands[n_commands].argv = &argbuf[i + 1];
string = find_a_file (&exec_prefixes, commands[n_commands].prog,
X_OK, 0);
X_OK, false);
if (string)
commands[n_commands].argv[0] = string;
n_commands++;
@ -3649,7 +3745,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
if appending a directory separator actually makes a
valid directory name. */
if (! IS_DIR_SEPARATOR (value [len - 1])
&& is_directory (value, "", 0))
&& is_directory (value, false))
{
char *tmp = xmalloc (len + 2);
strcpy (tmp, value);
@ -4397,108 +4493,55 @@ do_self_spec (const char *spec)
}
}
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)
/* Callback for processing %D and %I specs. */
struct spec_path_info {
const char *option;
const char *append;
size_t append_len;
bool omit_relative;
bool separate_options;
};
static void *
spec_path (char *path, void *data)
{
static size_t bufsize = 0;
static char *buffer;
int idx;
bool multilib_p = false;
struct spec_path_info *info = data;
size_t len = 0;
char save = 0;
/* 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;
if (info->omit_relative && !IS_ABSOLUTE_PATH (path))
return NULL;
/* Try subdirectory if there is one. */
if (machine_suffix && dir_for_machine_suffix)
if (info->append_len != 0)
{
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))
{
multilib_p = true;
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))
{
multilib_p = true;
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);
}
len = strlen (path);
memcpy (path + len, info->append, info->append_len + 1);
}
if (only_subdir || multilib_p)
return;
if (!is_directory (path, true))
return NULL;
if (machine_suffix)
do_spec_1 (info->option, 1, NULL);
if (info->separate_options)
do_spec_1 (" ", 0, NULL);
if (info->append_len == 0)
{
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);
}
len = strlen (path);
save = path[len - 1];
if (IS_DIR_SEPARATOR (path[len - 1]))
path[len - 1] = '\0';
}
do_spec_1 (path, 1, NULL);
do_spec_1 (" ", 0, NULL);
/* Must not damage the original path. */
if (info->append_len == 0)
path[len - 1] = save;
return NULL;
}
/* Process the sub-spec SPEC as a portion of a larger spec.
@ -4636,23 +4679,23 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
that we search for startfiles. */
case 'D':
{
struct prefix_list *pl = startfile_prefixes.plist;
struct spec_path_info info;
for (; pl; pl = pl->next)
{
const char *no_suffix_multilib_dir;
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",
info.option = "-L";
info.append_len = 0;
#ifdef RELATIVE_PREFIX_NOT_LINKDIR
1,
/* 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. */
info.omit_relative = true;
#else
0,
info.omit_relative = false;
#endif
0, 0, multilib_dir, no_suffix_multilib_dir);
}
info.separate_options = false;
for_each_path (&startfile_prefixes, true, 0, spec_path, &info);
}
break;
@ -4889,7 +4932,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
case 'I':
{
struct prefix_list *pl = include_prefixes.plist;
struct spec_path_info info;
if (gcc_exec_prefix)
{
@ -4912,9 +4955,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
do_spec_1 (" ", 0, NULL);
}
for (; pl; pl = pl->next)
/* Separate options, don't include non-suffixed variant. */
do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
info.option = "-isystem";
info.append = "include";
info.append_len = strlen (info.append);
info.omit_relative = false;
info.separate_options = true;
for_each_path (&include_prefixes, false, info.append_len,
spec_path, &info);
}
break;
@ -5900,48 +5948,27 @@ give_switch (int switchnum, int omit_first_word)
static const char *
find_file (const char *name)
{
char *newname;
/* Try multilib_dir if it is defined. */
if (multilib_os_dir != NULL)
{
newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
/* If we don't find it in the multi library dir, then fall
through and look for it in the normal places. */
if (newname != NULL)
return newname;
}
newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
return newname ? newname : name;
}
/* Determine whether a directory exists. If LINKER, return 0 for
certain fixed names not needed by the linker. If not LINKER, it is
only important to return 0 if the host machine has a small ARG_MAX
limit. */
certain fixed names not needed by the linker. */
static int
is_directory (const char *path1, const char *path2, int linker)
is_directory (const char *path1, bool linker)
{
int len1 = strlen (path1);
int len2 = strlen (path2);
char *path = alloca (3 + len1 + len2);
int len1;
char *path;
char *cp;
struct stat st;
#ifndef SMALL_ARG_MAX
if (! linker)
return 1;
#endif
/* Construct the path from the two parts. Ensure the string ends with "/.".
The resulting path will be a directory even if the given path is a
symbolic link. */
/* Ensure the string ends with "/.". The resulting path will be a
directory even if the given path is a symbolic link. */
len1 = strlen (path1);
path = alloca (3 + len1);
memcpy (path, path1, len1);
memcpy (path + len1, path2, len2);
cp = path + len1 + len2;
cp = path + len1;
if (!IS_DIR_SEPARATOR (cp[-1]))
*cp++ = DIR_SEPARATOR;
*cp++ = '.';
@ -5949,13 +5976,13 @@ is_directory (const char *path1, const char *path2, int linker)
/* Exclude directories that the linker is known to search. */
if (linker
&& IS_DIR_SEPARATOR (path[0])
&& ((cp - path == 6
&& strcmp (path, concat (dir_separator_str, "lib",
dir_separator_str, ".", NULL)) == 0)
&& strncmp (path + 1, "lib", 3) == 0)
|| (cp - path == 10
&& strcmp (path, concat (dir_separator_str, "usr",
dir_separator_str, "lib",
dir_separator_str, ".", NULL)) == 0)))
&& strncmp (path + 1, "usr", 3) == 0
&& IS_DIR_SEPARATOR (path[4])
&& strncmp (path + 5, "lib", 3) == 0)))
return 0;
return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
@ -6147,7 +6174,7 @@ main (int argc, char **argv)
spec_version, dir_separator_str, NULL);
just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
/* Read the specs file unless it is a default one. */
if (specs_file != 0 && strcmp (specs_file, "specs"))
read_specs (specs_file, TRUE);
@ -6283,7 +6310,7 @@ main (int argc, char **argv)
for (uptr = user_specs_head; uptr; uptr = uptr->next)
{
char *filename = find_a_file (&startfile_prefixes, uptr->filename,
R_OK, 0);
R_OK, true);
read_specs (filename ? filename : uptr->filename, FALSE);
}
@ -6312,8 +6339,10 @@ main (int argc, char **argv)
if (print_search_dirs)
{
printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
printf (_("programs: %s\n"),
build_search_list (&exec_prefixes, "", false, false));
printf (_("libraries: %s\n"),
build_search_list (&startfile_prefixes, "", false, true));
return (0);
}
@ -6630,14 +6659,14 @@ main (int argc, char **argv)
/* 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, 0);
char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
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");
putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV);
putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
value = do_spec (link_command_spec);
if (value < 0)

View File

@ -730,7 +730,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC \
PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF \
EXTRA_SECTIONS EXTRA_SECTION_FUNCTIONS READONLY_DATA_SECTION \
TARGET_ASM_EXCEPTION_SECTION TARGET_ASM_EH_FRAME_SECTION
TARGET_ASM_EXCEPTION_SECTION TARGET_ASM_EH_FRAME_SECTION \
SMALL_ARG_MAX
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \