aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog29
-rw-r--r--ld/NEWS4
-rw-r--r--ld/ld.texinfo28
-rw-r--r--ld/ldlang.c59
-rw-r--r--ld/ldlang.h1
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-1.d5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-1.map8
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-1.t10
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-2.d5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-2.map7
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-2.t10
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-3.d5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-3.map7
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-3.t10
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-4.d5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-4.map7
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-4.t10
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-a.s5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file-b.s5
-rw-r--r--ld/testsuite/ld-scripts/exclude-file.exp32
20 files changed, 231 insertions, 21 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 3098b4c..577af33 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,34 @@
2016-11-04 Andrew Burgess <andrew.burgess@embecosm.com>
+ * ldlang.h (struct lang_wild_statement_struct): Add
+ exclude_name_list field.
+ * ldlang.c (walk_wild_file_in_exclude_list): New function.
+ (walk_wild_consider_section): Use new
+ walk_wild_file_in_exclude_list function.
+ (walk_wild_file): Add call to walk_wild_file_in_exclude_list.
+ (print_wild_statement): Print new exclude_name_list field.
+ (lang_add_wild): Initialise new exclude_name_list field.
+ * testsuite/ld-scripts/exclude-file-1.d: New file.
+ * testsuite/ld-scripts/exclude-file-1.map: New file.
+ * testsuite/ld-scripts/exclude-file-1.t: New file.
+ * testsuite/ld-scripts/exclude-file-2.d: New file.
+ * testsuite/ld-scripts/exclude-file-2.map: New file.
+ * testsuite/ld-scripts/exclude-file-2.t: New file.
+ * testsuite/ld-scripts/exclude-file-3.d: New file.
+ * testsuite/ld-scripts/exclude-file-3.map: New file.
+ * testsuite/ld-scripts/exclude-file-3.t: New file.
+ * testsuite/ld-scripts/exclude-file-4.d: New file.
+ * testsuite/ld-scripts/exclude-file-4.map: New file.
+ * testsuite/ld-scripts/exclude-file-4.t: New file.
+ * testsuite/ld-scripts/exclude-file-a.s: New file.
+ * testsuite/ld-scripts/exclude-file-b.s: New file.
+ * testsuite/ld-scripts/exclude-file.exp: New file.
+ * ld.texinfo (Input Section Basics): Update description of
+ EXCLUDE_FILE to cover the new features.
+ * NEWS: Mention new EXCLUDE_FILE usage.
+
+2016-11-04 Andrew Burgess <andrew.burgess@embecosm.com>
+
* testsuite/lib/ld-lib.exp (run_dump_test): Use object file names
based on the original source file name.
* testsuite/ld-discard/extern.d: Update object file names.
diff --git a/ld/NEWS b/ld/NEWS
index 0efa411..f8bf58d 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,9 @@
-*- text -*-
+* The EXCLUDE_FILE linker script construct can now be applied outside of the
+ section list in order for the exclusions to apply over all input sections in
+ the list.
+
* Add support for the RISC-V architecture.
* The command line option --no-eh-frame-hdr can now be used in ELF based
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 6528b6a..500fda6 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -4192,14 +4192,24 @@ include all input @samp{.text} sections, you would write:
@end smallexample
@noindent
Here the @samp{*} is a wildcard which matches any file name. To exclude a list
+@cindex EXCLUDE_FILE
of files from matching the file name wildcard, EXCLUDE_FILE may be used to
match all files except the ones specified in the EXCLUDE_FILE list. For
example:
@smallexample
+EXCLUDE_FILE (*crtend.o *otherfile.o) *(.ctors)
+@end smallexample
+@noindent
+will cause all .ctors sections from all files except @file{crtend.o}
+and @file{otherfile.o} to be included. The EXCLUDE_FILE can also be
+placed inside the section list, for example:
+@smallexample
*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors)
@end smallexample
-will cause all .ctors sections from all files except @file{crtend.o} and
-@file{otherfile.o} to be included.
+@noindent
+The result of this is identically to the previous example. Supporting
+two syntaxes for EXCLUDE_FILE is useful if the section list contains
+more than one section, as described below.
There are two ways to include more than one section:
@smallexample
@@ -4214,8 +4224,9 @@ they are found in the linker input. In the second example, all
@samp{.text} input sections will appear first, followed by all
@samp{.rdata} input sections.
-When using EXCLUDE_FILE with more than one section, the exclusion only
-applies to the section immediately following, for example:
+When using EXCLUDE_FILE with more than one section, if the exclusion
+is within the section list then the exclusion only applies to the
+immediately following section, for example:
@smallexample
*(EXCLUDE_FILE (*somefile.o) .text .rdata)
@end smallexample
@@ -4224,10 +4235,17 @@ will cause all @samp{.text} sections from all files except
@file{somefile.o} to be included, while all @samp{.rdata} sections
from all files, including @file{somefile.o}, will be included. To
exclude the @samp{.rdata} sections from @file{somefile.o} the example
-should be modified to:
+could be modified to:
@smallexample
*(EXCLUDE_FILE (*somefile.o) .text EXCLUDE_FILE (*somefile.o) .rdata)
@end smallexample
+@noindent
+Alternatively, placing the EXCLUDE_FILE outside of the section list,
+before the input file selection, will cause the exclusion to apply for
+all sections. Thus the previous example can be rewritten as:
+@smallexample
+EXCLUDE_FILE (*somefile.o) *(.text .rdata)
+@end smallexample
You can specify a file name to include sections from a particular file.
You would do this if one or more of your files contain special data that
diff --git a/ld/ldlang.c b/ld/ldlang.c
index af2ca99..7d495c0 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -223,23 +223,16 @@ unique_section_p (const asection *sec,
/* Generic traversal routines for finding matching sections. */
-/* Try processing a section against a wildcard. This just calls
- the callback unless the filename exclusion list is present
- and excludes the file. It's hardly ever present so this
- function is very fast. */
+/* Return true if FILE matches a pattern in EXCLUDE_LIST, otherwise return
+ false. */
-static void
-walk_wild_consider_section (lang_wild_statement_type *ptr,
- lang_input_statement_type *file,
- asection *s,
- struct wildcard_list *sec,
- callback_t callback,
- void *data)
+static bfd_boolean
+walk_wild_file_in_exclude_list (struct name_list *exclude_list,
+ lang_input_statement_type *file)
{
struct name_list *list_tmp;
- /* Don't process sections from files which were excluded. */
- for (list_tmp = sec->spec.exclude_name_list;
+ for (list_tmp = exclude_list;
list_tmp;
list_tmp = list_tmp->next)
{
@@ -248,11 +241,11 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
if (p != NULL)
{
if (input_statement_is_archive_path (list_tmp->name, p, file))
- return;
+ return TRUE;
}
else if (name_match (list_tmp->name, file->filename) == 0)
- return;
+ return TRUE;
/* FIXME: Perhaps remove the following at some stage? Matching
unadorned archives like this was never documented and has
@@ -261,9 +254,29 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
&& file->the_bfd->my_archive != NULL
&& name_match (list_tmp->name,
file->the_bfd->my_archive->filename) == 0)
- return;
+ return TRUE;
}
+ return FALSE;
+}
+
+/* Try processing a section against a wildcard. This just calls
+ the callback unless the filename exclusion list is present
+ and excludes the file. It's hardly ever present so this
+ function is very fast. */
+
+static void
+walk_wild_consider_section (lang_wild_statement_type *ptr,
+ lang_input_statement_type *file,
+ asection *s,
+ struct wildcard_list *sec,
+ callback_t callback,
+ void *data)
+{
+ /* Don't process sections from files which were excluded. */
+ if (walk_wild_file_in_exclude_list (sec->spec.exclude_name_list, file))
+ return;
+
(*callback) (ptr, sec, s, ptr->section_flag_list, file, data);
}
@@ -860,6 +873,9 @@ walk_wild_file (lang_wild_statement_type *s,
callback_t callback,
void *data)
{
+ if (walk_wild_file_in_exclude_list (s->exclude_name_list, f))
+ return;
+
if (f->the_bfd == NULL
|| !bfd_check_format (f->the_bfd, bfd_archive))
walk_wild_section (s, f, callback, data);
@@ -4419,6 +4435,15 @@ print_wild_statement (lang_wild_statement_type *w,
print_space ();
+ if (w->exclude_name_list)
+ {
+ name_list *tmp;
+ minfo ("EXCLUDE_FILE(%s", w->exclude_name_list->name);
+ for (tmp = w->exclude_name_list->next; tmp; tmp = tmp->next)
+ minfo (" %s", tmp->name);
+ minfo (") ");
+ }
+
if (w->filenames_sorted)
minfo ("SORT(");
if (w->filename != NULL)
@@ -7073,11 +7098,13 @@ lang_add_wild (struct wildcard_spec *filespec,
new_stmt->filename = NULL;
new_stmt->filenames_sorted = FALSE;
new_stmt->section_flag_list = NULL;
+ new_stmt->exclude_name_list = NULL;
if (filespec != NULL)
{
new_stmt->filename = filespec->name;
new_stmt->filenames_sorted = filespec->sorted == by_name;
new_stmt->section_flag_list = filespec->section_flag_list;
+ new_stmt->exclude_name_list = filespec->exclude_name_list;
}
new_stmt->section_list = section_list;
new_stmt->keep_sections = keep_sections;
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 0cb147c..b70eb99 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -372,6 +372,7 @@ struct lang_wild_statement_struct
struct wildcard_list *section_list;
bfd_boolean keep_sections;
lang_statement_list_type children;
+ struct name_list *exclude_name_list;
walk_wild_section_handler_t walk_wild_section_handler;
struct wildcard_list *handler_data[4];
diff --git a/ld/testsuite/ld-scripts/exclude-file-1.d b/ld/testsuite/ld-scripts/exclude-file-1.d
new file mode 100644
index 0000000..068ecac
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-1.d
@@ -0,0 +1,5 @@
+#source: exclude-file-a.s
+#source: exclude-file-b.s
+#ld: -T exclude-file-1.t
+#map: exclude-file-1.map
+
diff --git a/ld/testsuite/ld-scripts/exclude-file-1.map b/ld/testsuite/ld-scripts/exclude-file-1.map
new file mode 100644
index 0000000..0fbf601
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-1.map
@@ -0,0 +1,8 @@
+#...
+\.data +0x[0-9a-f]+ +0x[0-9a-f]+
+ \*\(EXCLUDE_FILE\(\*-b\.o\) \.data \.data\.\*\)
+ \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+ \.data\.1 +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+ \.data\.1 +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-b\.o
+
+#... \ No newline at end of file
diff --git a/ld/testsuite/ld-scripts/exclude-file-1.t b/ld/testsuite/ld-scripts/exclude-file-1.t
new file mode 100644
index 0000000..f75e6c3
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-1.t
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ .data : {
+ * (EXCLUDE_FILE (*-b.o) .data .data.*)
+ }
+
+ /DISCARD/ : {
+ * (*)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/exclude-file-2.d b/ld/testsuite/ld-scripts/exclude-file-2.d
new file mode 100644
index 0000000..7c62c2f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-2.d
@@ -0,0 +1,5 @@
+#source: exclude-file-a.s
+#source: exclude-file-b.s
+#ld: -T exclude-file-2.t
+#map: exclude-file-2.map
+
diff --git a/ld/testsuite/ld-scripts/exclude-file-2.map b/ld/testsuite/ld-scripts/exclude-file-2.map
new file mode 100644
index 0000000..67acfe7
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-2.map
@@ -0,0 +1,7 @@
+#...
+\.data +0x[0-9a-f]+ +0x[0-9a-f]+
+ \*\(EXCLUDE_FILE\(\*-b\.o\) \.data EXCLUDE_FILE\(\*-b\.o\) \.data\.\*\)
+ \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+ \.data\.1 +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+
+#... \ No newline at end of file
diff --git a/ld/testsuite/ld-scripts/exclude-file-2.t b/ld/testsuite/ld-scripts/exclude-file-2.t
new file mode 100644
index 0000000..efdb5c0
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-2.t
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ .data : {
+ * (EXCLUDE_FILE (*-b.o) .data EXCLUDE_FILE (*-b.o) .data.*)
+ }
+
+ /DISCARD/ : {
+ * (*)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/exclude-file-3.d b/ld/testsuite/ld-scripts/exclude-file-3.d
new file mode 100644
index 0000000..19bfc4f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-3.d
@@ -0,0 +1,5 @@
+#source: exclude-file-a.s
+#source: exclude-file-b.s
+#ld: -T exclude-file-3.t
+#map: exclude-file-3.map
+
diff --git a/ld/testsuite/ld-scripts/exclude-file-3.map b/ld/testsuite/ld-scripts/exclude-file-3.map
new file mode 100644
index 0000000..389d170
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-3.map
@@ -0,0 +1,7 @@
+#...
+\.data +0x[0-9a-f]+ +0x[0-9a-f]+
+ EXCLUDE_FILE\(\*-b\.o\) \*\(\.data \.data\.\*\)
+ \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+ \.data\.1 +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+
+#... \ No newline at end of file
diff --git a/ld/testsuite/ld-scripts/exclude-file-3.t b/ld/testsuite/ld-scripts/exclude-file-3.t
new file mode 100644
index 0000000..4d4be58
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-3.t
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ .data : {
+ EXCLUDE_FILE (*-b.o) * (.data .data.*)
+ }
+
+ /DISCARD/ : {
+ * (*)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/exclude-file-4.d b/ld/testsuite/ld-scripts/exclude-file-4.d
new file mode 100644
index 0000000..b087fee
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-4.d
@@ -0,0 +1,5 @@
+#source: exclude-file-a.s
+#source: exclude-file-b.s
+#ld: -T exclude-file-4.t
+#map: exclude-file-4.map
+
diff --git a/ld/testsuite/ld-scripts/exclude-file-4.map b/ld/testsuite/ld-scripts/exclude-file-4.map
new file mode 100644
index 0000000..8549283
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-4.map
@@ -0,0 +1,7 @@
+#...
+\.data +0x[0-9a-f]+ +0x[0-9a-f]+
+ \*\(EXCLUDE_FILE\(\*-b\.o\) \.data EXCLUDE_FILE\(\*-a\.o\) \.data\.\*\)
+ \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o
+ \.data\.1 +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-b\.o
+
+#... \ No newline at end of file
diff --git a/ld/testsuite/ld-scripts/exclude-file-4.t b/ld/testsuite/ld-scripts/exclude-file-4.t
new file mode 100644
index 0000000..a9b03c4
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-4.t
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ .data : {
+ * (EXCLUDE_FILE (*-b.o) .data EXCLUDE_FILE (*-a.o) .data.*)
+ }
+
+ /DISCARD/ : {
+ * (*)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/exclude-file-a.s b/ld/testsuite/ld-scripts/exclude-file-a.s
new file mode 100644
index 0000000..19f5def
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-a.s
@@ -0,0 +1,5 @@
+ .section ".data", "aw"
+ .word 0x0
+
+ .section ".data.1", "aw"
+ .word 0x0
diff --git a/ld/testsuite/ld-scripts/exclude-file-b.s b/ld/testsuite/ld-scripts/exclude-file-b.s
new file mode 100644
index 0000000..19f5def
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file-b.s
@@ -0,0 +1,5 @@
+ .section ".data", "aw"
+ .word 0x0
+
+ .section ".data.1", "aw"
+ .word 0x0
diff --git a/ld/testsuite/ld-scripts/exclude-file.exp b/ld/testsuite/ld-scripts/exclude-file.exp
new file mode 100644
index 0000000..79fba17
--- /dev/null
+++ b/ld/testsuite/ld-scripts/exclude-file.exp
@@ -0,0 +1,32 @@
+# Test EXCLUDE_FILE in a linker script.
+# By Nathan Sidwell, CodeSourcery LLC
+# Copyright (C) 2004-2016 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.
+
+if { ![is_elf_format] } then {
+ unsupported exclude-file.exp
+ return
+}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/exclude-file-*.d]]
+foreach t $test_list {
+ # We need to strip the ".d", but can leave the dirname.
+ verbose [file rootname $t]
+ run_dump_test [file rootname $t]
+}