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

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since ed3a13d4 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
RevLine 
[ad31873f]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
265-/* Build a list of search directories from PATHS.
266- PREFIX is a string to prepend to the list.
267- If CHECK_DIR_P is nonzero we ensure the directory exists.
268- This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
269- It is also used by the --print-search-dirs flag. */
270-
271-static char *
272-build_search_list (struct path_prefix *paths, const char *prefix,
273- int check_dir_p)
274+/* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
275+ returns non-NULL.
276+ If DO_MULTI is true iterate over the paths twice, first with multilib
277+ suffix then without, otherwise iterate over the paths once without
278+ adding a multilib suffix. When DO_MULTI is true, some attempt is made
279+ to avoid visiting the same path twice, but we could do better. For
280+ instance, /usr/lib/../lib is considered different from /usr/lib.
281+ At least EXTRA_SPACE chars past the end of the path passed to
282+ CALLBACK are available for use by the callback.
283+ CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
284+
285+ Returns the value returned by CALLBACK. */
286+
287+static void *
288+for_each_path (const struct path_prefix *paths,
289+ bool do_multi,
290+ size_t extra_space,
291+ void *(*callback) (char *, void *),
292+ void *callback_info)
293 {
294- int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
295- int just_suffix_len
296- = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
297- int first_time = TRUE;
298- struct prefix_list *pprefix;
299-
300- obstack_grow (&collect_obstack, prefix, strlen (prefix));
301- obstack_1grow (&collect_obstack, '=');
302+ struct prefix_list *pl;
303+ const char *multi_dir = NULL;
304+ const char *multi_os_dir = NULL;
305+ const char *multi_suffix;
306+ const char *just_multi_suffix;
307+ char *path = NULL;
308+ void *ret = NULL;
309+ bool skip_multi_dir = false;
310+ bool skip_multi_os_dir = false;
311+
312+ multi_suffix = machine_suffix;
313+ just_multi_suffix = just_machine_suffix;
314+ if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
315+ {
316+ multi_dir = concat (multilib_dir, dir_separator_str, NULL);
317+ multi_suffix = concat (multi_suffix, multi_dir, NULL);
318+ just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
319+ }
320+ if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
321+ multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
322
323- for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
324+ while (1)
325 {
326- int len = strlen (pprefix->prefix);
327+ size_t multi_dir_len = 0;
328+ size_t multi_os_dir_len = 0;
329+ size_t suffix_len;
330+ size_t just_suffix_len;
331+ size_t len;
332+
333+ if (multi_dir)
334+ multi_dir_len = strlen (multi_dir);
335+ if (multi_os_dir)
336+ multi_os_dir_len = strlen (multi_os_dir);
337+ suffix_len = strlen (multi_suffix);
338+ just_suffix_len = strlen (just_multi_suffix);
339+
340+ if (path == NULL)
341+ {
342+ len = paths->max_len + extra_space + 1;
343+ if (suffix_len > multi_os_dir_len)
344+ len += suffix_len;
345+ else
346+ len += multi_os_dir_len;
347+ path = xmalloc (len);
348+ }
349
350- if (machine_suffix
351- && (! check_dir_p
352- || is_directory (pprefix->prefix, machine_suffix, 0)))
353+ for (pl = paths->plist; pl != 0; pl = pl->next)
354 {
355- if (!first_time)
356- obstack_1grow (&collect_obstack, PATH_SEPARATOR);
357+ len = strlen (pl->prefix);
358+ memcpy (path, pl->prefix, len);
359
360- first_time = FALSE;
361- obstack_grow (&collect_obstack, pprefix->prefix, len);
362- obstack_grow (&collect_obstack, machine_suffix, suffix_len);
363- }
364+ /* Look first in MACHINE/VERSION subdirectory. */
365+ if (!skip_multi_dir)
366+ {
367+ memcpy (path + len, multi_suffix, suffix_len + 1);
368+ ret = callback (path, callback_info);
369+ if (ret)
370+ break;
371+ }
372
373- if (just_machine_suffix
374- && pprefix->require_machine_suffix == 2
375- && (! check_dir_p
376- || is_directory (pprefix->prefix, just_machine_suffix, 0)))
377- {
378- if (! first_time)
379- obstack_1grow (&collect_obstack, PATH_SEPARATOR);
380+ /* Some paths are tried with just the machine (ie. target)
381+ subdir. This is used for finding as, ld, etc. */
382+ if (!skip_multi_dir
383+ && pl->require_machine_suffix == 2)
384+ {
385+ memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
386+ ret = callback (path, callback_info);
387+ if (ret)
388+ break;
389+ }
390+
391+ /* Now try the base path. */
392+ if (!pl->require_machine_suffix
393+ && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
394+ {
395+ const char *this_multi;
396+ size_t this_multi_len;
397+
398+ if (pl->os_multilib)
399+ {
400+ this_multi = multi_os_dir;
401+ this_multi_len = multi_os_dir_len;
402+ }
403+ else
404+ {
405+ this_multi = multi_dir;
406+ this_multi_len = multi_dir_len;
407+ }
408
409- first_time = FALSE;
410- obstack_grow (&collect_obstack, pprefix->prefix, len);
411- obstack_grow (&collect_obstack, just_machine_suffix,
412- just_suffix_len);
413+ if (this_multi_len)
414+ memcpy (path + len, this_multi, this_multi_len + 1);
415+ else
416+ path[len] = '\0';
417+
418+ ret = callback (path, callback_info);
419+ if (ret)
420+ break;
421+ }
422 }
423+ if (pl)
424+ break;
425
426- if (! pprefix->require_machine_suffix)
427- {
428- if (! first_time)
429- obstack_1grow (&collect_obstack, PATH_SEPARATOR);
430+ if (multi_dir == NULL && multi_os_dir == NULL)
431+ break;
432
433- first_time = FALSE;
434- obstack_grow (&collect_obstack, pprefix->prefix, len);
435+ /* Run through the paths again, this time without multilibs.
436+ Don't repeat any we have already seen. */
437+ if (multi_dir)
438+ {
439+ free ((char *) multi_dir);
440+ multi_dir = NULL;
441+ free ((char *) multi_suffix);
442+ multi_suffix = machine_suffix;
443+ free ((char *) just_multi_suffix);
444+ just_multi_suffix = just_machine_suffix;
445+ }
446+ else
447+ skip_multi_dir = true;
448+ if (multi_os_dir)
449+ {
450+ free ((char *) multi_os_dir);
451+ multi_os_dir = NULL;
452 }
453+ else
454+ skip_multi_os_dir = true;
455 }
456
457+ if (multi_dir)
458+ {
459+ free ((char *) multi_dir);
460+ free ((char *) multi_suffix);
461+ free ((char *) just_multi_suffix);
462+ }
463+ if (multi_os_dir)
464+ free ((char *) multi_os_dir);
465+ if (ret != path)
466+ free (path);
467+ return ret;
468+}
469+
470+/* Callback for build_search_list. Adds path to obstack being built. */
471+
472+struct add_to_obstack_info {
473+ struct obstack *ob;
474+ bool check_dir;
475+ bool first_time;
476+};
477+
478+static void *
479+add_to_obstack (char *path, void *data)
480+{
481+ struct add_to_obstack_info *info = data;
482+
483+ if (info->check_dir && !is_directory (path, false))
484+ return NULL;
485+
486+ if (!info->first_time)
487+ obstack_1grow (info->ob, PATH_SEPARATOR);
488+
489+ obstack_grow (info->ob, path, strlen (path));
490+
491+ info->first_time = false;
492+ return NULL;
493+}
494+
495+/* Build a list of search directories from PATHS.
496+ PREFIX is a string to prepend to the list.
497+ If CHECK_DIR_P is true we ensure the directory exists.
498+ If DO_MULTI is true, multilib paths are output first, then
499+ non-multilib paths.
500+ This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
501+ It is also used by the --print-search-dirs flag. */
502+
503+static char *
504+build_search_list (const struct path_prefix *paths, const char *prefix,
505+ bool check_dir, bool do_multi)
506+{
507+ struct add_to_obstack_info info;
508+
509+ info.ob = &collect_obstack;
510+ info.check_dir = check_dir;
511+ info.first_time = true;
512+
513+ obstack_grow (&collect_obstack, prefix, strlen (prefix));
514+ obstack_1grow (&collect_obstack, '=');
515+
516+ for_each_path (paths, do_multi, 0, add_to_obstack, &info);
517+
518 obstack_1grow (&collect_obstack, '\0');
519 return XOBFINISH (&collect_obstack, char *);
520 }
521@@ -2419,9 +2569,10 @@
522 for collect. */
523
524 static void
525-putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
526+putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
527+ bool do_multi)
528 {
529- putenv (build_search_list (paths, env_var, 1));
530+ putenv (build_search_list (paths, env_var, true, do_multi));
531 }
532
533
534 /* Check whether NAME can be accessed in MODE. This is like access,
535@@ -2442,20 +2593,53 @@
536 return access (name, mode);
537 }
538
539+/* Callback for find_a_file. Appends the file name to the directory
540+ path. If the resulting file exists in the right mode, return the
541+ full pathname to the file. */
542+
543+struct file_at_path_info {
544+ const char *name;
545+ const char *suffix;
546+ int name_len;
547+ int suffix_len;
548+ int mode;
549+};
550+
551+static void *
552+file_at_path (char *path, void *data)
553+{
554+ struct file_at_path_info *info = data;
555+ size_t len = strlen (path);
556+
557+ memcpy (path + len, info->name, info->name_len);
558+ len += info->name_len;
559+
560+ /* Some systems have a suffix for executable files.
561+ So try appending that first. */
562+ if (info->suffix_len)
563+ {
564+ memcpy (path + len, info->suffix, info->suffix_len + 1);
565+ if (access_check (path, info->mode) == 0)
566+ return path;
567+ }
568+
569+ path[len] = '\0';
570+ if (access_check (path, info->mode) == 0)
571+ return path;
572+
573+ return NULL;
574+}
575+
576 /* Search for NAME using the prefix list PREFIXES. MODE is passed to
577- access to check permissions.
578+ access to check permissions. If DO_MULTI is true, search multilib
579+ paths then non-multilib paths, otherwise do not search multilib paths.
580 Return 0 if not found, otherwise return its name, allocated with malloc. */
581
582 static char *
583-find_a_file (struct path_prefix *pprefix, const char *name, int mode,
584- int multilib)
585+find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
586+ bool do_multi)
587 {
588- char *temp;
589- const char *const file_suffix =
590- ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
591- struct prefix_list *pl;
592- int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
593- const char *multilib_name, *multilib_os_name;
594+ struct file_at_path_info info;
595
596 #ifdef DEFAULT_ASSEMBLER
597 if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
598@@ -2467,112 +2651,24 @@
599 return xstrdup (DEFAULT_LINKER);
600 #endif
601
602- if (machine_suffix)
603- len += strlen (machine_suffix);
604-
605- multilib_name = name;
606- multilib_os_name = name;
607- if (multilib && multilib_os_dir)
608- {
609- int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
610- int len2 = strlen (multilib_os_dir) + 1;
611-
612- len += len1 > len2 ? len1 : len2;
613- if (multilib_dir)
614- multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
615- NULL));
616- if (strcmp (multilib_os_dir, ".") != 0)
617- multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
618- NULL));
619- }
620-
621- temp = xmalloc (len);
622-
623 /* Determine the filename to execute (special case for absolute paths). */
624
625 if (IS_ABSOLUTE_PATH (name))
626 {
627 if (access (name, mode) == 0)
628- {
629- strcpy (temp, name);
630- return temp;
631- }
632- }
633- else
634- for (pl = pprefix->plist; pl; pl = pl->next)
635- {
636- const char *this_name
637- = pl->os_multilib ? multilib_os_name : multilib_name;
638+ return xstrdup (name);
639
640- if (machine_suffix)
641- {
642- /* Some systems have a suffix for executable files.
643- So try appending that first. */
644- if (file_suffix[0] != 0)
645- {
646- strcpy (temp, pl->prefix);
647- strcat (temp, machine_suffix);
648- strcat (temp, multilib_name);
649- strcat (temp, file_suffix);
650- if (access_check (temp, mode) == 0)
651- return temp;
652- }
653-
654- /* Now try just the multilib_name. */
655- strcpy (temp, pl->prefix);
656- strcat (temp, machine_suffix);
657- strcat (temp, multilib_name);
658- if (access_check (temp, mode) == 0)
659- return temp;
660- }
661-
662- /* Certain prefixes are tried with just the machine type,
663- not the version. This is used for finding as, ld, etc. */
664- if (just_machine_suffix && pl->require_machine_suffix == 2)
665- {
666- /* Some systems have a suffix for executable files.
667- So try appending that first. */
668- if (file_suffix[0] != 0)
669- {
670- strcpy (temp, pl->prefix);
671- strcat (temp, just_machine_suffix);
672- strcat (temp, multilib_name);
673- strcat (temp, file_suffix);
674- if (access_check (temp, mode) == 0)
675- return temp;
676- }
677-
678- strcpy (temp, pl->prefix);
679- strcat (temp, just_machine_suffix);
680- strcat (temp, multilib_name);
681- if (access_check (temp, mode) == 0)
682- return temp;
683- }
684-
685- /* Certain prefixes can't be used without the machine suffix
686- when the machine or version is explicitly specified. */
687- if (! pl->require_machine_suffix)
688- {
689- /* Some systems have a suffix for executable files.
690- So try appending that first. */
691- if (file_suffix[0] != 0)
692- {
693- strcpy (temp, pl->prefix);
694- strcat (temp, this_name);
695- strcat (temp, file_suffix);
696- if (access_check (temp, mode) == 0)
697- return temp;
698- }
699+ return NULL;
700+ }
701
702- strcpy (temp, pl->prefix);
703- strcat (temp, this_name);
704- if (access_check (temp, mode) == 0)
705- return temp;
706- }
707- }
708+ info.name = name;
709+ info.suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
710+ info.name_len = strlen (info.name);
711+ info.suffix_len = strlen (info.suffix);
712+ info.mode = mode;
713
714- free (temp);
715- return 0;
716+ return for_each_path (pprefix, do_multi, info.name_len + info.suffix_len,
717+ file_at_path, &info);
718 }
719
720 /* Ranking of prefixes in the sort list. -B prefixes are put before
721@@ -2691,7 +2787,7 @@
722
723 commands[0].prog = argbuf[0]; /* first command. */
724 commands[0].argv = &argbuf[0];
725- string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
726+ string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, false);
727
728 if (string)
729 commands[0].argv[0] = string;
730@@ -2706,7 +2802,7 @@
731 commands[n_commands].prog = argbuf[i + 1];
732 commands[n_commands].argv = &argbuf[i + 1];
733 string = find_a_file (&exec_prefixes, commands[n_commands].prog,
734- X_OK, 0);
735+ X_OK, false);
736 if (string)
737 commands[n_commands].argv[0] = string;
738 n_commands++;
739@@ -3643,7 +3739,7 @@
740 if appending a directory separator actually makes a
741 valid directory name. */
742 if (! IS_DIR_SEPARATOR (value [len - 1])
743- && is_directory (value, "", 0))
744+ && is_directory (value, false))
745 {
746 char *tmp = xmalloc (len + 2);
747 strcpy (tmp, value);
748@@ -4391,108 +4487,55 @@
749 }
750 }
751
752-void
753-do_spec_path (struct prefix_list *pl, const char *option,
754- int omit_if_relative, int separate_options,
755- int only_subdir,
756- const char *dir_for_machine_suffix,
757- const char *dir_for_no_suffix)
758-{
759- static size_t bufsize = 0;
760- static char *buffer;
761- int idx;
762- bool multilib_p = false;
763-
764- /* Used on systems which record the specified -L dirs
765- and use them to search for dynamic linking. */
766- /* Relative directories always come from -B,
767- and it is better not to use them for searching
768- at run time. In particular, stage1 loses. */
769- if (omit_if_relative
770- && !IS_ABSOLUTE_PATH (pl->prefix))
771- return;
772+/* Callback for processing %D and %I specs. */
773
774- /* Try subdirectory if there is one. */
775- if (machine_suffix && dir_for_machine_suffix)
776- {
777- if (strlen (pl->prefix) + strlen (machine_suffix)
778- >= bufsize)
779- bufsize = (strlen (pl->prefix)
780- + strlen (machine_suffix)) * 2 + 1;
781- buffer = xrealloc (buffer, bufsize);
782- strcpy (buffer, pl->prefix);
783- strcat (buffer, machine_suffix);
784- if (is_directory (buffer, dir_for_machine_suffix, 1))
785- {
786- multilib_p = true;
787- do_spec_1 (option, separate_options, NULL);
788- if (separate_options)
789- do_spec_1 (" ", 0, NULL);
790- do_spec_1 (buffer, 1, NULL);
791- do_spec_1 (dir_for_machine_suffix, 1, NULL);
792- /* Make this a separate argument. */
793- do_spec_1 (" ", 0, NULL);
794- }
795- }
796- if (!pl->require_machine_suffix && dir_for_no_suffix)
797+struct spec_path_info {
798+ const char *option;
799+ const char *append;
800+ size_t append_len;
801+ bool omit_relative;
802+ bool separate_options;
803+};
804+
805+static void *
806+spec_path (char *path, void *data)
807+{
808+ struct spec_path_info *info = data;
809+ size_t len = 0;
810+ char save = 0;
811+
812+ if (info->omit_relative && !IS_ABSOLUTE_PATH (path))
813+ return NULL;
814+
815+ if (info->append_len != 0)
816 {
817- if (is_directory (pl->prefix, dir_for_no_suffix, 1))
818- {
819- multilib_p = true;
820- do_spec_1 (option, separate_options, NULL);
821- if (separate_options)
822- do_spec_1 (" ", 0, NULL);
823- do_spec_1 (pl->prefix, 1, NULL);
824- do_spec_1 (dir_for_no_suffix, 1, NULL);
825- /* Make this a separate argument. */
826- do_spec_1 (" ", 0, NULL);
827- }
828+ len = strlen (path);
829+ memcpy (path + len, info->append, info->append_len + 1);
830 }
831
832- if (only_subdir || multilib_p)
833- return;
834+ if (!is_directory (path, true))
835+ return NULL;
836+
837+ do_spec_1 (info->option, 1, NULL);
838+ if (info->separate_options)
839+ do_spec_1 (" ", 0, NULL);
840
841- if (machine_suffix)
842+ if (info->append_len == 0)
843 {
844- if (is_directory (pl->prefix, machine_suffix, 1))
845- {
846- do_spec_1 (option, separate_options, NULL);
847- if (separate_options)
848- do_spec_1 (" ", 0, NULL);
849- do_spec_1 (pl->prefix, 1, NULL);
850- /* Remove slash from machine_suffix. */
851- if (strlen (machine_suffix) >= bufsize)
852- bufsize = strlen (machine_suffix) * 2 + 1;
853- buffer = xrealloc (buffer, bufsize);
854- strcpy (buffer, machine_suffix);
855- idx = strlen (buffer);
856- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
857- buffer[idx - 1] = 0;
858- do_spec_1 (buffer, 1, NULL);
859- /* Make this a separate argument. */
860- do_spec_1 (" ", 0, NULL);
861- }
862- }
863- if (!pl->require_machine_suffix)
864- {
865- if (is_directory (pl->prefix, "", 1))
866- {
867- do_spec_1 (option, separate_options, NULL);
868- if (separate_options)
869- do_spec_1 (" ", 0, NULL);
870- /* Remove slash from pl->prefix. */
871- if (strlen (pl->prefix) >= bufsize)
872- bufsize = strlen (pl->prefix) * 2 + 1;
873- buffer = xrealloc (buffer, bufsize);
874- strcpy (buffer, pl->prefix);
875- idx = strlen (buffer);
876- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
877- buffer[idx - 1] = 0;
878- do_spec_1 (buffer, 1, NULL);
879- /* Make this a separate argument. */
880- do_spec_1 (" ", 0, NULL);
881- }
882+ len = strlen (path);
883+ save = path[len - 1];
884+ if (IS_DIR_SEPARATOR (path[len - 1]))
885+ path[len - 1] = '\0';
886 }
887+
888+ do_spec_1 (path, 1, NULL);
889+ do_spec_1 (" ", 0, NULL);
890+
891+ /* Must not damage the original path. */
892+ if (info->append_len == 0)
893+ path[len - 1] = save;
894+
895+ return NULL;
896 }
897
898 /* Process the sub-spec SPEC as a portion of a larger spec.
899@@ -4630,23 +4673,23 @@
900 that we search for startfiles. */
901 case 'D':
902 {
903- struct prefix_list *pl = startfile_prefixes.plist;
904-
905- for (; pl; pl = pl->next)
906- {
907- const char *no_suffix_multilib_dir;
908+ struct spec_path_info info;
909
910- no_suffix_multilib_dir = pl->os_multilib ? multilib_os_dir
911- : multilib_dir;
912- /* Do not separate options, include non-multilibbed variant. */
913- do_spec_path (pl, "-L",
914+ info.option = "-L";
915+ info.append_len = 0;
916 #ifdef RELATIVE_PREFIX_NOT_LINKDIR
917- 1,
918+ /* Used on systems which record the specified -L dirs
919+ and use them to search for dynamic linking.
920+ Relative directories always come from -B,
921+ and it is better not to use them for searching
922+ at run time. In particular, stage1 loses. */
923+ info.omit_relative = true;
924 #else
925- 0,
926+ info.omit_relative = false;
927 #endif
928- 0, 0, multilib_dir, no_suffix_multilib_dir);
929- }
930+ info.separate_options = false;
931+
932+ for_each_path (&startfile_prefixes, true, 0, spec_path, &info);
933 }
934 break;
935
936@@ -4883,7 +4926,7 @@
937
938 case 'I':
939 {
940- struct prefix_list *pl = include_prefixes.plist;
941+ struct spec_path_info info;
942
943 if (gcc_exec_prefix)
944 {
945@@ -4906,9 +4949,14 @@
946 do_spec_1 (" ", 0, NULL);
947 }
948
949- for (; pl; pl = pl->next)
950- /* Separate options, don't include non-suffixed variant. */
951- do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
952+ info.option = "-isystem";
953+ info.append = "include";
954+ info.append_len = strlen (info.append);
955+ info.omit_relative = false;
956+ info.separate_options = true;
957+
958+ for_each_path (&include_prefixes, false, info.append_len,
959+ spec_path, &info);
960 }
961 break;
962
963@@ -5894,48 +5942,27 @@
964 static const char *
965 find_file (const char *name)
966 {
967- char *newname;
968-
969- /* Try multilib_dir if it is defined. */
970- if (multilib_os_dir != NULL)
971- {
972- newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
973-
974- /* If we don't find it in the multi library dir, then fall
975- through and look for it in the normal places. */
976- if (newname != NULL)
977- return newname;
978- }
979-
980- newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
981+ char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
982 return newname ? newname : name;
983 }
984
985 /* Determine whether a directory exists. If LINKER, return 0 for
986- certain fixed names not needed by the linker. If not LINKER, it is
987- only important to return 0 if the host machine has a small ARG_MAX
988- limit. */
989+ certain fixed names not needed by the linker. */
990
991 static int
992-is_directory (const char *path1, const char *path2, int linker)
993+is_directory (const char *path1, bool linker)
994 {
995- int len1 = strlen (path1);
996- int len2 = strlen (path2);
997- char *path = alloca (3 + len1 + len2);
998+ int len1;
999+ char *path;
1000 char *cp;
1001 struct stat st;
1002
1003-#ifndef SMALL_ARG_MAX
1004- if (! linker)
1005- return 1;
1006-#endif
1007-
1008- /* Construct the path from the two parts. Ensure the string ends with "/.".
1009- The resulting path will be a directory even if the given path is a
1010- symbolic link. */
1011+ /* Ensure the string ends with "/.". The resulting path will be a
1012+ directory even if the given path is a symbolic link. */
1013+ len1 = strlen (path1);
1014+ path = alloca (3 + len1);
1015 memcpy (path, path1, len1);
1016- memcpy (path + len1, path2, len2);
1017- cp = path + len1 + len2;
1018+ cp = path + len1;
1019 if (!IS_DIR_SEPARATOR (cp[-1]))
1020 *cp++ = DIR_SEPARATOR;
1021 *cp++ = '.';
1022@@ -5943,13 +5970,13 @@
1023
1024 /* Exclude directories that the linker is known to search. */
1025 if (linker
1026+ && IS_DIR_SEPARATOR (path[0])
1027 && ((cp - path == 6
1028- && strcmp (path, concat (dir_separator_str, "lib",
1029- dir_separator_str, ".", NULL)) == 0)
1030+ && strncmp (path + 1, "lib", 3) == 0)
1031 || (cp - path == 10
1032- && strcmp (path, concat (dir_separator_str, "usr",
1033- dir_separator_str, "lib",
1034- dir_separator_str, ".", NULL)) == 0)))
1035+ && strncmp (path + 1, "usr", 3) == 0
1036+ && IS_DIR_SEPARATOR (path[4])
1037+ && strncmp (path + 5, "lib", 3) == 0)))
1038 return 0;
1039
1040 return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
1041@@ -6139,7 +6166,7 @@
1042 spec_version, dir_separator_str, NULL);
1043 just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
1044
1045- specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
1046+ specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
1047 /* Read the specs file unless it is a default one. */
1048 if (specs_file != 0 && strcmp (specs_file, "specs"))
1049 read_specs (specs_file, TRUE);
1050@@ -6275,7 +6302,7 @@
1051 for (uptr = user_specs_head; uptr; uptr = uptr->next)
1052 {
1053 char *filename = find_a_file (&startfile_prefixes, uptr->filename,
1054- R_OK, 0);
1055+ R_OK, true);
1056 read_specs (filename ? filename : uptr->filename, FALSE);
1057 }
1058
1059@@ -6304,8 +6331,10 @@
1060 if (print_search_dirs)
1061 {
1062 printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
1063- printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
1064- printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
1065+ printf (_("programs: %s\n"),
1066+ build_search_list (&exec_prefixes, "", false, false));
1067+ printf (_("libraries: %s\n"),
1068+ build_search_list (&startfile_prefixes, "", false, true));
1069 return (0);
1070 }
1071
1072@@ -6622,14 +6651,14 @@
1073 /* We'll use ld if we can't find collect2. */
1074 if (! strcmp (linker_name_spec, "collect2"))
1075 {
1076- char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0);
1077+ char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
1078 if (s == NULL)
1079 linker_name_spec = "ld";
1080 }
1081 /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
1082 for collect. */
1083- putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH");
1084- putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV);
1085+ putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
1086+ putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
1087
1088 value = do_spec (link_command_spec);
1089 if (value < 0)
1090diff -uNr gcc-4.1.0/gcc/system.h gcc-4.1.0-PR20425/gcc/system.h
1091--- gcc-4.1.0/gcc/system.h 2005-08-16 10:13:53.000000000 +1000
1092+++ gcc-4.1.0-PR20425/gcc/system.h 2006-03-10 23:51:31.000000000 +1100
1093@@ -728,7 +728,8 @@
1094 TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT \
1095 LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE \
1096 TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC \
1097- PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF
1098+ PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF \
1099+ SMALL_ARG_MAX
1100
1101 /* Hooks that are no longer used. */
1102 #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
Note: See TracBrowser for help on using the repository browser.