+2014-10-15 Hans-Peter Nilsson <hp@axis.com>
+
+ Backport "="-ldscript-path-prefix changes from master.
+ * ldlex.l (INPUTLIST): New start condition.
+ (comment pattern, ",", "(", ")", "AS_NEEDED")
+ ({FILENAMECHAR1}{FILENAMECHAR}*, "-l"{FILENAMECHAR}+)
+ (quoted string pattern, whitespace pattern): Add INPUTLIST to
+ valid start conditions.
+ (<INPUTLIST>"="{FILENAMECHAR1}{FILENAMECHAR}*): New NAME rule.
+ (ldlex_inputlist): New start-condition-setter function.
+ * ldgram.y (input_list1): Rename from input_list. All recursive
+ use changed.
+ (input_list): New wrapper rule for input_list1, setting
+ INPUTLIST lexer state for the duration of parsing input_list1.
+ * ldlang.c (lang_add_input_file): If the first character in the
+ filename is '=', prepend the sysroot and force the context of that
+ input file to non-sysroot.
+ * ld.texinfo (Options): When mentioning "=" and sysroot, mention
+ that --sysroot controls it, not only through the configuration.
+ (input files in linker scripts): When mentioning
+ behavior of first character "/" on scripts within sysroot, also
+ mention that effect can be forced by prefixing with "=" and
+ refer to SEARCH_DIR.
+
2014-10-14 Tristan Gingold <gingold@adacore.com>
* NEWS: Add marker for 2.25.
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.
+by the @dfn{sysroot prefix}, controlled by the @samp{--sysroot} option, or
+specified when the linker is configured.
@ifset UsesEnvVars
The default set of paths searched (without being specified with
located inside the @dfn{sysroot prefix}, the filename will be looked
for in the @dfn{sysroot prefix}. Otherwise, the linker will try to
open the file in the current directory. If it is not found, the
-linker will search through the archive library search path. See the
+linker will search through the archive library search path.
+The @dfn{sysroot prefix} can also be forced by specifying @code{=}
+as the first character in the filename path. See also the
description of @samp{-L} in @ref{Options,,Command Line Options}.
If you use @samp{INPUT (-l@var{file})}, @command{ld} will transform the
;
input_list:
+ { ldlex_inputlist(); }
+ input_list1
+ { ldlex_popstate(); }
+
+input_list1:
NAME
{ lang_add_input_file($1,lang_input_file_is_search_file_enum,
(char *)NULL); }
- | input_list ',' NAME
+ | input_list1 ',' NAME
{ lang_add_input_file($3,lang_input_file_is_search_file_enum,
(char *)NULL); }
- | input_list NAME
+ | input_list1 NAME
{ lang_add_input_file($2,lang_input_file_is_search_file_enum,
(char *)NULL); }
| LNAME
{ lang_add_input_file($1,lang_input_file_is_l_enum,
(char *)NULL); }
- | input_list ',' LNAME
+ | input_list1 ',' LNAME
{ lang_add_input_file($3,lang_input_file_is_l_enum,
(char *)NULL); }
- | input_list LNAME
+ | input_list1 LNAME
{ lang_add_input_file($2,lang_input_file_is_l_enum,
(char *)NULL); }
| AS_NEEDED '('
{ $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
input_flags.add_DT_NEEDED_for_regular = TRUE; }
- input_list ')'
+ input_list1 ')'
{ input_flags.add_DT_NEEDED_for_regular = $<integer>3; }
- | input_list ',' AS_NEEDED '('
+ | input_list1 ',' AS_NEEDED '('
{ $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
input_flags.add_DT_NEEDED_for_regular = TRUE; }
- input_list ')'
+ input_list1 ')'
{ input_flags.add_DT_NEEDED_for_regular = $<integer>5; }
- | input_list AS_NEEDED '('
+ | input_list1 AS_NEEDED '('
{ $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
input_flags.add_DT_NEEDED_for_regular = TRUE; }
- input_list ')'
+ input_list1 ')'
{ input_flags.add_DT_NEEDED_for_regular = $<integer>4; }
;
lang_input_file_enum_type file_type,
const char *target)
{
+ if (name != NULL && *name == '=')
+ {
+ lang_input_statement_type *ret;
+ char *sysrooted_name
+ = concat (ld_sysroot, name + 1, (const char *) NULL);
+
+ /* We've now forcibly prepended the sysroot, making the input
+ file independent of the context. Therefore, temporarily
+ force a non-sysrooted context for this statement, so it won't
+ get the sysroot prepended again when opened. (N.B. if it's a
+ script, any child nodes with input files starting with "/"
+ will be handled as "sysrooted" as they'll be found to be
+ within the sysroot subdirectory.) */
+ unsigned int outer_sysrooted = input_flags.sysrooted;
+ input_flags.sysrooted = 0;
+ ret = new_afile (sysrooted_name, file_type, target, TRUE);
+ input_flags.sysrooted = outer_sysrooted;
+ return ret;
+ }
+
return new_afile (name, file_type, target, TRUE);
}
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_inputlist (void);
extern void ldlex_mri_script (void);
extern void ldlex_version_script (void);
extern void ldlex_version_file (void);
/* STATES
EXPRESSION definitely in an expression
SCRIPT definitely in a script
+ INPUTLIST definitely in a script, a filename-list
BOTH either EXPRESSION or SCRIPT
DEFSYMEXP in an argument to -defsym
MRI in an MRI script
V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
%s SCRIPT
+%s INPUTLIST
%s EXPRESSION
%s BOTH
%s DEFSYMEXP
}
}
-<BOTH,SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT>"/*" { comment (); }
+<BOTH,SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"/*" { comment (); }
<DEFSYMEXP>"-" { RTOKEN('-');}
<BOTH,SCRIPT,EXPRESSION,MRI>"|=" { RTOKEN(OREQ);}
<BOTH,SCRIPT,EXPRESSION,MRI>"&&" { RTOKEN(ANDAND);}
<BOTH,SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>');}
-<BOTH,SCRIPT,EXPRESSION,MRI>"," { RTOKEN(',');}
+<BOTH,SCRIPT,EXPRESSION,MRI,INPUTLIST>"," { RTOKEN(',');}
<BOTH,SCRIPT,EXPRESSION,MRI>"&" { RTOKEN('&');}
<BOTH,SCRIPT,EXPRESSION,MRI>"|" { RTOKEN('|');}
<BOTH,SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~');}
<BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');}
<BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
-<BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');}
-<BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');}
+<BOTH,SCRIPT,EXPRESSION,MRI,INPUTLIST>")" { RTOKEN(')');}
+<BOTH,SCRIPT,EXPRESSION,MRI,INPUTLIST>"(" { RTOKEN('(');}
<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
-<EXPRESSION,BOTH,SCRIPT>"AS_NEEDED" { RTOKEN(AS_NEEDED);}
+<EXPRESSION,BOTH,SCRIPT,INPUTLIST>"AS_NEEDED" { RTOKEN(AS_NEEDED);}
<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
}
-<BOTH>{FILENAMECHAR1}{FILENAMECHAR}* {
+<BOTH,INPUTLIST>{FILENAMECHAR1}{FILENAMECHAR}* {
yylval.name = xstrdup (yytext);
return NAME;
}
-<BOTH>"-l"{FILENAMECHAR}+ {
+<INPUTLIST>"="{FILENAMECHAR1}{FILENAMECHAR}* {
+/* Filename to be prefixed by --sysroot or when non-sysrooted, nothing. */
+ yylval.name = xstrdup (yytext);
+ return NAME;
+ }
+<BOTH,INPUTLIST>"-l"{FILENAMECHAR}+ {
yylval.name = xstrdup (yytext + 2);
return LNAME;
}
}
}
-<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" {
+<EXPRESSION,BOTH,SCRIPT,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" {
/* No matter the state, quotes
give what's inside */
yylval.name = xstrdup (yytext + 1);
<VERS_START,VERS_NODE,VERS_SCRIPT>#.* { /* Eat up comments */ }
-<VERS_START,VERS_NODE,VERS_SCRIPT>[ \t\r]+ { /* Eat up whitespace */ }
+<VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>[ \t\r]+ { /* Eat up whitespace */ }
<<EOF>> {
include_stack_ptr--;
}
void
+ldlex_inputlist (void)
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (INPUTLIST);
+}
+
+void
ldlex_mri_script (void)
{
*(state_stack_p)++ = yy_start;
+2014-10-15 Hans-Peter Nilsson <hp@axis.com>
+
+ Backport "="-ldscript-path-prefix changes from master.
+ * ld-scripts/sysroot-prefix.exp, ld-scripts/sysroot-prefix-x.s,
+ ld-scripts/sysroot-prefix-y.s: New files.
+ * lib/ld-lib.exp (check_sysroot_available): New proc.
+
2014-10-04 Alan Modra <amodra@gmail.com>
* ld-elf/eh1.s: Don't create FDEs with zero address ranges.
--- /dev/null
+ .data
+ .globl x
+x:
+ .dc.a y
+
--- /dev/null
+ .data
+ .globl y
+y:
+ .dc.a 0
--- /dev/null
+# Copyright (C) 2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# Check that scripts using the "=" sysroot-prefix work, for both
+# toolchains with and without --sysroot support.
+
+# We test this by emitting archives into a subdirectory and expect
+# constructs such as GROUP and AS_NEEDED (the only two constructs
+# actually tested) to find them (or not); both quoted and unquoted
+# paths, with different prefixes on the path and with --sysroot
+# present or not, with different arguments.
+
+# Find out if the linker supports sysroot; if it was configured
+# "--with-sysroot X". We ignore that X can actually be set to
+# interfere with the tests, as that's unlikely to be useful, and
+# assume that the build-directory (aka. $base_dir) does not contain X.
+set with_sysroot [check_sysroot_available]
+verbose -log "Has (non-empty) sysroot support: $with_sysroot"
+
+# Entries in the array-tables:
+# 0: Testtype (1: only non-sysroot, 2: only sysroot, 3: either).
+# 1: Description, forming part of the dejagnu test-name.
+# 2: Replacement for @p@.
+# 3: Option to pass to linker (usually something with --sysroot).
+# 4: Message substring; a substring to match against the error message
+# if an error is expected, or empty if no error is expected.
+#
+# If the replacement or option contains @cwd@, that'll be replaced by
+# "$base_dir/tmpdir", the full path to the location of the script
+# (with the actual files in the "sysroot" subdirectory). If the
+# description contains @cwd@, that will be replaced by "<CWD>".
+
+set sysroot_prefix_tests {
+ {3 "plain -Lpath" "sysroot/" {} ""}
+ {3 "root-anchored but -Lpath" "/sysroot/" {} "cannot find"}
+ {3 "full-path" "@cwd@/sysroot/" {} ""}
+ {3 "root-anchored =-prefixed -Lpath" "=/sysroot/" {} "cannot find"}
+ {3 "full-path =-prefixed with empty" "=@cwd@/sysroot/" "--sysroot=" ""}
+ {3 "plain =-prefixed with empty" "=sysroot/" "--sysroot=" ""}
+ {2 "root-anchored but script outside sysroot" "/" "--sysroot=@cwd@/sysroot" "cannot find"}
+ {2 "root-anchored and script inside sysroot" "/sysroot/" "--sysroot=@cwd@" ""}
+ {2 "root-anchored =-prefixed script outside" "=/" "--sysroot=@cwd@/sysroot" ""}
+ {2 "root-anchored =-prefixed script inside" "=/sysroot/" "--sysroot=@cwd@" ""}
+ {2 "plain =-prefixed without but -Lpath" "=sysroot/" {} "cannot find"}
+ {2 "full-path =-prefixed without" "=@cwd@/sysroot/" {} "cannot find"}
+ {1 "plain =-prefixed -Lpath" "=sysroot/" {} ""}
+ {1 "full-path =-prefixed without" "=@cwd@/sysroot/" {} ""}
+}
+
+# May have to provide a target-specific assembler option for some targets.
+set gasopt ""
+
+# Intentionally similar to the ubiquitous glibc libc.so script.
+set template "GROUP ( @q@@p@tmp/ldtest-xyzzy/libx.a@q@ AS_NEEDED ( @q@@p@tmp/ldtest-xyzzy/liby.a@q@ ) )"
+
+# Set up everything from the variables above.
+proc sysroot_prefix_test_setup { } {
+ global as gasopt srcdir subdir ar
+
+ if {![ld_assemble_flags $as $gasopt $srcdir/$subdir/pr14962a.s tmpdir/main.o]} {
+ error "Error assembling a trivial file for sysroot-prefix tests framework"
+ return 0
+ }
+
+ # We need somewhere under tmpdir to point the sysroot, a subdirectory
+ # that is benevolent if it escapes into "/".
+ remote_exec host "mkdir -p tmpdir/sysroot/tmp/ldtest-xyzzy"
+
+ # 0: a "main" object that needs a symbol (x) (most portably by
+ # using a pre-existing file). 1: a library with an object that
+ # provides that symbol and needs another one (y). 2: another
+ # library with a third object providing that other symbol.
+ set sysroot_prefix_tests_framework_objects {
+ {"pr14962a.s" "main" ""}
+ {"sysroot-prefix-x.s" "x" "x"}
+ {"sysroot-prefix-y.s" "y" "y"}
+ }
+
+ foreach test_object $sysroot_prefix_tests_framework_objects {
+ set sname [lindex $test_object 0]
+ set onamebase [lindex $test_object 1]
+ set oname "tmpdir/$onamebase.o"
+ set libnamebase [lindex $test_object 2]
+
+ if ![ld_assemble_flags $as $gasopt $srcdir/$subdir/$sname $oname] {
+ error "Error assembling trivial file $sname for sysroot-prefix tests framework"
+ return 0
+ }
+
+ if { [string length $libnamebase] != 0 &&
+ ![ar_simple_create $ar "" tmpdir/sysroot/tmp/ldtest-xyzzy/lib$libnamebase.a $oname] } {
+ error "Error creating archive $libnamebase for sysroot-prefix tests framework"
+ return 0
+ }
+ }
+
+ return 1
+}
+
+# Run a single linker test.
+proc single_sysroot_prefix_test { type xtestname finalscript ldopt errstr } {
+ global ld exec_output with_sysroot
+ set scriptname "tmpdir/libsysroottest.a"
+ set testname "sysroot-prefix $xtestname"
+
+ if { ($type & ($with_sysroot + 1)) == 0 } {
+ unsupported $testname
+ return
+ }
+
+ if [catch { set ofd [open $scriptname w] } x] {
+ perror "$x"
+ unresolved $testname
+ return
+ }
+
+ puts $ofd "$finalscript"
+ close $ofd
+ verbose -log "script: $finalscript"
+
+ set res [ld_simple_link $ld tmpdir/output "$ldopt tmpdir/main.o -Ltmpdir -lsysroottest"]
+ set ld_output "$exec_output"
+ set expect_success [expr [string length $errstr] == 0]
+
+ if { $res == $expect_success &&
+ ($expect_success || [regexp "$errstr" $ld_output]) } {
+ pass $testname
+ catch "exec rm -f $scriptname"
+ } {
+ fail $testname
+ }
+}
+
+# Run all interesting variants from an option-and-path combination.
+proc run_sysroot_prefix_test { type name templ p ldopt errstr } {
+ global base_dir
+ set qlist { { "quoted" "\"" } { "unquoted" {} } }
+
+ regsub -all "@p@" $templ $p templ
+ regsub -all "@cwd@" $templ "$base_dir/tmpdir" templ
+ regsub -all "@cwd@" $ldopt "$base_dir/tmpdir" ldopt
+ regsub -all "@cwd@" $name "<CWD>" name
+
+ foreach qitems $qlist {
+ regsub -all "@q@" $templ [lindex $qitems 1] finalscript
+ single_sysroot_prefix_test $type "$name, [lindex $qitems 0]" \
+ $finalscript $ldopt $errstr
+ }
+}
+
+# Run a list of option-and-path test-combinations.
+proc run_sysroot_prefix_tests { descr templ items } {
+ foreach item $items {
+ set type [lindex $item 0]
+ set name [lindex $item 1]
+ set p [lindex $item 2]
+ set ldopt [lindex $item 3]
+ set errstr [lindex $item 4]
+ run_sysroot_prefix_test $type "$descr $name" $templ "$p" "$ldopt" "$errstr"
+ }
+}
+
+if ![sysroot_prefix_test_setup] {
+ return
+}
+
+run_sysroot_prefix_tests "common" $template $sysroot_prefix_tests
return $plugin_api_available_saved
}
+# Returns true if the target ld supports sysroot.
+proc check_sysroot_available { } {
+ global ld_sysroot_available_saved
+ global ld
+ if {![info exists ld_sysroot_available_saved]} {
+ # Check if ld supports --sysroot *other* than empty
+ # (non-sysroot linkers don't emit errors for --sysroot="").
+ # The help-text by itself is no indication as it always lists --sysroot.
+ set status [remote_exec host $ld "--sysroot=ldxyzzy --help >/dev/null"]
+ if { [lindex $status 0] != 0 } {
+ set ld_sysroot_available_saved 0
+ } else {
+ set ld_sysroot_available_saved 1
+ }
+ }
+ return $ld_sysroot_available_saved
+}
+
# Returns true if the target compiler supports LTO
proc check_lto_available { } {
global lto_available_saved