source:
scripts/patches/gcc-4.1.0-fix_PR20425.patch@
cb92ef5
Last change on this file since cb92ef5 was ad31873f, checked in by , 19 years ago | |
---|---|
|
|
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 1 2006-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 1 29 2006-02-28 Release Manager 2 30 3 31 * 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 90 90 build_install_headers_dir=install-headers-cpio 91 91 ;; 92 92 i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* ) 93 build_xm_defines="SMALL_ARG_MAX"94 93 build_install_headers_dir=install-headers-cpio 95 94 ;; 96 i[34567]86-*-solaris2*)97 build_xm_defines="SMALL_ARG_MAX"98 ;;99 95 i[34567]86-*-sysv4*) 100 96 # Intel x86 running system V r4 101 build_xm_defines="SMALL_ARG_MAX"102 97 build_install_headers_dir=install-headers-cpio 103 98 ;; 104 99 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 994 994 then 995 995 tm_file="${tm_file} usegas.h" 996 996 fi 997 xm_defines="SMALL_ARG_MAX"998 997 tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ptx4.h i386/ptx4-i.h" 999 998 tmake_file=t-svr4 1000 999 extra_parts="crtbegin.o crtend.o" … … 1125 1124 use_fixproto=yes 1126 1125 ;; 1127 1126 i[34567]86-*-solaris2*) 1128 xm_defines="SMALL_ARG_MAX"1129 1127 tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h" 1130 1128 case ${target} in 1131 1129 *-*-solaris2.[0-6] | *-*-solaris2.[0-6].*) … … 1192 1190 use_fixproto=yes 1193 1191 ;; 1194 1192 i[34567]86-*-sysv4*) # Intel 80386's running system V.4 1195 xm_defines="SMALL_ARG_MAX"1196 1193 tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h" 1197 1194 if test x$stabs = xyes 1198 1195 then -
gcc/config.host
diff -uNr gcc-4.1.0/gcc/config.host gcc-4.1.0-PR20425/gcc/config.host
old new 135 135 i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture 136 136 host_xm_defines='FATAL_EXIT_CODE=12' 137 137 ;; 138 i[34567]86-sequent-ptx4*)139 host_xm_defines="SMALL_ARG_MAX"140 ;;141 138 i[34567]86-*-solaris2*) 142 host_xm_defines="SMALL_ARG_MAX"143 139 out_host_hook_obj=host-solaris.o 144 140 host_xmake_file=x-solaris 145 141 ;; 146 i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4147 host_xm_defines="SMALL_ARG_MAX"148 ;;149 142 i[34567]86-pc-msdosdjgpp*) 150 143 host_xm_file=i386/xm-djgpp.h 151 144 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 208 208 If defined, a C statement (sans semicolon) that performs host-dependent 209 209 initialization when a compilation driver is being initialized. 210 210 211 @item SMALL_ARG_MAX212 Define this macro if the host system has a small limit on the total213 size of an argument vector. This causes the driver to take more care214 not to pass unnecessary arguments to subprocesses.215 216 211 @item HOST_LONG_LONG_FORMAT 217 212 If defined, the string used to indicate an argument of type @code{long 218 213 long} 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 287 287 static void read_specs (const char *, int); 288 288 static void set_spec (const char *, const char *); 289 289 static 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 *); 290 static char *build_search_list (const struct path_prefix *, const char *, 291 bool, bool); 292 static void putenv_from_prefixes (const struct path_prefix *, const char *, 293 bool); 292 294 static int access_check (const char *, int); 293 static char *find_a_file ( struct path_prefix *, const char *, int, int);295 static char *find_a_file (const struct path_prefix *, const char *, int, bool); 294 296 static void add_prefix (struct path_prefix *, const char *, const char *, 295 297 int, int, int); 296 298 static void add_sysrooted_prefix (struct path_prefix *, const char *, … … 313 315 static const char *handle_spec_function (const char *); 314 316 static char *save_string (const char *, int); 315 317 static void set_collect_gcc_options (void); 316 static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);317 318 static int do_spec_1 (const char *, int, const char *); 318 319 static int do_spec_2 (const char *); 319 320 static void do_option_spec (const char *, const char *); 320 321 static void do_self_spec (const char *); 321 322 static const char *find_file (const char *); 322 static int is_directory (const char *, const char *, int);323 static int is_directory (const char *, bool); 323 324 static const char *validate_switches (const char *); 324 325 static void validate_all_switches (void); 325 326 static inline void validate_switches_from_spec (const char *); … … 2036 2037 (long) (p1 - buffer + 1)); 2037 2038 2038 2039 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); 2040 2041 read_specs (new_filename ? new_filename : p1, FALSE); 2041 2042 continue; 2042 2043 } … … 2055 2056 (long) (p1 - buffer + 1)); 2056 2057 2057 2058 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); 2059 2060 if (new_filename) 2060 2061 read_specs (new_filename, FALSE); 2061 2062 else if (verbose_flag) … … 2352 2353 failure_delete_queue = 0; 2353 2354 } 2354 2355 2355 2356 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 2370 static void * 2371 for_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) 2365 2376 { 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); 2374 2397 2375 for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)2398 while (1) 2376 2399 { 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 } 2378 2422 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) 2382 2424 { 2383 if (!first_time)2384 obstack_1grow (&collect_obstack, PATH_SEPARATOR);2425 len = strlen (pl->prefix); 2426 memcpy (path, pl->prefix, len); 2385 2427 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 } 2390 2436 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 } 2398 2465 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 } 2403 2475 } 2476 if (pl) 2477 break; 2404 2478 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; 2409 2481 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; 2412 2499 } 2500 else 2501 skip_multi_os_dir = true; 2413 2502 } 2414 2503 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 2519 struct add_to_obstack_info { 2520 struct obstack *ob; 2521 bool check_dir; 2522 bool first_time; 2523 }; 2524 2525 static void * 2526 add_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 2550 static char * 2551 build_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 2415 2565 obstack_1grow (&collect_obstack, '\0'); 2416 2566 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 728 728 TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT \ 729 729 LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE \ 730 730 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 732 733 733 734 /* Hooks that are no longer used. */ 734 735 #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
Note:
See TracBrowser
for help on using the repository browser.