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:
parent
bd1ef75776
commit
00dcee0c2b
7 changed files with 377 additions and 340 deletions
|
@ -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,
|
||||
|
|
|
@ -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*)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
667
gcc/gcc.c
|
@ -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)
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Add table
Reference in a new issue