This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld sysroot scripts
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Thu, 8 Mar 2012 16:02:50 +1030
- Subject: 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