source: scripts/patches/gcc-4.1.0-fix_PR20425.patch@ 75bc092

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 75bc092 was ad31873f, checked in by Jim Gifford <clfs@…>, 19 years ago

r2539@server (orig r1260): ryan | 2006-03-10 06:07:41 -0800

r1336@rei: lfs | 2006-03-11 01:06:05 +1100
Add GCC PR20425 fixes to 4.1.0 release.
This fixes a multitude of sins, most noticably with libtool on multilib systems.
Iterative path searches the gcc driver performs should now search multilib directories first.


Submitted By: Ryan Oliver <ryan at pha dot com dot au>
Date: 2006-03-10
Initial Package Version: 4.1.0
Origin: GCC SVN Revision 108635 (diffed against 4.1.0 release)
Upstream Status: In GCC trunk
Description: Fix for PR20425


From http://gcc.gnu.org/ml/gcc-patches/2005-12/msg00818.html
---------------------------------8<------------------------------------
This gives the gcc driver a new path iteration function, for_each_path,
and uses it everywhere, making path iteration a little more consistent.
for_each_path uses the same path ordering as the existing find_file
function. I've also tweaked some of the existing find_a_file calls for
consistency, and uncovered and fixed some other bugs..


Functional changes are:


o %D library paths are printed in the same order as gcc uses elsewhere

when searching library directories, ie. all multilib paths are first.
http://gcc.gnu.org/ml/gcc-patches/2005-03/msg02044.html effectively
reverted by the rewrite because I believe the same speedup is gained
by searching the right dirs first.


o gcc -print-search-dirs prints library multilib paths followed by

non-multilib paths where before we just printed non-multilib paths.


o LIBRARY_PATH_ENV similarly includes multilib directories.


o All searches of startfile_prefixes now look in multilib dirs first

followed by non-multilib dirs. This changes the dirs we search for
spec files, and %include and %include_noerr in specs. Previously
we only searched the non-multilib dirs for specs files. I think this
change is worthwhile just for consistency, and the extension is
reasonable. For instance, it would allow different spec files to be
used for gcc -m64 vs. gcc -m32. However, if others think this wrong,
I won't argue. Consistency isn't everything.


o Some attempt made to prevent searching of duplicate paths. The old

find_file would search some paths twice (when multilib_dir was NULL
but multilib_os_dir non-NULL). We still search twice in some cases,
eg. /usr/lib/../lib and /usr/lib are considered different paths.


o find_a_file with last param (do_multi) true now searches both

multilib and non-multilib paths. Before, do_multi (well, the old
param name was multilib) meant just search multilib paths. This
isn't a user-visible change as the only place where find_a_file was
invoked with the last param true was from find_file, where we
immediately followed with a non-multilib find_a_file.


o Memory leaks fixed in is_directory.


o LIBRARY_PATH_ENV and COMPILER_PATH now only have existing

directories, making LIBRARY_PATH_ENV closer to %D paths. The
following lines (which I remove) in is_directory meant that
is_directory didn't do much for LIBRARY_PATH_ENV, except on
SMALL_ARG_MAX machines.


4278 ian #ifndef SMALL_ARG_MAX
4278 ian if (! linker)
4278 ian return 1;
4278 ian #endif


I'll also remove mention of SMALL_ARG_MAX in config and doc files
when I commit this change as this is the only place it is used.


o gcc -Bnon-dir-prefix- now works properly. The previously mentioned

is_directory peculiarity affected the following code.


43664 nickc /* Catch the case where the user has forgotten to append a
46063 jsm28 directory separator to the path. Note, they may be using
43664 nickc -B to add an executable name prefix, eg "i386-elf-", in
43664 nickc order to distinguish between multiple installations of
43664 nickc GCC in the same directory. Hence we must check to see
43664 nickc if appending a directory separator actually makes a
43664 nickc valid directory name. */
43664 nickc if (! IS_DIR_SEPARATOR (value [len - 1])
43664 nickc && is_directory (value, "", 0))
43664 nickc {
43767 ghazi char *tmp = xmalloc (len + 2);
43767 ghazi strcpy (tmp, value);
43767 ghazi tmp[len] = DIR_SEPARATOR;
43767 ghazi tmp[++ len] = 0;
43767 ghazi value = tmp;
43664 nickc }


Bootstrapped and regression tested powerpc64-linux and powerpc-linux on
a previous iteration of this patch missing is_directory fixes.
Currently running tests on this patch.



  • Property mode set to 100644
File size: 36.4 KB
  • gcc/ChangeLog

    Submitted By: Ryan Oliver <ryan at pha dot com dot au>
    Date: 2006-03-10
    Initial Package Version: 4.1.0
    Origin: GCC SVN Revision 108635 (diffed against 4.1.0 release)
    Upstream Status: In GCC trunk
    Description: Fix for PR20425
    
    From http://gcc.gnu.org/ml/gcc-patches/2005-12/msg00818.html
    ---------------------------------8<------------------------------------
    This gives the gcc driver a new path iteration function, for_each_path,
    and uses it everywhere, making path iteration a little more consistent.
    for_each_path uses the same path ordering as the existing find_file
    function.  I've also tweaked some of the existing find_a_file calls for
    consistency, and uncovered and fixed some other bugs..
    
    Functional changes are:
    
    o  %D library paths are printed in the same order as gcc uses elsewhere
       when searching library directories, ie. all multilib paths are first.
       http://gcc.gnu.org/ml/gcc-patches/2005-03/msg02044.html effectively
       reverted by the rewrite because I believe the same speedup is gained
       by searching the right dirs first.
    
    o  gcc -print-search-dirs prints library multilib paths followed by
       non-multilib paths where before we just printed non-multilib paths.
    
    o  LIBRARY_PATH_ENV similarly includes multilib directories.
    
    o  All searches of startfile_prefixes now look in multilib dirs first
       followed by non-multilib dirs.  This changes the dirs we search for
       spec files, and %include and %include_noerr in specs.  Previously
       we only searched the non-multilib dirs for specs files.  I think this
       change is worthwhile just for consistency, and the extension is
       reasonable.  For instance, it would allow different spec files to be
       used for gcc -m64 vs. gcc -m32.  However, if others think this wrong,
       I won't argue.  Consistency isn't everything.
    
    o  Some attempt made to prevent searching of duplicate paths.  The old
       find_file would search some paths twice (when multilib_dir was NULL
       but multilib_os_dir non-NULL).  We still search twice in some cases,
       eg. /usr/lib/../lib and /usr/lib are considered different paths.
    
    o  find_a_file with last param (do_multi) true now searches both
       multilib and non-multilib paths.  Before, do_multi (well, the old
       param name was multilib) meant just search multilib paths.  This
       isn't a user-visible change as the only place where find_a_file was
       invoked with the last param true was from find_file, where we
       immediately followed with a non-multilib find_a_file.
    
    o  Memory leaks fixed in is_directory.
    
    o  LIBRARY_PATH_ENV and COMPILER_PATH now only have existing
       directories, making LIBRARY_PATH_ENV closer to %D paths.  The
       following lines (which I remove) in is_directory meant that
       is_directory didn't do much for LIBRARY_PATH_ENV, except on
       SMALL_ARG_MAX machines.
    
      4278        ian #ifndef SMALL_ARG_MAX
      4278        ian   if (! linker)
      4278        ian     return 1;
      4278        ian #endif
    
       I'll also remove mention of SMALL_ARG_MAX in config and doc files
       when I commit this change as this is the only place it is used.
    
    o  gcc -Bnon-dir-prefix- now works properly.  The previously mentioned
       is_directory peculiarity affected the following code.
    
     43664      nickc /* Catch the case where the user has forgotten to append a
     46063      jsm28    directory separator to the path.  Note, they may be using
     43664      nickc    -B to add an executable name prefix, eg "i386-elf-", in
     43664      nickc    order to distinguish between multiple installations of
     43664      nickc    GCC in the same directory.  Hence we must check to see
     43664      nickc    if appending a directory separator actually makes a
     43664      nickc    valid directory name.  */
     43664      nickc if (! IS_DIR_SEPARATOR (value [len - 1])
     43664      nickc     && is_directory (value, "", 0))
     43664      nickc   {
     43767      ghazi     char *tmp = xmalloc (len + 2);
     43767      ghazi     strcpy (tmp, value);
     43767      ghazi     tmp[len] = DIR_SEPARATOR;
     43767      ghazi     tmp[++ len] = 0;
     43767      ghazi     value = tmp;
     43664      nickc   }
    
    Bootstrapped and regression tested powerpc64-linux and powerpc-linux on
    a previous iteration of this patch missing is_directory fixes.
    Currently running tests on this patch.
    ---------------------------------8<------------------------------------
    
    diff -uNr gcc-4.1.0/gcc/ChangeLog gcc-4.1.0-PR20425/gcc/ChangeLog
    old new  
     12006-03-10  Ryan Oliver <ryan@linuxfromscratch.org>
     2        Backport:
     3        2005-12-16  Alan Modra  <amodra@bigpond.net.au>
     4        PR driver/20425
     5        * gcc.c (for_each_path): New function.
     6        (add_to_obstack, file_at_path): New functions.
     7        (struct file_at_path_info, struct add_to_obstack_info): New.
     8        (build_search_list): Rewrite using for_each_path.  Constify struct
     9        path_prefix pointer.  Add do_multi param.  Adjust all callers.
     10        (find_a_file): Similarly, but just change existing param to bool.
     11        (putenv_from_prefixes): Add do_multi param, make "paths" const.
     12        (do_spec_path): Delete.
     13        (struct spec_path_info): New.
     14        (spec_path): New function.
     15        (do_spec_1): Use for_each_path for %D and %I.
     16        (find_file): Adjust for find_a_file changes.
     17        (main): Search multilibs for specs.  Print multilib lib path for
     18        -print-search-dirs.  Likewise add multilibs to LIBRARY_PATH_ENV.
     19        (read_specs): Search multilibs for %include and %include_noerr.
     20        (is_directory): Remove second string param.  Change last param
     21        to a bool.  Don't use concat.  Remove SMALL_ARG_MAX test, always
     22        check path is a dir.  Update all callers.
     23        * doc/hostconfig.texi (SMALL_ARG_MAX): Remove mention.
     24        * system.h (SMALL_ARG_MAX): Poison.
     25        * config.gcc: Don't define SMALL_ARG_MAX.
     26        * config.host: Likewise.
     27        * config.build: Likewise.
     28
    1292006-02-28  Release Manager
    230
    331        * GCC 4.1.0 released.
  • gcc/config.build

    diff -uNr gcc-4.1.0/gcc/config.build gcc-4.1.0-PR20425/gcc/config.build
    old new  
    9090    build_install_headers_dir=install-headers-cpio
    9191    ;;
    9292  i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
    93     build_xm_defines="SMALL_ARG_MAX"
    9493    build_install_headers_dir=install-headers-cpio
    9594    ;;
    96   i[34567]86-*-solaris2*)
    97     build_xm_defines="SMALL_ARG_MAX"
    98     ;;
    9995  i[34567]86-*-sysv4*)
    10096    # Intel x86 running system V r4
    101     build_xm_defines="SMALL_ARG_MAX"
    10297    build_install_headers_dir=install-headers-cpio
    10398    ;;
    10499  i[34567]86-*-udk*)
  • gcc/config.gcc

    diff -uNr gcc-4.1.0/gcc/config.gcc gcc-4.1.0-PR20425/gcc/config.gcc
    old new  
    994994        then
    995995                tm_file="${tm_file} usegas.h"
    996996        fi
    997         xm_defines="SMALL_ARG_MAX"
    998997        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ptx4.h i386/ptx4-i.h"
    999998        tmake_file=t-svr4
    1000999        extra_parts="crtbegin.o crtend.o"
     
    11251124        use_fixproto=yes
    11261125        ;;
    11271126i[34567]86-*-solaris2*)
    1128         xm_defines="SMALL_ARG_MAX"
    11291127        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h"
    11301128        case ${target} in
    11311129        *-*-solaris2.[0-6] | *-*-solaris2.[0-6].*)
     
    11921190        use_fixproto=yes
    11931191       ;;
    11941192i[34567]86-*-sysv4*)            # Intel 80386's running system V.4
    1195         xm_defines="SMALL_ARG_MAX"
    11961193        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
    11971194        if test x$stabs = xyes
    11981195        then
  • gcc/config.host

    diff -uNr gcc-4.1.0/gcc/config.host gcc-4.1.0-PR20425/gcc/config.host
    old new  
    135135  i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
    136136    host_xm_defines='FATAL_EXIT_CODE=12'
    137137    ;;
    138   i[34567]86-sequent-ptx4*)
    139     host_xm_defines="SMALL_ARG_MAX"
    140     ;;
    141138  i[34567]86-*-solaris2*)
    142     host_xm_defines="SMALL_ARG_MAX"
    143139    out_host_hook_obj=host-solaris.o
    144140    host_xmake_file=x-solaris
    145141    ;;
    146   i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
    147     host_xm_defines="SMALL_ARG_MAX"
    148     ;;
    149142  i[34567]86-pc-msdosdjgpp*)
    150143    host_xm_file=i386/xm-djgpp.h
    151144    host_exeext=.exe
  • gcc/doc/hostconfig.texi

    diff -uNr gcc-4.1.0/gcc/doc/hostconfig.texi gcc-4.1.0-PR20425/gcc/doc/hostconfig.texi
    old new  
    208208If defined, a C statement (sans semicolon) that performs host-dependent
    209209initialization when a compilation driver is being initialized.
    210210
    211 @item SMALL_ARG_MAX
    212 Define this macro if the host system has a small limit on the total
    213 size of an argument vector.  This causes the driver to take more care
    214 not to pass unnecessary arguments to subprocesses.
    215 
    216211@item HOST_LONG_LONG_FORMAT
    217212If defined, the string used to indicate an argument of type @code{long
    218213long} to functions like @code{printf}.  The default value is
  • gcc/gcc.c

    diff -uNr gcc-4.1.0/gcc/gcc.c gcc-4.1.0-PR20425/gcc/gcc.c
    old new  
    287287static void read_specs (const char *, int);
    288288static void set_spec (const char *, const char *);
    289289static struct compiler *lookup_compiler (const char *, size_t, const char *);
    290 static char *build_search_list (struct path_prefix *, const char *, int);
    291 static void putenv_from_prefixes (struct path_prefix *, const char *);
     290static char *build_search_list (const struct path_prefix *, const char *,
     291                                bool, bool);
     292static void putenv_from_prefixes (const struct path_prefix *, const char *,
     293                                  bool);
    292294static int access_check (const char *, int);
    293 static char *find_a_file (struct path_prefix *, const char *, int, int);
     295static char *find_a_file (const struct path_prefix *, const char *, int, bool);
    294296static void add_prefix (struct path_prefix *, const char *, const char *,
    295297                        int, int, int);
    296298static void add_sysrooted_prefix (struct path_prefix *, const char *,
     
    313315static const char *handle_spec_function (const char *);
    314316static char *save_string (const char *, int);
    315317static void set_collect_gcc_options (void);
    316 static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);
    317318static int do_spec_1 (const char *, int, const char *);
    318319static int do_spec_2 (const char *);
    319320static void do_option_spec (const char *, const char *);
    320321static void do_self_spec (const char *);
    321322static const char *find_file (const char *);
    322 static int is_directory (const char *, const char *, int);
     323static int is_directory (const char *, bool);
    323324static const char *validate_switches (const char *);
    324325static void validate_all_switches (void);
    325326static inline void validate_switches_from_spec (const char *);
     
    20362037                       (long) (p1 - buffer + 1));
    20372038
    20382039              p[-2] = '\0';
    2039               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
     2040              new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    20402041              read_specs (new_filename ? new_filename : p1, FALSE);
    20412042              continue;
    20422043            }
     
    20552056                       (long) (p1 - buffer + 1));
    20562057
    20572058              p[-2] = '\0';
    2058               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
     2059              new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    20592060              if (new_filename)
    20602061                read_specs (new_filename, FALSE);
    20612062              else if (verbose_flag)
     
    23522353  failure_delete_queue = 0;
    23532354}
    23542355
    23552356
    2356 /* Build a list of search directories from PATHS.
    2357    PREFIX is a string to prepend to the list.
    2358    If CHECK_DIR_P is nonzero we ensure the directory exists.
    2359    This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
    2360    It is also used by the --print-search-dirs flag.  */
    2361 
    2362 static char *
    2363 build_search_list (struct path_prefix *paths, const char *prefix,
    2364                    int check_dir_p)
     2357/* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
     2358   returns non-NULL.
     2359   If DO_MULTI is true iterate over the paths twice, first with multilib
     2360   suffix then without, otherwise iterate over the paths once without
     2361   adding a multilib suffix.  When DO_MULTI is true, some attempt is made
     2362   to avoid visiting the same path twice, but we could do better.  For
     2363   instance, /usr/lib/../lib is considered different from /usr/lib.
     2364   At least EXTRA_SPACE chars past the end of the path passed to
     2365   CALLBACK are available for use by the callback.
     2366   CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
     2367
     2368   Returns the value returned by CALLBACK.  */
     2369
     2370static void *
     2371for_each_path (const struct path_prefix *paths,
     2372               bool do_multi,
     2373               size_t extra_space,
     2374               void *(*callback) (char *, void *),
     2375               void *callback_info)
    23652376{
    2366   int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
    2367   int just_suffix_len
    2368     = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
    2369   int first_time = TRUE;
    2370   struct prefix_list *pprefix;
    2371 
    2372   obstack_grow (&collect_obstack, prefix, strlen (prefix));
    2373   obstack_1grow (&collect_obstack, '=');
     2377  struct prefix_list *pl;
     2378  const char *multi_dir = NULL;
     2379  const char *multi_os_dir = NULL;
     2380  const char *multi_suffix;
     2381  const char *just_multi_suffix;
     2382  char *path = NULL;
     2383  void *ret = NULL;
     2384  bool skip_multi_dir = false;
     2385  bool skip_multi_os_dir = false;
     2386
     2387  multi_suffix = machine_suffix;
     2388  just_multi_suffix = just_machine_suffix;
     2389  if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
     2390    {
     2391      multi_dir = concat (multilib_dir, dir_separator_str, NULL);
     2392      multi_suffix = concat (multi_suffix, multi_dir, NULL);
     2393      just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
     2394    }
     2395  if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
     2396    multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
    23742397
    2375   for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
     2398  while (1)
    23762399    {
    2377       int len = strlen (pprefix->prefix);
     2400      size_t multi_dir_len = 0;
     2401      size_t multi_os_dir_len = 0;
     2402      size_t suffix_len;
     2403      size_t just_suffix_len;
     2404      size_t len;
     2405
     2406      if (multi_dir)
     2407        multi_dir_len = strlen (multi_dir);
     2408      if (multi_os_dir)
     2409        multi_os_dir_len = strlen (multi_os_dir);
     2410      suffix_len = strlen (multi_suffix);
     2411      just_suffix_len = strlen (just_multi_suffix);
     2412
     2413      if (path == NULL)
     2414        {
     2415          len = paths->max_len + extra_space + 1;
     2416          if (suffix_len > multi_os_dir_len)
     2417            len += suffix_len;
     2418          else
     2419            len += multi_os_dir_len;
     2420          path = xmalloc (len);
     2421        }
    23782422
    2379       if (machine_suffix
    2380           && (! check_dir_p
    2381               || is_directory (pprefix->prefix, machine_suffix, 0)))
     2423      for (pl = paths->plist; pl != 0; pl = pl->next)
    23822424        {
    2383           if (!first_time)
    2384             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
     2425          len = strlen (pl->prefix);
     2426          memcpy (path, pl->prefix, len);
    23852427
    2386           first_time = FALSE;
    2387           obstack_grow (&collect_obstack, pprefix->prefix, len);
    2388           obstack_grow (&collect_obstack, machine_suffix, suffix_len);
    2389         }
     2428          /* Look first in MACHINE/VERSION subdirectory.  */
     2429          if (!skip_multi_dir)
     2430            {
     2431              memcpy (path + len, multi_suffix, suffix_len + 1);
     2432              ret = callback (path, callback_info);
     2433              if (ret)
     2434                break;
     2435            }
    23902436
    2391       if (just_machine_suffix
    2392           && pprefix->require_machine_suffix == 2
    2393           && (! check_dir_p
    2394               || is_directory (pprefix->prefix, just_machine_suffix, 0)))
    2395         {
    2396           if (! first_time)
    2397             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
     2437          /* Some paths are tried with just the machine (ie. target)
     2438             subdir.  This is used for finding as, ld, etc.  */
     2439          if (!skip_multi_dir
     2440              && pl->require_machine_suffix == 2)
     2441            {
     2442              memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
     2443              ret = callback (path, callback_info);
     2444              if (ret)
     2445                break;
     2446            }
     2447
     2448          /* Now try the base path.  */
     2449          if (!pl->require_machine_suffix
     2450              && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
     2451            {
     2452              const char *this_multi;
     2453              size_t this_multi_len;
     2454
     2455              if (pl->os_multilib)
     2456                {
     2457                  this_multi = multi_os_dir;
     2458                  this_multi_len = multi_os_dir_len;
     2459                }
     2460              else
     2461                {
     2462                  this_multi = multi_dir;
     2463                  this_multi_len = multi_dir_len;
     2464                }
    23982465
    2399           first_time = FALSE;
    2400           obstack_grow (&collect_obstack, pprefix->prefix, len);
    2401           obstack_grow (&collect_obstack, just_machine_suffix,
    2402                         just_suffix_len);
     2466              if (this_multi_len)
     2467                memcpy (path + len, this_multi, this_multi_len + 1);
     2468              else
     2469                path[len] = '\0';
     2470
     2471              ret = callback (path, callback_info);
     2472              if (ret)
     2473                break;
     2474            }
    24032475        }
     2476      if (pl)
     2477        break;
    24042478
    2405       if (! pprefix->require_machine_suffix)
    2406         {
    2407           if (! first_time)
    2408             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
     2479      if (multi_dir == NULL && multi_os_dir == NULL)
     2480        break;
    24092481
    2410           first_time = FALSE;
    2411           obstack_grow (&collect_obstack, pprefix->prefix, len);
     2482      /* Run through the paths again, this time without multilibs.
     2483         Don't repeat any we have already seen.  */
     2484      if (multi_dir)
     2485        {
     2486          free ((char *) multi_dir);
     2487          multi_dir = NULL;
     2488          free ((char *) multi_suffix);
     2489          multi_suffix = machine_suffix;
     2490          free ((char *) just_multi_suffix);
     2491          just_multi_suffix = just_machine_suffix;
     2492        }
     2493      else
     2494        skip_multi_dir = true;
     2495      if (multi_os_dir)
     2496        {
     2497          free ((char *) multi_os_dir);
     2498          multi_os_dir = NULL;
    24122499        }
     2500      else
     2501        skip_multi_os_dir = true;
    24132502    }
    24142503
     2504  if (multi_dir)
     2505    {
     2506      free ((char *) multi_dir);
     2507      free ((char *) multi_suffix);
     2508      free ((char *) just_multi_suffix);
     2509    }
     2510  if (multi_os_dir)
     2511    free ((char *) multi_os_dir);
     2512  if (ret != path)
     2513    free (path);
     2514  return ret;
     2515}
     2516
     2517/* Callback for build_search_list.  Adds path to obstack being built.  */
     2518
     2519struct add_to_obstack_info {
     2520  struct obstack *ob;
     2521  bool check_dir;
     2522  bool first_time;
     2523};
     2524
     2525static void *
     2526add_to_obstack (char *path, void *data)
     2527{
     2528  struct add_to_obstack_info *info = data;
     2529
     2530  if (info->check_dir && !is_directory (path, false))
     2531    return NULL;
     2532
     2533  if (!info->first_time)
     2534    obstack_1grow (info->ob, PATH_SEPARATOR);
     2535
     2536  obstack_grow (info->ob, path, strlen (path));
     2537
     2538  info->first_time = false;
     2539  return NULL;
     2540}
     2541
     2542/* Build a list of search directories from PATHS.
     2543   PREFIX is a string to prepend to the list.
     2544   If CHECK_DIR_P is true we ensure the directory exists.
     2545   If DO_MULTI is true, multilib paths are output first, then
     2546   non-multilib paths.
     2547   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
     2548   It is also used by the --print-search-dirs flag.  */
     2549
     2550static char *
     2551build_search_list (const struct path_prefix *paths, const char *prefix,
     2552                   bool check_dir, bool do_multi)
     2553{
     2554  struct add_to_obstack_info info;
     2555
     2556  info.ob = &collect_obstack;
     2557  info.check_dir = check_dir;
     2558  info.first_time = true;
     2559
     2560  obstack_grow (&collect_obstack, prefix, strlen (prefix));
     2561  obstack_1grow (&collect_obstack, '=');
     2562
     2563  for_each_path (paths, do_multi, 0, add_to_obstack, &info);
     2564
    24152565  obstack_1grow (&collect_obstack, '\0');
    24162566  return XOBFINISH (&collect_obstack, char *);
  • gcc/system.h

     }
    @@ -2419,9 +2569,10 @@
        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,
    @@ -2442,20 +2593,53 @@
       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)
    @@ -2467,112 +2651,24 @@
         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;
    -	}
    -    }
    -  else
    -    for (pl = pprefix->plist; pl; pl = pl->next)
    -      {
    -	const char *this_name
    -	  = pl->os_multilib ? multilib_os_name : multilib_name;
    +	return xstrdup (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;
    -	      }
    -
    -	    /* 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;
    -	      }
    +      return NULL;
    +    }
     
    -	    strcpy (temp, pl->prefix);
    -	    strcat (temp, this_name);
    -	    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;
     
    -  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
    @@ -2691,7 +2787,7 @@
     
       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;
    @@ -2706,7 +2802,7 @@
     	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++;
    @@ -3643,7 +3739,7 @@
     		   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);
    @@ -4391,108 +4487,55 @@
         }
     }
     
    -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;
    -  bool multilib_p = false;
    -
    -  /* 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;
    +/* Callback for processing %D and %I specs.  */
     
    -  /* 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))
    -	{
    -	  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)
    +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)
    +{
    +  struct spec_path_info *info = data;
    +  size_t len = 0;
    +  char save = 0;
    +
    +  if (info->omit_relative && !IS_ABSOLUTE_PATH (path))
    +    return NULL;
    +
    +  if (info->append_len != 0)
         {
    -      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;
    +
    +  do_spec_1 (info->option, 1, NULL);
    +  if (info->separate_options)
    +    do_spec_1 (" ", 0, NULL);
     
    -  if (machine_suffix)
    +  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.
    @@ -4630,23 +4673,23 @@
     	     that we search for startfiles.  */
     	  case 'D':
     	    {
    -	      struct prefix_list *pl = startfile_prefixes.plist;
    -
    -	      for (; pl; pl = pl->next)
    -		{
    -		  const char *no_suffix_multilib_dir;
    +	      struct spec_path_info info;
     
    -		  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;
     
    @@ -4883,7 +4926,7 @@
     
     	  case 'I':
     	    {
    -	      struct prefix_list *pl = include_prefixes.plist;
    +	      struct spec_path_info info;
     
     	      if (gcc_exec_prefix)
     		{
    @@ -4906,9 +4949,14 @@
     		  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;
     
    @@ -5894,48 +5942,27 @@
     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++ = '.';
    @@ -5943,13 +5970,13 @@
     
       /* 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));
    @@ -6139,7 +6166,7 @@
     			   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);
    @@ -6275,7 +6302,7 @@
       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);
         }
     
    @@ -6304,8 +6331,10 @@
       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);
         }
     
    @@ -6622,14 +6651,14 @@
           /* 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)
    diff -uNr gcc-4.1.0/gcc/system.h gcc-4.1.0-PR20425/gcc/system.h
    old new  
    728728        TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT           \
    729729        LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE                \
    730730        TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC         \
    731         PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF
     731        PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF            \
     732        SMALL_ARG_MAX
    732733
    733734/* Hooks that are no longer used.  */
    734735 #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE   \
Note: See TracBrowser for help on using the repository browser.