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]

ld sysroot scripts


Current linker treatment of absolute paths in scripts found in a
sysroot is odd.  What's odd is that whether or not such paths have the
sysroot prepended depends on how the script is found rather than where
the script is found.  For instance given a script libc.so in
$sysroot/usr/lib/, "ld ... -lc" will prepend $sysroot to absolute
paths in the script, while "ld ... $sysroot/usr/lib/libc.so" won't,
and similarly for INCLUDE and a bunch of other ways scripts may be
found.  This patch fixes the inconsistency, and removes some dead
code.

I'll note that the bug reporter wants to always search the sysroot
first regardless of where the script is found.  I'm not making that
policy change with this patch.  So copying a script out of a sysroot
will mean paths need adjusting.  (A symbolic link to script in a
sysroot will work though, since ld uses realpath.)

	PR ld/10340
	* ldfile.c (is_sysrooted_pathname): Remove notsame param.
	(ldfile_add_library_path): Don't set sysrooted flag.
	(ldfile_open_file_search): Likewise, and don't copy them.
	(try_open): Delete exten and code handling such.  Add sysrooted
	param and return whether path is in sysroot.
	(ldfile_find_command_file): Delete extend param.  Add sysrooted
	param.  Rename local var.  Update try_open calls.
	(ldfile_open_command_file_1): Pass sysrooted to lex_push_file.
	* ldfile.h (search_dirs_type): Remove sysrooted field.
	* ldlang.c (new_afile): Always set sysrooted from input_flags.
	(load_symbols): Don't set input_flags.sysrooted.
	* ldlang.h (struct lang_input_statement_flags): Revise sysrooted
	comment.
	* ldlex.h (lex_push_file): Update prototype.
	* ldlex.l (sysrooted_stack): New array.
	(EOF): Pop input_flags.sysrooted.
	(lex_push_file): Add sysrooted param.  Save and set
	input_flags.sysrooted.

Index: ld/ldfile.c
===================================================================
RCS file: /cvs/src/src/ld/ldfile.c,v
retrieving revision 1.65
diff -u -p -r1.65 ldfile.c
--- ld/ldfile.c	5 Mar 2012 22:43:40 -0000	1.65
+++ ld/ldfile.c	8 Mar 2012 03:42:42 -0000
@@ -70,7 +70,7 @@ static search_arch_type **search_arch_ta
    sub-directory of the sysroot directory.  */
 
 static bfd_boolean
-is_sysrooted_pathname (const char *name, bfd_boolean notsame)
+is_sysrooted_pathname (const char *name)
 {
   char *realname;
   int len;
@@ -82,18 +82,13 @@ is_sysrooted_pathname (const char *name,
   realname = lrealpath (name);
   len = strlen (realname);
   result = FALSE;
-  if (len == ld_canon_sysroot_len)
-    result = !notsame;
-  else if (len > ld_canon_sysroot_len
-	   && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len]))
+  if (len > ld_canon_sysroot_len
+      && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len]))
     {
-      result = TRUE;
       realname[ld_canon_sysroot_len] = '\0';
+      result = FILENAME_CMP (ld_canon_sysroot, realname) == 0;
     }
 
-  if (result)
-    result = FILENAME_CMP (ld_canon_sysroot, realname) == 0;
-
   free (realname);
   return result;
 }
@@ -118,15 +113,9 @@ ldfile_add_library_path (const char *nam
   /* If a directory is marked as honoring sysroot, prepend the sysroot path
      now.  */
   if (name[0] == '=')
-    {
-      new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL);
-      new_dirs->sysrooted = TRUE;
-    }
+    new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL);
   else
-    {
-      new_dirs->name = xstrdup (name);
-      new_dirs->sysrooted = is_sysrooted_pathname (name, FALSE);
-    }
+    new_dirs->name = xstrdup (name);
 }
 
 /* Try to open a BFD for a lang_input_statement.  */
@@ -364,12 +353,7 @@ ldfile_open_file_search (const char *arc
 	  free (name);
 	}
       else if (ldfile_try_open_bfd (entry->filename, entry))
-	{
-	  entry->flags.sysrooted
-	    = (IS_ABSOLUTE_PATH (entry->filename)
-	       && is_sysrooted_pathname (entry->filename, TRUE));
-	  return TRUE;
-	}
+	return TRUE;
 
       if (IS_ABSOLUTE_PATH (entry->filename))
 	return FALSE;
@@ -382,10 +366,7 @@ ldfile_open_file_search (const char *arc
       if (entry->flags.dynamic && ! link_info.relocatable)
 	{
 	  if (ldemul_open_dynamic_archive (arch, search, entry))
-	    {
-	      entry->flags.sysrooted = search->sysrooted;
-	      return TRUE;
-	    }
+	    return TRUE;
 	}
 
       if (entry->flags.maybe_archive)
@@ -398,7 +379,6 @@ ldfile_open_file_search (const char *arc
       if (ldfile_try_open_bfd (string, entry))
 	{
 	  entry->filename = string;
-	  entry->flags.sysrooted = search->sysrooted;
 	  return TRUE;
 	}
 
@@ -473,15 +453,18 @@ ldfile_open_file (lang_input_statement_t
     }
 }
 
-/* Try to open NAME; if that fails, try NAME with EXTEN appended to it.  */
+/* Try to open NAME.  */
 
 static FILE *
-try_open (const char *name, const char *exten)
+try_open (const char *name, bfd_boolean *sysrooted)
 {
   FILE *result;
 
   result = fopen (name, "r");
 
+  if (result != NULL)
+    *sysrooted = is_sysrooted_pathname (name);
+
   if (trace_file_tries)
     {
       if (result == NULL)
@@ -490,26 +473,6 @@ try_open (const char *name, const char *
 	info_msg (_("opened script file %s\n"), name);
     }
 
-  if (result != NULL)
-    return result;
-
-  if (*exten)
-    {
-      char *buff;
-
-      buff = concat (name, exten, (const char *) NULL);
-      result = fopen (buff, "r");
-
-      if (trace_file_tries)
-	{
-	  if (result == NULL)
-	    info_msg (_("cannot find script file %s\n"), buff);
-	  else
-	    info_msg (_("opened script file %s\n"), buff);
-	}
-      free (buff);
-    }
-
   return result;
 }
 
@@ -570,22 +533,23 @@ find_scripts_dir (void)
 
 /* 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.  */
+   directory.  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,
-			  bfd_boolean default_only)
+ldfile_find_command_file (const char *name,
+			  bfd_boolean default_only,
+			  bfd_boolean *sysrooted)
 {
   search_dirs_type *search;
   FILE *result = NULL;
-  char *buffer;
+  char *path;
   static search_dirs_type *script_search;
 
   if (!default_only)
     {
       /* First try raw name.  */
-      result = try_open (name, "");
+      result = try_open (name, sysrooted);
       if (result != NULL)
 	return result;
     }
@@ -611,9 +575,9 @@ ldfile_find_command_file (const char *na
        search != NULL;
        search = search->next)
     {
-      buffer = concat (search->name, slash, name, (const char *) NULL);
-      result = try_open (buffer, extend);
-      free (buffer);
+      path = concat (search->name, slash, name, (const char *) NULL);
+      result = try_open (path, sysrooted);
+      free (path);
       if (result)
 	break;
     }
@@ -630,7 +594,9 @@ 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, "", default_only);
+  bfd_boolean sysrooted;
+
+  ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted);
 
   if (ldlex_input_stack == NULL)
     {
@@ -638,7 +604,7 @@ ldfile_open_command_file_1 (const char *
       einfo (_("%P%F: cannot open linker script file %s: %E\n"), name);
     }
 
-  lex_push_file (ldlex_input_stack, name);
+  lex_push_file (ldlex_input_stack, name, sysrooted);
 
   lineno = 1;
 
Index: ld/ldfile.h
===================================================================
RCS file: /cvs/src/src/ld/ldfile.h,v
retrieving revision 1.19
diff -u -p -r1.19 ldfile.h
--- ld/ldfile.h	17 Feb 2012 14:09:57 -0000	1.19
+++ ld/ldfile.h	8 Mar 2012 03:42:42 -0000
@@ -37,8 +37,6 @@ typedef struct search_dirs {
   const char *name;
   /* TRUE if this is from the command line.  */
   bfd_boolean cmdline;
-  /* true if this is from within the sys-root.  */
-  bfd_boolean sysrooted;
 } search_dirs_type;
 
 extern search_dirs_type *search_head;
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.385
diff -u -p -r1.385 ldlang.c
--- ld/ldlang.c	5 Mar 2012 22:43:40 -0000	1.385
+++ ld/ldlang.c	8 Mar 2012 03:42:43 -0000
@@ -1064,6 +1064,7 @@ new_afile (const char *name,
   p->flags.add_DT_NEEDED_for_dynamic = input_flags.add_DT_NEEDED_for_dynamic;
   p->flags.add_DT_NEEDED_for_regular = input_flags.add_DT_NEEDED_for_regular;
   p->flags.whole_archive = input_flags.whole_archive;
+  p->flags.sysrooted = input_flags.sysrooted;
 
   if (file_type == lang_input_file_is_l_enum
       && name[0] == ':' && name[1] != '\0')
@@ -1101,7 +1102,6 @@ new_afile (const char *name,
       p->local_sym_name = name;
       p->flags.real = TRUE;
       p->flags.search_dirs = TRUE;
-      p->flags.sysrooted = input_flags.sysrooted;
       break;
     case lang_input_file_is_file_enum:
       p->filename = name;
@@ -2716,7 +2716,6 @@ load_symbols (lang_input_statement_type 
       ldfile_open_command_file (entry->filename);
 
       push_stat_ptr (place);
-      input_flags.sysrooted = entry->flags.sysrooted;
       input_flags.add_DT_NEEDED_for_regular
 	= entry->flags.add_DT_NEEDED_for_regular;
       input_flags.add_DT_NEEDED_for_dynamic
@@ -2729,7 +2728,9 @@ load_symbols (lang_input_statement_type 
       yyparse ();
       ldfile_assumed_script = FALSE;
 
-      /* missing_file is sticky.  */
+      /* missing_file is sticky.  sysrooted will already have been
+	 restored when seeing EOF in yyparse, but no harm to restore
+	 again.  */
       save_flags.missing_file |= input_flags.missing_file;
       input_flags = save_flags;
       pop_stat_ptr ();
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.102
diff -u -p -r1.102 ldlang.h
--- ld/ldlang.h	5 Mar 2012 22:43:40 -0000	1.102
+++ ld/ldlang.h	8 Mar 2012 03:42:43 -0000
@@ -236,10 +236,7 @@ struct lang_input_statement_flags
   /* 1 means search a set of directories for this file.  */
   unsigned int search_dirs : 1;
 
-  /* 1 means this was found in a search directory marked as sysrooted,
-     if search_dirs is false, otherwise, that it should be
-     searched in ld_sysroot before any other location, as long as it
-     starts with a slash.  */
+  /* 1 means this was found when processing a script in the sysroot.  */
   unsigned int sysrooted : 1;
 
   /* 1 means this is base file of incremental load.
Index: ld/ldlex.h
===================================================================
RCS file: /cvs/src/src/ld/ldlex.h,v
retrieving revision 1.9
diff -u -p -r1.9 ldlex.h
--- ld/ldlex.h	17 Feb 2012 14:09:57 -0000	1.9
+++ ld/ldlex.h	8 Mar 2012 03:42:43 -0000
@@ -41,7 +41,7 @@ extern const char *lex_string;
 
 /* In ldlex.l.  */
 extern int yylex (void);
-extern void lex_push_file (FILE *, const char *);
+extern void lex_push_file (FILE *, const char *, unsigned int);
 extern void lex_redirect (const char *, const char *, unsigned int);
 extern void ldlex_script (void);
 extern void ldlex_mri_script (void);
Index: ld/ldlex.l
===================================================================
RCS file: /cvs/src/src/ld/ldlex.l,v
retrieving revision 1.54
diff -u -p -r1.54 ldlex.l
--- ld/ldlex.l	17 Feb 2012 14:09:57 -0000	1.54
+++ ld/ldlex.l	8 Mar 2012 03:42:44 -0000
@@ -68,6 +68,7 @@ const char *lex_string = NULL;
 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
 static const char *file_name_stack[MAX_INCLUDE_DEPTH];
 static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
+static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH];
 static unsigned int include_stack_ptr = 0;
 static int vers_node_nesting = 0;
 
@@ -454,6 +455,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
     yy_switch_to_buffer (include_stack[include_stack_ptr]);
 
   lineno = lineno_stack[include_stack_ptr];
+  input_flags.sysrooted = sysrooted_stack[include_stack_ptr];
 
   return END;
 }
@@ -468,7 +470,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
    saving the current input info on the include stack.  */
 
 void
-lex_push_file (FILE *file, const char *name)
+lex_push_file (FILE *file, const char *name, unsigned int sysrooted)
 {
   if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
     {
@@ -476,10 +478,12 @@ lex_push_file (FILE *file, const char *n
     }
   file_name_stack[include_stack_ptr] = name;
   lineno_stack[include_stack_ptr] = lineno;
+  sysrooted_stack[include_stack_ptr] = input_flags.sysrooted;
   include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
 
   include_stack_ptr++;
   lineno = 1;
+  input_flags.sysrooted = sysrooted;
   yyin = file;
   yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE));
 }

-- 
Alan Modra
Australia Development Lab, IBM


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