This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] ldfile.c: Fix the search path ordering for a linker script. (Take 2)


Hi,

Attached is a revised patch to fix the search path ordering for a
linker script.

The previous iteration of this patch was posted at:

  http://sourceware.org/ml/binutils/2009-04/msg00048.html

In this iteration, I'm changing the search paths for a linker script
as follows.

If "-T foo.ld" is specified, then we search for foo.ld in the current
directory, -L directories, and the default script directory, in that
order.

If "-T foo.ld" is not specified, then we search for a default script
in the default script directory only.

This way, we can accommodate both bare-metal and OS applications
fairly well.  For OS applications, we typically don't specify -T.  For
bare metal applications, we almost always specify -T.  Plus, as Daniel
mentioned, users may copy an installed linker script to another
location and modify it to suit their needs.

With this patch, ldfile.c provides two ways of opening a linker
script.

  ldfile_open_command_file (s);
  ldfile_open_default_command_file (s);

The only difference is that the latter searches the default script
directory only.  Other than that, everything else is the same.  To
avoid duplicating code, I've created ldfile_open_command_file_1 to do
the actual work of ldfile_open_command_file and
ldfile_open_default_command_file.  Also, I've generalized
ldfile_find_command_file so that it can handle both types of searches.

Tested on fido-none-elf.  OK to apply?

Kazu Hirata

2009-04-02  Kazu Hirata  <kazu@codesourcery.com>

	* ld.texinfo (-L): Mention that -L options do not affect how ld
	searches for a linker script unless -T option is specified.
	* ldfile.c (ldfile_find_command_file): Append the path obtained
	from the program name to the search path instead of
	prepending. Add a new parameter "default_only". Restrict the
	search to the default script location if the new parameter is
	true.
	(ldfile_open_command_file_1): New.
	(ldfile_open_command_file): Call ldfile_open_command_file_1.
	(ldfile_open_default_command_file): New.

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.221
diff -u -d -p -r1.221 ld.texinfo
--- ld/ld.texinfo	18 Jul 2008 20:49:12 -0000	1.221
+++ ld/ld.texinfo	3 Apr 2009 09:14:32 -0000
@@ -646,7 +646,9 @@ option any number of times.  The directo
 in which they are specified on the command line.  Directories specified
 on the command line are searched before the default directories.  All
 @option{-L} options apply to all @option{-l} options, regardless of the
-order in which the options appear.
+order in which the options appear.  @option{-L} options do not affect
+how @command{ld} searches for a linker script unless @option{-T}
+option is specified.
 
 If @var{searchdir} begins with @code{=}, then the @code{=} will be replaced
 by the @dfn{sysroot prefix}, a path specified when the linker is configured.
Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.47
diff -u -d -p -r1.47 ldfile.c
--- ld/ldfile.c	9 Aug 2008 10:15:38 -0000	1.47
+++ ld/ldfile.c	3 Apr 2009 09:14:32 -0000
@@ -542,22 +542,27 @@ find_scripts_dir (void)
   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.  */
+/* If DEFAULT_ONLY is false, try to open NAME; if that fails, look for
+   it in directories specified with -L, then in the default script
+   directory, without and with EXTEND appended.  If DEFAULT_ONLY is
+   true, the search is restricted to the default script location.  */
 
 static FILE *
-ldfile_find_command_file (const char *name, const char *extend)
+ldfile_find_command_file (const char *name, const char *extend,
+			  bfd_boolean default_only)
 {
   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)
-    return result;
+  if (default_only)
+    {
+      /* First try raw name.  */
+      result = try_open (name, "");
+      if (result != NULL)
+	return result;
+    }
 
   if (!script_search)
     {
@@ -569,16 +574,17 @@ ldfile_find_command_file (const char *na
 	  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;
     }
 
+  /* Temporarily append script_search to the path list so that the
+     paths specified with -L will be searched first.  */
+  *search_tail_ptr = script_search;
+
   /* Try now prefixes.  */
-  for (search = script_search; search != NULL; search = search->next)
+  for (search = default_only ? script_search : search_head;
+       search != NULL;
+       search = search->next)
     {
-
       buffer = concat (search->name, slash, name, (const char *) NULL);
       result = try_open (buffer, extend);
       free (buffer);
@@ -586,14 +592,19 @@ ldfile_find_command_file (const char *na
 	break;
     }
 
+  /* Restore the original path list.  */
+  *search_tail_ptr = NULL;
+
   return result;
 }
 
-void
-ldfile_open_command_file (const char *name)
+/* Open command file NAME.  */
+
+static void
+ldfile_open_command_file_1 (const char *name, bfd_boolean default_only)
 {
   FILE *ldlex_input_stack;
-  ldlex_input_stack = ldfile_find_command_file (name, "");
+  ldlex_input_stack = ldfile_find_command_file (name, "", default_only);
 
   if (ldlex_input_stack == NULL)
     {
@@ -609,6 +620,23 @@ ldfile_open_command_file (const char *na
   saved_script_handle = ldlex_input_stack;
 }
 
+/* Open command file NAME in the current directory, -L directories,
+   the default script location, in that order.  */
+
+void
+ldfile_open_command_file (const char *name)
+{
+  ldfile_open_command_file_1 (name, FALSE);
+}
+
+/* Open command file NAME at the default script location.  */
+
+void
+ldfile_open_default_command_file (const char *name)
+{
+  ldfile_open_command_file_1 (name, TRUE);
+}
+
 void
 ldfile_add_arch (const char *in_name)
 {
Index: ld/ldfile.h
===================================================================
RCS file: /cvs/src/src/ld/ldfile.h,v
retrieving revision 1.16
diff -u -d -p -r1.16 ldfile.h
--- ld/ldfile.h	6 Jul 2007 14:09:41 -0000	1.16
+++ ld/ldfile.h	3 Apr 2009 09:14:32 -0000
@@ -50,6 +50,8 @@ extern void ldfile_add_library_path
   (const char *, bfd_boolean cmdline);
 extern void ldfile_open_command_file
   (const char *name);
+extern void ldfile_open_default_command_file
+  (const char *name);
 extern void ldfile_open_file
   (struct lang_input_statement_struct *);
 extern bfd_boolean ldfile_try_open_bfd
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.132
diff -u -d -p -r1.132 ldmain.c
--- ld/ldmain.c	9 Aug 2008 10:15:38 -0000	1.132
+++ ld/ldmain.c	3 Apr 2009 09:14:32 -0000
@@ -374,7 +374,7 @@ main (int argc, char **argv)
       char *s = ldemul_get_script (&isfile);
 
       if (isfile)
-	ldfile_open_command_file (s);
+	ldfile_open_default_command_file (s);
       else
 	{
 	  lex_string = s;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]