This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PR 6753
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Sat, 9 Aug 2008 19:39:23 +0930
- Subject: PR 6753
This patch is a result of my analysis of PR6753, a complaint that the
library search order is different when specifying a script with -T as
compared to using the same script as the default. It turns out that
the claim is true for directories specified in a script SEARCH_DIR,
but not, I think, for -L directories, unless of course the user places
the -T option in the middle of -L options. The problem is caused by
set_scripts_dir, a function that finds the location of ldscripts/ and
adds that directory to the linker search path, before parsing the
default script. Typically, ldscripts/ is found in
$prefix/$target_alias/lib/, but can live in other places. For
instance it is possible to put ldscripts in /usr/lib. Call the
location of ldscripts/, $scriptdir. If the user specifies a script
using -T (after any -L dirs!), the search order is:
-L directories, script SEARCH_DIRs, $scriptdir
If you allow the linker to find the script, the search order is:
-L directories, $scriptdir, script SEARCH_DIRs.
set_scripts_dir gets called even when the linker scripts are built-in
and there's no need to go looking in the file system.
I think that messing with the library search directories like this is
rather nasty, so let's not do that any more. I've also fixed another
bug. "ld -nostdlib" used to throw away the ldscripts/ directory,
potentially resulting in the linker not being able to find its linker
scripts.
* ldmain.c (check_for_scripts_dir, set_scripts_dir): Delete.
(main): Don't set_scripts_dir here.
* ldfile.c (check_for_scripts_dir, find_scripts_dir): New functions,
largely based on ldmain.c versions.
(ldfile_find_command_file): Set up search in script dir here without
affecting library search.
* Makefile.am (ldmain.o): No need to define SCRIPTDIR.
(ldfile.o): New rule.
* Makefile.in: Regenerate.
Index: ld/Makefile.am
===================================================================
RCS file: /cvs/src/src/ld/Makefile.am,v
retrieving revision 1.251
diff -u -p -r1.251 Makefile.am
--- ld/Makefile.am 4 Aug 2008 06:55:32 -0000 1.251
+++ ld/Makefile.am 9 Aug 2008 04:58:52 -0000
@@ -464,11 +464,15 @@ po/POTFILES.in: @MAINT@ Makefile
ldmain.o: ldmain.c config.status
$(COMPILE) -c -DDEFAULT_EMULATION='"$(EMUL)"' \
- -DSCRIPTDIR='"$(scriptdir)"' -DBINDIR='"$(bindir)"' \
- -DTOOLBINDIR='"$(tooldir)/bin"' \
+ -DBINDIR='"$(bindir)"' -DTOOLBINDIR='"$(tooldir)/bin"' \
-DTARGET='"@target@"' @TARGET_SYSTEM_ROOT_DEFINE@ \
$(srcdir)/ldmain.c
+ldfile.o: ldfile.c config.status
+ $(COMPILE) -c -DSCRIPTDIR='"$(scriptdir)"' \
+ -DBINDIR='"$(bindir)"' -DTOOLBINDIR='"$(tooldir)/bin"' \
+ $(srcdir)/ldfile.c
+
eelf32_spu.o: eelf32_spu.c
$(COMPILE) -c -DEMBEDSPU="\"`echo embedspu | sed '$(transform)'`\"" \
eelf32_spu.c
Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.46
diff -u -p -r1.46 ldfile.c
--- ld/ldfile.c 8 Aug 2008 08:06:16 -0000 1.46
+++ ld/ldfile.c 9 Aug 2008 09:45:13 -0000
@@ -456,30 +456,134 @@ try_open (const char *name, const char *
return result;
}
-/* Try to open NAME; if that fails, look for it in any directories
- specified with -L, without and with EXTEND appended. */
+/* Return TRUE iff directory DIR contains an "ldscripts" subdirectory. */
+
+static bfd_boolean
+check_for_scripts_dir (char *dir)
+{
+ char *buf;
+ struct stat s;
+ bfd_boolean res;
+
+ buf = concat (dir, "/ldscripts", (const char *) NULL);
+ res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
+ free (buf);
+ return res;
+}
+
+/* Return the default directory for finding script files.
+ We look for the "ldscripts" directory in:
+
+ SCRIPTDIR (passed from Makefile)
+ (adjusted according to the current location of the binary)
+ SCRIPTDIR (passed from Makefile)
+ the dir where this program is (for using it from the build tree)
+ the dir where this program is/../lib
+ (for installing the tool suite elsewhere). */
+
+static char *
+find_scripts_dir (void)
+{
+ char *end, *dir;
+ size_t dirlen;
+
+ dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR);
+ if (dir)
+ {
+ if (check_for_scripts_dir (dir))
+ return dir;
+ free (dir);
+ }
+
+ dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR);
+ if (dir)
+ {
+ if (check_for_scripts_dir (dir))
+ return dir;
+ free (dir);
+ }
+
+ if (check_for_scripts_dir (SCRIPTDIR))
+ /* We've been installed normally. */
+ return SCRIPTDIR;
+
+ /* Look for "ldscripts" in the dir where our binary is. */
+ end = strrchr (program_name, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ {
+ /* We could have \foo\bar, or /foo\bar. */
+ char *bslash = strrchr (program_name, '\\');
+
+ if (end == NULL || (bslash != NULL && bslash > end))
+ end = bslash;
+ }
+#endif
+
+ if (end == NULL)
+ /* Don't look for ldscripts in the current directory. There is
+ too much potential for confusion. */
+ return NULL;
+
+ dirlen = end - program_name;
+ /* Make a copy of program_name in dir.
+ Leave room for later "/../lib". */
+ dir = xmalloc (dirlen + sizeof ("/../lib"));
+ strncpy (dir, program_name, dirlen);
+ dir[dirlen] = '\0';
+
+ if (check_for_scripts_dir (dir))
+ return dir;
+
+ /* Look for "ldscripts" in <the dir where our binary is>/../lib. */
+ strcpy (dir + dirlen, "/../lib");
+ if (check_for_scripts_dir (dir))
+ return dir;
+ free (dir);
+ return NULL;
+}
+
+/* Try to open NAME; if that fails, look for it in the default script
+ directory, then in any directories specified with -L, without and
+ with EXTEND appended. */
static FILE *
ldfile_find_command_file (const char *name, const char *extend)
{
search_dirs_type *search;
FILE *result;
+ char *buffer;
+ static search_dirs_type *script_search;
/* First try raw name. */
result = try_open (name, "");
- if (result == NULL)
+ if (result != NULL)
+ return result;
+
+ if (!script_search)
{
- /* Try now prefixes. */
- for (search = search_head; search != NULL; search = search->next)
+ char *script_dir = find_scripts_dir ();
+ if (script_dir)
{
- char *buffer;
-
- buffer = concat (search->name, slash, name, (const char *) NULL);
- result = try_open (buffer, extend);
- free (buffer);
- if (result)
- break;
+ search_dirs_type **save_tail_ptr = search_tail_ptr;
+ search_tail_ptr = &script_search;
+ ldfile_add_library_path (script_dir, TRUE);
+ search_tail_ptr = save_tail_ptr;
}
+ if (!script_search)
+ script_search = search_head;
+ else
+ script_search->next = search_head;
+ }
+
+ /* Try now prefixes. */
+ for (search = script_search; search != NULL; search = search->next)
+ {
+
+ buffer = concat (search->name, slash, name, (const char *) NULL);
+ result = try_open (buffer, extend);
+ free (buffer);
+ if (result)
+ break;
}
return result;
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.131
diff -u -p -r1.131 ldmain.c
--- ld/ldmain.c 12 Jul 2008 08:54:13 -0000 1.131
+++ ld/ldmain.c 9 Aug 2008 04:59:02 -0000
@@ -114,8 +114,6 @@ static const char *get_sysroot
(int, char **);
static char *get_emulation
(int, char **);
-static void set_scripts_dir
- (void);
static bfd_boolean add_archive_element
(struct bfd_link_info *, bfd *, const char *);
static bfd_boolean multiple_definition
@@ -358,10 +356,6 @@ main (int argc, char **argv)
link_info.discard = discard_all;
}
- /* This essentially adds another -L directory so this must be done after
- the -L's in argv have been processed. */
- set_scripts_dir ();
-
/* If we have not already opened and parsed a linker script,
try the default script from command line first. */
if (saved_script_handle == NULL
@@ -671,106 +665,6 @@ get_emulation (int argc, char **argv)
return emulation;
}
-/* If directory DIR contains an "ldscripts" subdirectory,
- add DIR to the library search path and return TRUE,
- else return FALSE. */
-
-static bfd_boolean
-check_for_scripts_dir (char *dir)
-{
- size_t dirlen;
- char *buf;
- struct stat s;
- bfd_boolean res;
-
- dirlen = strlen (dir);
- /* sizeof counts the terminating NUL. */
- buf = xmalloc (dirlen + sizeof ("/ldscripts"));
- sprintf (buf, "%s/ldscripts", dir);
-
- res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
- free (buf);
- if (res)
- ldfile_add_library_path (dir, FALSE);
- return res;
-}
-
-/* Set the default directory for finding script files.
- Libraries will be searched for here too, but that's ok.
- We look for the "ldscripts" directory in:
-
- SCRIPTDIR (passed from Makefile)
- (adjusted according to the current location of the binary)
- SCRIPTDIR (passed from Makefile)
- the dir where this program is (for using it from the build tree)
- the dir where this program is/../lib
- (for installing the tool suite elsewhere). */
-
-static void
-set_scripts_dir (void)
-{
- char *end, *dir;
- size_t dirlen;
- bfd_boolean found;
-
- dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR);
- if (dir)
- {
- found = check_for_scripts_dir (dir);
- free (dir);
- if (found)
- return;
- }
-
- dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR);
- if (dir)
- {
- found = check_for_scripts_dir (dir);
- free (dir);
- if (found)
- return;
- }
-
- if (check_for_scripts_dir (SCRIPTDIR))
- /* We've been installed normally. */
- return;
-
- /* Look for "ldscripts" in the dir where our binary is. */
- end = strrchr (program_name, '/');
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
- {
- /* We could have \foo\bar, or /foo\bar. */
- char *bslash = strrchr (program_name, '\\');
-
- if (end == NULL || (bslash != NULL && bslash > end))
- end = bslash;
- }
-#endif
-
- if (end == NULL)
- /* Don't look for ldscripts in the current directory. There is
- too much potential for confusion. */
- return;
-
- dirlen = end - program_name;
- /* Make a copy of program_name in dir.
- Leave room for later "/../lib". */
- dir = xmalloc (dirlen + 8);
- strncpy (dir, program_name, dirlen);
- dir[dirlen] = '\0';
-
- if (check_for_scripts_dir (dir))
- {
- free (dir);
- return;
- }
-
- /* Look for "ldscripts" in <the dir where our binary is>/../lib. */
- strcpy (dir + dirlen, "/../lib");
- check_for_scripts_dir (dir);
- free (dir);
-}
-
void
add_ysym (const char *name)
{
--
Alan Modra
Australia Development Lab, IBM