source: patches/gcc-4.1.0-PR20425-1.patch @ 4fc5a87

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since 4fc5a87 was 4fc5a87, checked in by Jim Gifford <clfs@…>, 18 years ago

Added GCC multilib patch. Rename fold_const patch to PR # to keep consistency

  • Property mode set to 100644
File size: 36.4 KB
RevLine 
[4fc5a87]1Submitted By: Ryan Oliver <ryan at pha dot com dot au>
2Date: 2006-03-10
3Initial Package Version: 4.1.0
4Origin: GCC SVN Revision 108635 (diffed against 4.1.0 release)
5Upstream Status: In GCC trunk
6Description: Fix for PR20425
7
8From http://gcc.gnu.org/ml/gcc-patches/2005-12/msg00818.html
9---------------------------------8<------------------------------------
10This gives the gcc driver a new path iteration function, for_each_path,
11and uses it everywhere, making path iteration a little more consistent.
12for_each_path uses the same path ordering as the existing find_file
13function.  I've also tweaked some of the existing find_a_file calls for
14consistency, and uncovered and fixed some other bugs..
15
16Functional changes are:
17
18o  %D library paths are printed in the same order as gcc uses elsewhere
19   when searching library directories, ie. all multilib paths are first.
20   http://gcc.gnu.org/ml/gcc-patches/2005-03/msg02044.html effectively
21   reverted by the rewrite because I believe the same speedup is gained
22   by searching the right dirs first.
23
24o  gcc -print-search-dirs prints library multilib paths followed by
25   non-multilib paths where before we just printed non-multilib paths.
26
27o  LIBRARY_PATH_ENV similarly includes multilib directories.
28
29o  All searches of startfile_prefixes now look in multilib dirs first
30   followed by non-multilib dirs.  This changes the dirs we search for
31   spec files, and %include and %include_noerr in specs.  Previously
32   we only searched the non-multilib dirs for specs files.  I think this
33   change is worthwhile just for consistency, and the extension is
34   reasonable.  For instance, it would allow different spec files to be
35   used for gcc -m64 vs. gcc -m32.  However, if others think this wrong,
36   I won't argue.  Consistency isn't everything.
37
38o  Some attempt made to prevent searching of duplicate paths.  The old
39   find_file would search some paths twice (when multilib_dir was NULL
40   but multilib_os_dir non-NULL).  We still search twice in some cases,
41   eg. /usr/lib/../lib and /usr/lib are considered different paths.
42
43o  find_a_file with last param (do_multi) true now searches both
44   multilib and non-multilib paths.  Before, do_multi (well, the old
45   param name was multilib) meant just search multilib paths.  This
46   isn't a user-visible change as the only place where find_a_file was
47   invoked with the last param true was from find_file, where we
48   immediately followed with a non-multilib find_a_file.
49
50o  Memory leaks fixed in is_directory.
51
52o  LIBRARY_PATH_ENV and COMPILER_PATH now only have existing
53   directories, making LIBRARY_PATH_ENV closer to %D paths.  The
54   following lines (which I remove) in is_directory meant that
55   is_directory didn't do much for LIBRARY_PATH_ENV, except on
56   SMALL_ARG_MAX machines.
57
58  4278        ian #ifndef SMALL_ARG_MAX
59  4278        ian   if (! linker)
60  4278        ian     return 1;
61  4278        ian #endif
62
63   I'll also remove mention of SMALL_ARG_MAX in config and doc files
64   when I commit this change as this is the only place it is used.
65
66o  gcc -Bnon-dir-prefix- now works properly.  The previously mentioned
67   is_directory peculiarity affected the following code.
68
69 43664      nickc /* Catch the case where the user has forgotten to append a
70 46063      jsm28    directory separator to the path.  Note, they may be using
71 43664      nickc    -B to add an executable name prefix, eg "i386-elf-", in
72 43664      nickc    order to distinguish between multiple installations of
73 43664      nickc    GCC in the same directory.  Hence we must check to see
74 43664      nickc    if appending a directory separator actually makes a
75 43664      nickc    valid directory name.  */
76 43664      nickc if (! IS_DIR_SEPARATOR (value [len - 1])
77 43664      nickc     && is_directory (value, "", 0))
78 43664      nickc   {
79 43767      ghazi     char *tmp = xmalloc (len + 2);
80 43767      ghazi     strcpy (tmp, value);
81 43767      ghazi     tmp[len] = DIR_SEPARATOR;
82 43767      ghazi     tmp[++ len] = 0;
83 43767      ghazi     value = tmp;
84 43664      nickc   }
85
86Bootstrapped and regression tested powerpc64-linux and powerpc-linux on
87a previous iteration of this patch missing is_directory fixes.
88Currently running tests on this patch.
89---------------------------------8<------------------------------------
90
91diff -uNr gcc-4.1.0/gcc/ChangeLog gcc-4.1.0-PR20425/gcc/ChangeLog
92--- gcc-4.1.0/gcc/ChangeLog     2006-02-28 19:28:30.000000000 +1100
93+++ gcc-4.1.0-PR20425/gcc/ChangeLog     2006-03-10 23:56:57.000000000 +1100
94@@ -1,3 +1,31 @@
95+2006-03-10  Ryan Oliver <ryan@linuxfromscratch.org>
96+       Backport:
97+       2005-12-16  Alan Modra  <amodra@bigpond.net.au>
98+       PR driver/20425
99+       * gcc.c (for_each_path): New function.
100+       (add_to_obstack, file_at_path): New functions.
101+       (struct file_at_path_info, struct add_to_obstack_info): New.
102+       (build_search_list): Rewrite using for_each_path.  Constify struct
103+       path_prefix pointer.  Add do_multi param.  Adjust all callers.
104+       (find_a_file): Similarly, but just change existing param to bool.
105+       (putenv_from_prefixes): Add do_multi param, make "paths" const.
106+       (do_spec_path): Delete.
107+       (struct spec_path_info): New.
108+       (spec_path): New function.
109+       (do_spec_1): Use for_each_path for %D and %I.
110+       (find_file): Adjust for find_a_file changes.
111+       (main): Search multilibs for specs.  Print multilib lib path for
112+       -print-search-dirs.  Likewise add multilibs to LIBRARY_PATH_ENV.
113+       (read_specs): Search multilibs for %include and %include_noerr.
114+       (is_directory): Remove second string param.  Change last param
115+       to a bool.  Don't use concat.  Remove SMALL_ARG_MAX test, always
116+       check path is a dir.  Update all callers.
117+       * doc/hostconfig.texi (SMALL_ARG_MAX): Remove mention.
118+       * system.h (SMALL_ARG_MAX): Poison.
119+       * config.gcc: Don't define SMALL_ARG_MAX.
120+       * config.host: Likewise.
121+       * config.build: Likewise.
122+
123 2006-02-28  Release Manager
124 
125        * GCC 4.1.0 released.
126diff -uNr gcc-4.1.0/gcc/config.build gcc-4.1.0-PR20425/gcc/config.build
127--- gcc-4.1.0/gcc/config.build  2005-06-25 12:02:01.000000000 +1000
128+++ gcc-4.1.0-PR20425/gcc/config.build  2006-03-10 23:47:02.000000000 +1100
129@@ -90,15 +90,10 @@
130     build_install_headers_dir=install-headers-cpio
131     ;;
132   i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
133-    build_xm_defines="SMALL_ARG_MAX"
134     build_install_headers_dir=install-headers-cpio
135     ;;
136-  i[34567]86-*-solaris2*)
137-    build_xm_defines="SMALL_ARG_MAX"
138-    ;;
139   i[34567]86-*-sysv4*)
140     # Intel x86 running system V r4
141-    build_xm_defines="SMALL_ARG_MAX"
142     build_install_headers_dir=install-headers-cpio
143     ;;
144   i[34567]86-*-udk*)
145diff -uNr gcc-4.1.0/gcc/config.gcc gcc-4.1.0-PR20425/gcc/config.gcc
146--- gcc-4.1.0/gcc/config.gcc    2006-02-07 03:07:46.000000000 +1100
147+++ gcc-4.1.0-PR20425/gcc/config.gcc    2006-03-10 23:47:20.000000000 +1100
148@@ -994,7 +994,6 @@
149        then
150                tm_file="${tm_file} usegas.h"
151        fi
152-       xm_defines="SMALL_ARG_MAX"
153        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ptx4.h i386/ptx4-i.h"
154        tmake_file=t-svr4
155        extra_parts="crtbegin.o crtend.o"
156@@ -1125,7 +1124,6 @@
157        use_fixproto=yes
158        ;;
159 i[34567]86-*-solaris2*)
160-       xm_defines="SMALL_ARG_MAX"
161        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h"
162        case ${target} in
163        *-*-solaris2.[0-6] | *-*-solaris2.[0-6].*)
164@@ -1192,7 +1190,6 @@
165        use_fixproto=yes
166        ;;
167 i[34567]86-*-sysv4*)           # Intel 80386's running system V.4
168-       xm_defines="SMALL_ARG_MAX"
169        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
170        if test x$stabs = xyes
171        then
172diff -uNr gcc-4.1.0/gcc/config.host gcc-4.1.0-PR20425/gcc/config.host
173--- gcc-4.1.0/gcc/config.host   2006-02-06 03:18:20.000000000 +1100
174+++ gcc-4.1.0-PR20425/gcc/config.host   2006-03-10 23:47:52.000000000 +1100
175@@ -135,17 +135,10 @@
176   i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
177     host_xm_defines='FATAL_EXIT_CODE=12'
178     ;;
179-  i[34567]86-sequent-ptx4*)
180-    host_xm_defines="SMALL_ARG_MAX"
181-    ;;
182   i[34567]86-*-solaris2*)
183-    host_xm_defines="SMALL_ARG_MAX"
184     out_host_hook_obj=host-solaris.o
185     host_xmake_file=x-solaris
186     ;;
187-  i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
188-    host_xm_defines="SMALL_ARG_MAX"
189-    ;;
190   i[34567]86-pc-msdosdjgpp*)
191     host_xm_file=i386/xm-djgpp.h
192     host_exeext=.exe
193diff -uNr gcc-4.1.0/gcc/doc/hostconfig.texi gcc-4.1.0-PR20425/gcc/doc/hostconfig.texi
194--- gcc-4.1.0/gcc/doc/hostconfig.texi   2004-11-24 15:31:58.000000000 +1100
195+++ gcc-4.1.0-PR20425/gcc/doc/hostconfig.texi   2006-03-10 23:48:20.000000000 +1100
196@@ -208,11 +208,6 @@
197 If defined, a C statement (sans semicolon) that performs host-dependent
198 initialization when a compilation driver is being initialized.
199 
200-@item SMALL_ARG_MAX
201-Define this macro if the host system has a small limit on the total
202-size of an argument vector.  This causes the driver to take more care
203-not to pass unnecessary arguments to subprocesses.
204-
205 @item HOST_LONG_LONG_FORMAT
206 If defined, the string used to indicate an argument of type @code{long
207 long} to functions like @code{printf}.  The default value is
208diff -uNr gcc-4.1.0/gcc/gcc.c gcc-4.1.0-PR20425/gcc/gcc.c
209--- gcc-4.1.0/gcc/gcc.c 2006-01-22 05:29:08.000000000 +1100
210+++ gcc-4.1.0-PR20425/gcc/gcc.c 2006-03-10 22:14:35.000000000 +1100
211@@ -287,10 +287,12 @@
212 static void read_specs (const char *, int);
213 static void set_spec (const char *, const char *);
214 static struct compiler *lookup_compiler (const char *, size_t, const char *);
215-static char *build_search_list (struct path_prefix *, const char *, int);
216-static void putenv_from_prefixes (struct path_prefix *, const char *);
217+static char *build_search_list (const struct path_prefix *, const char *,
218+                               bool, bool);
219+static void putenv_from_prefixes (const struct path_prefix *, const char *,
220+                                 bool);
221 static int access_check (const char *, int);
222-static char *find_a_file (struct path_prefix *, const char *, int, int);
223+static char *find_a_file (const struct path_prefix *, const char *, int, bool);
224 static void add_prefix (struct path_prefix *, const char *, const char *,
225                        int, int, int);
226 static void add_sysrooted_prefix (struct path_prefix *, const char *,
227@@ -313,13 +315,12 @@
228 static const char *handle_spec_function (const char *);
229 static char *save_string (const char *, int);
230 static void set_collect_gcc_options (void);
231-static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);
232 static int do_spec_1 (const char *, int, const char *);
233 static int do_spec_2 (const char *);
234 static void do_option_spec (const char *, const char *);
235 static void do_self_spec (const char *);
236 static const char *find_file (const char *);
237-static int is_directory (const char *, const char *, int);
238+static int is_directory (const char *, bool);
239 static const char *validate_switches (const char *);
240 static void validate_all_switches (void);
241 static inline void validate_switches_from_spec (const char *);
242@@ -2036,7 +2037,7 @@
243                       (long) (p1 - buffer + 1));
244 
245              p[-2] = '\0';
246-             new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
247+             new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
248              read_specs (new_filename ? new_filename : p1, FALSE);
249              continue;
250            }
251@@ -2055,7 +2056,7 @@
252                       (long) (p1 - buffer + 1));
253 
254              p[-2] = '\0';
255-             new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
256+             new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
257              if (new_filename)
258                read_specs (new_filename, FALSE);
259              else if (verbose_flag)
260@@ -2352,65 +2353,214 @@
261   failure_delete_queue = 0;
262 }
263 
264-/* Build a list of search directories from PATHS.
265-   PREFIX is a string to prepend to the list.
266-   If CHECK_DIR_P is nonzero we ensure the directory exists.
267-   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
268-   It is also used by the --print-search-dirs flag.  */
269-
270-static char *
271-build_search_list (struct path_prefix *paths, const char *prefix,
272-                  int check_dir_p)
273+/* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
274+   returns non-NULL.
275+   If DO_MULTI is true iterate over the paths twice, first with multilib
276+   suffix then without, otherwise iterate over the paths once without
277+   adding a multilib suffix.  When DO_MULTI is true, some attempt is made
278+   to avoid visiting the same path twice, but we could do better.  For
279+   instance, /usr/lib/../lib is considered different from /usr/lib.
280+   At least EXTRA_SPACE chars past the end of the path passed to
281+   CALLBACK are available for use by the callback.
282+   CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
283+
284+   Returns the value returned by CALLBACK.  */
285+
286+static void *
287+for_each_path (const struct path_prefix *paths,
288+              bool do_multi,
289+              size_t extra_space,
290+              void *(*callback) (char *, void *),
291+              void *callback_info)
292 {
293-  int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
294-  int just_suffix_len
295-    = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
296-  int first_time = TRUE;
297-  struct prefix_list *pprefix;
298-
299-  obstack_grow (&collect_obstack, prefix, strlen (prefix));
300-  obstack_1grow (&collect_obstack, '=');
301+  struct prefix_list *pl;
302+  const char *multi_dir = NULL;
303+  const char *multi_os_dir = NULL;
304+  const char *multi_suffix;
305+  const char *just_multi_suffix;
306+  char *path = NULL;
307+  void *ret = NULL;
308+  bool skip_multi_dir = false;
309+  bool skip_multi_os_dir = false;
310+
311+  multi_suffix = machine_suffix;
312+  just_multi_suffix = just_machine_suffix;
313+  if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
314+    {
315+      multi_dir = concat (multilib_dir, dir_separator_str, NULL);
316+      multi_suffix = concat (multi_suffix, multi_dir, NULL);
317+      just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
318+    }
319+  if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
320+    multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
321 
322-  for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
323+  while (1)
324     {
325-      int len = strlen (pprefix->prefix);
326+      size_t multi_dir_len = 0;
327+      size_t multi_os_dir_len = 0;
328+      size_t suffix_len;
329+      size_t just_suffix_len;
330+      size_t len;
331+
332+      if (multi_dir)
333+       multi_dir_len = strlen (multi_dir);
334+      if (multi_os_dir)
335+       multi_os_dir_len = strlen (multi_os_dir);
336+      suffix_len = strlen (multi_suffix);
337+      just_suffix_len = strlen (just_multi_suffix);
338+
339+      if (path == NULL)
340+       {
341+         len = paths->max_len + extra_space + 1;
342+         if (suffix_len > multi_os_dir_len)
343+           len += suffix_len;
344+         else
345+           len += multi_os_dir_len;
346+         path = xmalloc (len);
347+       }
348 
349-      if (machine_suffix
350-         && (! check_dir_p
351-             || is_directory (pprefix->prefix, machine_suffix, 0)))
352+      for (pl = paths->plist; pl != 0; pl = pl->next)
353        {
354-         if (!first_time)
355-           obstack_1grow (&collect_obstack, PATH_SEPARATOR);
356+         len = strlen (pl->prefix);
357+         memcpy (path, pl->prefix, len);
358 
359-         first_time = FALSE;
360-         obstack_grow (&collect_obstack, pprefix->prefix, len);
361-         obstack_grow (&collect_obstack, machine_suffix, suffix_len);
362-       }
363+         /* Look first in MACHINE/VERSION subdirectory.  */
364+         if (!skip_multi_dir)
365+           {
366+             memcpy (path + len, multi_suffix, suffix_len + 1);
367+             ret = callback (path, callback_info);
368+             if (ret)
369+               break;
370+           }
371 
372-      if (just_machine_suffix
373-         && pprefix->require_machine_suffix == 2
374-         && (! check_dir_p
375-             || is_directory (pprefix->prefix, just_machine_suffix, 0)))
376-       {
377-         if (! first_time)
378-           obstack_1grow (&collect_obstack, PATH_SEPARATOR);
379+         /* Some paths are tried with just the machine (ie. target)
380+            subdir.  This is used for finding as, ld, etc.  */
381+         if (!skip_multi_dir
382+             && pl->require_machine_suffix == 2)
383+           {
384+             memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
385+             ret = callback (path, callback_info);
386+             if (ret)
387+               break;
388+           }
389+
390+         /* Now try the base path.  */
391+         if (!pl->require_machine_suffix
392+             && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
393+           {
394+             const char *this_multi;
395+             size_t this_multi_len;
396+
397+             if (pl->os_multilib)
398+               {
399+                 this_multi = multi_os_dir;
400+                 this_multi_len = multi_os_dir_len;
401+               }
402+             else
403+               {
404+                 this_multi = multi_dir;
405+                 this_multi_len = multi_dir_len;
406+               }
407 
408-         first_time = FALSE;
409-         obstack_grow (&collect_obstack, pprefix->prefix, len);
410-         obstack_grow (&collect_obstack, just_machine_suffix,
411-                       just_suffix_len);
412+             if (this_multi_len)
413+               memcpy (path + len, this_multi, this_multi_len + 1);
414+             else
415+               path[len] = '\0';
416+
417+             ret = callback (path, callback_info);
418+             if (ret)
419+               break;
420+           }
421        }
422+      if (pl)
423+       break;
424 
425-      if (! pprefix->require_machine_suffix)
426-       {
427-         if (! first_time)
428-           obstack_1grow (&collect_obstack, PATH_SEPARATOR);
429+      if (multi_dir == NULL && multi_os_dir == NULL)
430+       break;
431 
432-         first_time = FALSE;
433-         obstack_grow (&collect_obstack, pprefix->prefix, len);
434+      /* Run through the paths again, this time without multilibs.
435+        Don't repeat any we have already seen.  */
436+      if (multi_dir)
437+       {
438+         free ((char *) multi_dir);
439+         multi_dir = NULL;
440+         free ((char *) multi_suffix);
441+         multi_suffix = machine_suffix;
442+         free ((char *) just_multi_suffix);
443+         just_multi_suffix = just_machine_suffix;
444+       }
445+      else
446+       skip_multi_dir = true;
447+      if (multi_os_dir)
448+       {
449+         free ((char *) multi_os_dir);
450+         multi_os_dir = NULL;
451        }
452+      else
453+       skip_multi_os_dir = true;
454     }
455 
456+  if (multi_dir)
457+    {
458+      free ((char *) multi_dir);
459+      free ((char *) multi_suffix);
460+      free ((char *) just_multi_suffix);
461+    }
462+  if (multi_os_dir)
463+    free ((char *) multi_os_dir);
464+  if (ret != path)
465+    free (path);
466+  return ret;
467+}
468+
469+/* Callback for build_search_list.  Adds path to obstack being built.  */
470+
471+struct add_to_obstack_info {
472+  struct obstack *ob;
473+  bool check_dir;
474+  bool first_time;
475+};
476+
477+static void *
478+add_to_obstack (char *path, void *data)
479+{
480+  struct add_to_obstack_info *info = data;
481+
482+  if (info->check_dir && !is_directory (path, false))
483+    return NULL;
484+
485+  if (!info->first_time)
486+    obstack_1grow (info->ob, PATH_SEPARATOR);
487+
488+  obstack_grow (info->ob, path, strlen (path));
489+
490+  info->first_time = false;
491+  return NULL;
492+}
493+
494+/* Build a list of search directories from PATHS.
495+   PREFIX is a string to prepend to the list.
496+   If CHECK_DIR_P is true we ensure the directory exists.
497+   If DO_MULTI is true, multilib paths are output first, then
498+   non-multilib paths.
499+   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
500+   It is also used by the --print-search-dirs flag.  */
501+
502+static char *
503+build_search_list (const struct path_prefix *paths, const char *prefix,
504+                  bool check_dir, bool do_multi)
505+{
506+  struct add_to_obstack_info info;
507+
508+  info.ob = &collect_obstack;
509+  info.check_dir = check_dir;
510+  info.first_time = true;
511+
512+  obstack_grow (&collect_obstack, prefix, strlen (prefix));
513+  obstack_1grow (&collect_obstack, '=');
514+
515+  for_each_path (paths, do_multi, 0, add_to_obstack, &info);
516+
517   obstack_1grow (&collect_obstack, '\0');
518   return XOBFINISH (&collect_obstack, char *);
519 }
520@@ -2419,9 +2569,10 @@
521    for collect.  */
522 
523 static void
524-putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
525+putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
526+                     bool do_multi)
527 {
528-  putenv (build_search_list (paths, env_var, 1));
529+  putenv (build_search_list (paths, env_var, true, do_multi));
530 }
531 
532 /* Check whether NAME can be accessed in MODE.  This is like access,
533@@ -2442,20 +2593,53 @@
534   return access (name, mode);
535 }
536 
537+/* Callback for find_a_file.  Appends the file name to the directory
538+   path.  If the resulting file exists in the right mode, return the
539+   full pathname to the file.  */
540+
541+struct file_at_path_info {
542+  const char *name;
543+  const char *suffix;
544+  int name_len;
545+  int suffix_len;
546+  int mode;
547+};
548+
549+static void *
550+file_at_path (char *path, void *data)
551+{
552+  struct file_at_path_info *info = data;
553+  size_t len = strlen (path);
554+
555+  memcpy (path + len, info->name, info->name_len);
556+  len += info->name_len;
557+
558+  /* Some systems have a suffix for executable files.
559+     So try appending that first.  */
560+  if (info->suffix_len)
561+    {
562+      memcpy (path + len, info->suffix, info->suffix_len + 1);
563+      if (access_check (path, info->mode) == 0)
564+       return path;
565+    }
566+
567+  path[len] = '\0';
568+  if (access_check (path, info->mode) == 0)
569+    return path;
570+
571+  return NULL;
572+}
573+
574 /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
575-   access to check permissions.
576+   access to check permissions.  If DO_MULTI is true, search multilib
577+   paths then non-multilib paths, otherwise do not search multilib paths.
578    Return 0 if not found, otherwise return its name, allocated with malloc.  */
579 
580 static char *
581-find_a_file (struct path_prefix *pprefix, const char *name, int mode,
582-            int multilib)
583+find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
584+            bool do_multi)
585 {
586-  char *temp;
587-  const char *const file_suffix =
588-    ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
589-  struct prefix_list *pl;
590-  int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
591-  const char *multilib_name, *multilib_os_name;
592+  struct file_at_path_info info;
593 
594 #ifdef DEFAULT_ASSEMBLER
595   if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
596@@ -2467,112 +2651,24 @@
597     return xstrdup (DEFAULT_LINKER);
598 #endif
599 
600-  if (machine_suffix)
601-    len += strlen (machine_suffix);
602-
603-  multilib_name = name;
604-  multilib_os_name = name;
605-  if (multilib && multilib_os_dir)
606-    {
607-      int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
608-      int len2 = strlen (multilib_os_dir) + 1;
609-
610-      len += len1 > len2 ? len1 : len2;
611-      if (multilib_dir)
612-       multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
613-                                 NULL));
614-      if (strcmp (multilib_os_dir, ".") != 0)
615-       multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
616-                                   NULL));
617-    }
618-
619-  temp = xmalloc (len);
620-
621   /* Determine the filename to execute (special case for absolute paths).  */
622 
623   if (IS_ABSOLUTE_PATH (name))
624     {
625       if (access (name, mode) == 0)
626-       {
627-         strcpy (temp, name);
628-         return temp;
629-       }
630-    }
631-  else
632-    for (pl = pprefix->plist; pl; pl = pl->next)
633-      {
634-       const char *this_name
635-         = pl->os_multilib ? multilib_os_name : multilib_name;
636+       return xstrdup (name);
637 
638-       if (machine_suffix)
639-         {
640-           /* Some systems have a suffix for executable files.
641-              So try appending that first.  */
642-           if (file_suffix[0] != 0)
643-             {
644-               strcpy (temp, pl->prefix);
645-               strcat (temp, machine_suffix);
646-               strcat (temp, multilib_name);
647-               strcat (temp, file_suffix);
648-               if (access_check (temp, mode) == 0)
649-                 return temp;
650-             }
651-
652-           /* Now try just the multilib_name.  */
653-           strcpy (temp, pl->prefix);
654-           strcat (temp, machine_suffix);
655-           strcat (temp, multilib_name);
656-           if (access_check (temp, mode) == 0)
657-             return temp;
658-         }
659-
660-       /* Certain prefixes are tried with just the machine type,
661-          not the version.  This is used for finding as, ld, etc.  */
662-       if (just_machine_suffix && pl->require_machine_suffix == 2)
663-         {
664-           /* Some systems have a suffix for executable files.
665-              So try appending that first.  */
666-           if (file_suffix[0] != 0)
667-             {
668-               strcpy (temp, pl->prefix);
669-               strcat (temp, just_machine_suffix);
670-               strcat (temp, multilib_name);
671-               strcat (temp, file_suffix);
672-               if (access_check (temp, mode) == 0)
673-                 return temp;
674-             }
675-
676-           strcpy (temp, pl->prefix);
677-           strcat (temp, just_machine_suffix);
678-           strcat (temp, multilib_name);
679-           if (access_check (temp, mode) == 0)
680-             return temp;
681-         }
682-
683-       /* Certain prefixes can't be used without the machine suffix
684-          when the machine or version is explicitly specified.  */
685-       if (! pl->require_machine_suffix)
686-         {
687-           /* Some systems have a suffix for executable files.
688-              So try appending that first.  */
689-           if (file_suffix[0] != 0)
690-             {
691-               strcpy (temp, pl->prefix);
692-               strcat (temp, this_name);
693-               strcat (temp, file_suffix);
694-               if (access_check (temp, mode) == 0)
695-                 return temp;
696-             }
697+      return NULL;
698+    }
699 
700-           strcpy (temp, pl->prefix);
701-           strcat (temp, this_name);
702-           if (access_check (temp, mode) == 0)
703-             return temp;
704-         }
705-      }
706+  info.name = name;
707+  info.suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
708+  info.name_len = strlen (info.name);
709+  info.suffix_len = strlen (info.suffix);
710+  info.mode = mode;
711 
712-  free (temp);
713-  return 0;
714+  return for_each_path (pprefix, do_multi, info.name_len + info.suffix_len,
715+                       file_at_path, &info);
716 }
717 
718 /* Ranking of prefixes in the sort list. -B prefixes are put before
719@@ -2691,7 +2787,7 @@
720 
721   commands[0].prog = argbuf[0]; /* first command.  */
722   commands[0].argv = &argbuf[0];
723-  string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
724+  string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, false);
725 
726   if (string)
727     commands[0].argv[0] = string;
728@@ -2706,7 +2802,7 @@
729        commands[n_commands].prog = argbuf[i + 1];
730        commands[n_commands].argv = &argbuf[i + 1];
731        string = find_a_file (&exec_prefixes, commands[n_commands].prog,
732-                             X_OK, 0);
733+                             X_OK, false);
734        if (string)
735          commands[n_commands].argv[0] = string;
736        n_commands++;
737@@ -3643,7 +3739,7 @@
738                   if appending a directory separator actually makes a
739                   valid directory name.  */
740                if (! IS_DIR_SEPARATOR (value [len - 1])
741-                   && is_directory (value, "", 0))
742+                   && is_directory (value, false))
743                  {
744                    char *tmp = xmalloc (len + 2);
745                    strcpy (tmp, value);
746@@ -4391,108 +4487,55 @@
747     }
748 }
749 
750-void
751-do_spec_path (struct prefix_list *pl, const char *option,
752-             int omit_if_relative, int separate_options,
753-             int only_subdir,
754-             const char *dir_for_machine_suffix,
755-             const char *dir_for_no_suffix)
756-{
757-  static size_t bufsize = 0;
758-  static char *buffer;
759-  int idx;
760-  bool multilib_p = false;
761-
762-  /* Used on systems which record the specified -L dirs
763-     and use them to search for dynamic linking.  */
764-  /* Relative directories always come from -B,
765-     and it is better not to use them for searching
766-     at run time.  In particular, stage1 loses.  */
767-  if (omit_if_relative
768-      && !IS_ABSOLUTE_PATH (pl->prefix))
769-    return;
770+/* Callback for processing %D and %I specs.  */
771 
772-  /* Try subdirectory if there is one.  */
773-  if (machine_suffix && dir_for_machine_suffix)
774-    {
775-      if (strlen (pl->prefix) + strlen (machine_suffix)
776-         >= bufsize)
777-       bufsize = (strlen (pl->prefix)
778-                 + strlen (machine_suffix)) * 2 + 1;
779-      buffer = xrealloc (buffer, bufsize);
780-      strcpy (buffer, pl->prefix);
781-      strcat (buffer, machine_suffix);
782-      if (is_directory (buffer, dir_for_machine_suffix, 1))
783-       {
784-         multilib_p = true;
785-         do_spec_1 (option, separate_options, NULL);
786-         if (separate_options)
787-           do_spec_1 (" ", 0, NULL);
788-         do_spec_1 (buffer, 1, NULL);
789-         do_spec_1 (dir_for_machine_suffix, 1, NULL);
790-         /* Make this a separate argument.  */
791-         do_spec_1 (" ", 0, NULL);
792-       }
793-    }
794-  if (!pl->require_machine_suffix && dir_for_no_suffix)
795+struct spec_path_info {
796+  const char *option;
797+  const char *append;
798+  size_t append_len;
799+  bool omit_relative;
800+  bool separate_options;
801+};
802+
803+static void *
804+spec_path (char *path, void *data)
805+{
806+  struct spec_path_info *info = data;
807+  size_t len = 0;
808+  char save = 0;
809+
810+  if (info->omit_relative && !IS_ABSOLUTE_PATH (path))
811+    return NULL;
812+
813+  if (info->append_len != 0)
814     {
815-      if (is_directory (pl->prefix, dir_for_no_suffix, 1))
816-       {
817-         multilib_p = true;
818-         do_spec_1 (option, separate_options, NULL);
819-         if (separate_options)
820-           do_spec_1 (" ", 0, NULL);
821-         do_spec_1 (pl->prefix, 1, NULL);
822-         do_spec_1 (dir_for_no_suffix, 1, NULL);
823-         /* Make this a separate argument.  */
824-         do_spec_1 (" ", 0, NULL);
825-       }
826+      len = strlen (path);
827+      memcpy (path + len, info->append, info->append_len + 1);
828     }
829 
830-  if (only_subdir || multilib_p)
831-    return;
832+  if (!is_directory (path, true))
833+    return NULL;
834+
835+  do_spec_1 (info->option, 1, NULL);
836+  if (info->separate_options)
837+    do_spec_1 (" ", 0, NULL);
838 
839-  if (machine_suffix)
840+  if (info->append_len == 0)
841     {
842-      if (is_directory (pl->prefix, machine_suffix, 1))
843-       {
844-         do_spec_1 (option, separate_options, NULL);
845-         if (separate_options)
846-           do_spec_1 (" ", 0, NULL);
847-         do_spec_1 (pl->prefix, 1, NULL);
848-         /* Remove slash from machine_suffix.  */
849-         if (strlen (machine_suffix) >= bufsize)
850-           bufsize = strlen (machine_suffix) * 2 + 1;
851-         buffer = xrealloc (buffer, bufsize);
852-         strcpy (buffer, machine_suffix);
853-         idx = strlen (buffer);
854-         if (IS_DIR_SEPARATOR (buffer[idx - 1]))
855-           buffer[idx - 1] = 0;
856-         do_spec_1 (buffer, 1, NULL);
857-         /* Make this a separate argument.  */
858-         do_spec_1 (" ", 0, NULL);
859-       }
860-    }
861-  if (!pl->require_machine_suffix)
862-    {
863-      if (is_directory (pl->prefix, "", 1))
864-       {
865-         do_spec_1 (option, separate_options, NULL);
866-         if (separate_options)
867-           do_spec_1 (" ", 0, NULL);
868-         /* Remove slash from pl->prefix.  */
869-         if (strlen (pl->prefix) >= bufsize)
870-           bufsize = strlen (pl->prefix) * 2 + 1;
871-         buffer = xrealloc (buffer, bufsize);
872-         strcpy (buffer, pl->prefix);
873-         idx = strlen (buffer);
874-         if (IS_DIR_SEPARATOR (buffer[idx - 1]))
875-           buffer[idx - 1] = 0;
876-         do_spec_1 (buffer, 1, NULL);
877-         /* Make this a separate argument.  */
878-         do_spec_1 (" ", 0, NULL);
879-       }
880+      len = strlen (path);
881+      save = path[len - 1];
882+      if (IS_DIR_SEPARATOR (path[len - 1]))
883+       path[len - 1] = '\0';
884     }
885+
886+  do_spec_1 (path, 1, NULL);
887+  do_spec_1 (" ", 0, NULL);
888+
889+  /* Must not damage the original path.  */
890+  if (info->append_len == 0)
891+    path[len - 1] = save;
892+
893+  return NULL;
894 }
895 
896 /* Process the sub-spec SPEC as a portion of a larger spec.
897@@ -4630,23 +4673,23 @@
898             that we search for startfiles.  */
899          case 'D':
900            {
901-             struct prefix_list *pl = startfile_prefixes.plist;
902-
903-             for (; pl; pl = pl->next)
904-               {
905-                 const char *no_suffix_multilib_dir;
906+             struct spec_path_info info;
907 
908-                 no_suffix_multilib_dir = pl->os_multilib ? multilib_os_dir
909-                                          : multilib_dir;
910-                 /* Do not separate options, include non-multilibbed variant.  */
911-                 do_spec_path (pl, "-L",
912+             info.option = "-L";
913+             info.append_len = 0;
914 #ifdef RELATIVE_PREFIX_NOT_LINKDIR
915-                               1,
916+             /* Used on systems which record the specified -L dirs
917+                and use them to search for dynamic linking.
918+                Relative directories always come from -B,
919+                and it is better not to use them for searching
920+                at run time.  In particular, stage1 loses.  */
921+             info.omit_relative = true;
922 #else
923-                               0,
924+             info.omit_relative = false;
925 #endif
926-                               0, 0, multilib_dir, no_suffix_multilib_dir);
927-               }
928+             info.separate_options = false;
929+
930+             for_each_path (&startfile_prefixes, true, 0, spec_path, &info);
931            }
932            break;
933 
934@@ -4883,7 +4926,7 @@
935 
936          case 'I':
937            {
938-             struct prefix_list *pl = include_prefixes.plist;
939+             struct spec_path_info info;
940 
941              if (gcc_exec_prefix)
942                {
943@@ -4906,9 +4949,14 @@
944                  do_spec_1 (" ", 0, NULL);
945                }
946 
947-             for (; pl; pl = pl->next)
948-               /* Separate options, don't include non-suffixed variant.  */
949-               do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
950+             info.option = "-isystem";
951+             info.append = "include";
952+             info.append_len = strlen (info.append);
953+             info.omit_relative = false;
954+             info.separate_options = true;
955+
956+             for_each_path (&include_prefixes, false, info.append_len,
957+                            spec_path, &info);
958            }
959            break;
960 
961@@ -5894,48 +5942,27 @@
962 static const char *
963 find_file (const char *name)
964 {
965-  char *newname;
966-
967-  /* Try multilib_dir if it is defined.  */
968-  if (multilib_os_dir != NULL)
969-    {
970-      newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
971-
972-      /* If we don't find it in the multi library dir, then fall
973-        through and look for it in the normal places.  */
974-      if (newname != NULL)
975-       return newname;
976-    }
977-
978-  newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
979+  char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
980   return newname ? newname : name;
981 }
982 
983 /* Determine whether a directory exists.  If LINKER, return 0 for
984-   certain fixed names not needed by the linker.  If not LINKER, it is
985-   only important to return 0 if the host machine has a small ARG_MAX
986-   limit.  */
987+   certain fixed names not needed by the linker.  */
988 
989 static int
990-is_directory (const char *path1, const char *path2, int linker)
991+is_directory (const char *path1, bool linker)
992 {
993-  int len1 = strlen (path1);
994-  int len2 = strlen (path2);
995-  char *path = alloca (3 + len1 + len2);
996+  int len1;
997+  char *path;
998   char *cp;
999   struct stat st;
1000 
1001-#ifndef SMALL_ARG_MAX
1002-  if (! linker)
1003-    return 1;
1004-#endif
1005-
1006-  /* Construct the path from the two parts.  Ensure the string ends with "/.".
1007-     The resulting path will be a directory even if the given path is a
1008-     symbolic link.  */
1009+  /* Ensure the string ends with "/.".  The resulting path will be a
1010+     directory even if the given path is a symbolic link.  */
1011+  len1 = strlen (path1);
1012+  path = alloca (3 + len1);
1013   memcpy (path, path1, len1);
1014-  memcpy (path + len1, path2, len2);
1015-  cp = path + len1 + len2;
1016+  cp = path + len1;
1017   if (!IS_DIR_SEPARATOR (cp[-1]))
1018     *cp++ = DIR_SEPARATOR;
1019   *cp++ = '.';
1020@@ -5943,13 +5970,13 @@
1021 
1022   /* Exclude directories that the linker is known to search.  */
1023   if (linker
1024+      && IS_DIR_SEPARATOR (path[0])
1025       && ((cp - path == 6
1026-          && strcmp (path, concat (dir_separator_str, "lib",
1027-                                   dir_separator_str, ".", NULL)) == 0)
1028+          && strncmp (path + 1, "lib", 3) == 0)
1029          || (cp - path == 10
1030-             && strcmp (path, concat (dir_separator_str, "usr",
1031-                                      dir_separator_str, "lib",
1032-                                      dir_separator_str, ".", NULL)) == 0)))
1033+             && strncmp (path + 1, "usr", 3) == 0
1034+             && IS_DIR_SEPARATOR (path[4])
1035+             && strncmp (path + 5, "lib", 3) == 0)))
1036     return 0;
1037 
1038   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
1039@@ -6139,7 +6166,7 @@
1040                           spec_version, dir_separator_str, NULL);
1041   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
1042 
1043-  specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
1044+  specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
1045   /* Read the specs file unless it is a default one.  */
1046   if (specs_file != 0 && strcmp (specs_file, "specs"))
1047     read_specs (specs_file, TRUE);
1048@@ -6275,7 +6302,7 @@
1049   for (uptr = user_specs_head; uptr; uptr = uptr->next)
1050     {
1051       char *filename = find_a_file (&startfile_prefixes, uptr->filename,
1052-                                   R_OK, 0);
1053+                                   R_OK, true);
1054       read_specs (filename ? filename : uptr->filename, FALSE);
1055     }
1056 
1057@@ -6304,8 +6331,10 @@
1058   if (print_search_dirs)
1059     {
1060       printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
1061-      printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
1062-      printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
1063+      printf (_("programs: %s\n"),
1064+             build_search_list (&exec_prefixes, "", false, false));
1065+      printf (_("libraries: %s\n"),
1066+             build_search_list (&startfile_prefixes, "", false, true));
1067       return (0);
1068     }
1069 
1070@@ -6622,14 +6651,14 @@
1071       /* We'll use ld if we can't find collect2.  */
1072       if (! strcmp (linker_name_spec, "collect2"))
1073        {
1074-         char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0);
1075+         char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
1076          if (s == NULL)
1077            linker_name_spec = "ld";
1078        }
1079       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
1080         for collect.  */
1081-      putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH");
1082-      putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV);
1083+      putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
1084+      putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
1085 
1086       value = do_spec (link_command_spec);
1087       if (value < 0)
1088diff -uNr gcc-4.1.0/gcc/system.h gcc-4.1.0-PR20425/gcc/system.h
1089--- gcc-4.1.0/gcc/system.h      2005-08-16 10:13:53.000000000 +1000
1090+++ gcc-4.1.0-PR20425/gcc/system.h      2006-03-10 23:51:31.000000000 +1100
1091@@ -728,7 +728,8 @@
1092         TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT          \
1093         LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE               \
1094        TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC         \
1095-       PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF
1096+       PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF            \
1097+       SMALL_ARG_MAX
1098 
1099 /* Hooks that are no longer used.  */
1100  #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE  \
Note: See TracBrowser for help on using the repository browser.