From 2b94abd48aef2d91bae1c35c8c10ebfb8757247d Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Fri, 28 Jul 2017 13:01:10 +0100 Subject: [PATCH] Make some improvements to how SORT_* specifiers and EXCLUDE_FILE specifiers are handled in the linker script grammar. * ldgram.y (ldgram_had_keep): Make static. (ldgram_vers_current_lang): Likewise. (filename_spec): New rule. (input_section_spec_no_keep): Use filename_spec. (wildcard_maybe_exclude): New rule. (wildcard_spec): Rename to... (section_name_spec): ...this. (section_NAME_list): Rename to... (section_name_list): ...this. (section_name_spec): Simplifiy and use wildcard_maybe_exclude. * ldlang.c (placed_commons): Delete. (lang_add_wild): No longer set placed_commons. (print_wild_statement): Use full names for SORT specifiers. * testsuite/ld-scripts/align.exp: Run new tests. * testsuite/ld-scripts/align3.d: New file. * testsuite/ld-scripts/align3.t: New file. * testsuite/ld-scripts/align4.d: New file. * testsuite/ld-scripts/align4.t: New file. * testsuite/ld-scripts/align5.d: New file. * testsuite/ld-scripts/align5.t: New file. * testsuite/ld-scripts/exclude-file-5.d: New file. * testsuite/ld-scripts/exclude-file-5.map: New file. * testsuite/ld-scripts/exclude-file-5.t: New file. * testsuite/ld-scripts/exclude-file-6.d: New file. * testsuite/ld-scripts/exclude-file-6.map: New file. * testsuite/ld-scripts/exclude-file-6.t: New file. * NEWS: Mention the changes. --- ld/ChangeLog | 30 +++++++ ld/NEWS | 7 ++ ld/ldgram.y | 97 ++++++++++------------ ld/ldlang.c | 50 +++++++++-- ld/testsuite/ld-scripts/align.exp | 3 + ld/testsuite/ld-scripts/align3.d | 3 + ld/testsuite/ld-scripts/align3.t | 10 +++ ld/testsuite/ld-scripts/align4.d | 3 + ld/testsuite/ld-scripts/align4.t | 10 +++ ld/testsuite/ld-scripts/align5.d | 7 ++ ld/testsuite/ld-scripts/align5.t | 12 +++ ld/testsuite/ld-scripts/exclude-file-5.d | 5 ++ ld/testsuite/ld-scripts/exclude-file-5.map | 8 ++ ld/testsuite/ld-scripts/exclude-file-5.t | 11 +++ ld/testsuite/ld-scripts/exclude-file-6.d | 5 ++ ld/testsuite/ld-scripts/exclude-file-6.map | 8 ++ ld/testsuite/ld-scripts/exclude-file-6.t | 11 +++ ld/testsuite/ld-scripts/exclude-file-7.d | 5 ++ ld/testsuite/ld-scripts/exclude-file-7.map | 8 ++ ld/testsuite/ld-scripts/exclude-file-7.t | 11 +++ 20 files changed, 244 insertions(+), 60 deletions(-) create mode 100644 ld/testsuite/ld-scripts/align3.d create mode 100644 ld/testsuite/ld-scripts/align3.t create mode 100644 ld/testsuite/ld-scripts/align4.d create mode 100644 ld/testsuite/ld-scripts/align4.t create mode 100644 ld/testsuite/ld-scripts/align5.d create mode 100644 ld/testsuite/ld-scripts/align5.t create mode 100644 ld/testsuite/ld-scripts/exclude-file-5.d create mode 100644 ld/testsuite/ld-scripts/exclude-file-5.map create mode 100644 ld/testsuite/ld-scripts/exclude-file-5.t create mode 100644 ld/testsuite/ld-scripts/exclude-file-6.d create mode 100644 ld/testsuite/ld-scripts/exclude-file-6.map create mode 100644 ld/testsuite/ld-scripts/exclude-file-6.t create mode 100644 ld/testsuite/ld-scripts/exclude-file-7.d create mode 100644 ld/testsuite/ld-scripts/exclude-file-7.map create mode 100644 ld/testsuite/ld-scripts/exclude-file-7.t diff --git a/ld/ChangeLog b/ld/ChangeLog index fad1b7c165c..93457854a72 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,33 @@ +2017-07-28 Andrew Burgess + + * ldgram.y (ldgram_had_keep): Make static. + (ldgram_vers_current_lang): Likewise. + (filename_spec): New rule. + (input_section_spec_no_keep): Use filename_spec. + (wildcard_maybe_exclude): New rule. + (wildcard_spec): Rename to... + (section_name_spec): ...this. + (section_NAME_list): Rename to... + (section_name_list): ...this. + (section_name_spec): Simplifiy and use wildcard_maybe_exclude. + * ldlang.c (placed_commons): Delete. + (lang_add_wild): No longer set placed_commons. + (print_wild_statement): Use full names for SORT specifiers. + * testsuite/ld-scripts/align.exp: Run new tests. + * testsuite/ld-scripts/align3.d: New file. + * testsuite/ld-scripts/align3.t: New file. + * testsuite/ld-scripts/align4.d: New file. + * testsuite/ld-scripts/align4.t: New file. + * testsuite/ld-scripts/align5.d: New file. + * testsuite/ld-scripts/align5.t: New file. + * testsuite/ld-scripts/exclude-file-5.d: New file. + * testsuite/ld-scripts/exclude-file-5.map: New file. + * testsuite/ld-scripts/exclude-file-5.t: New file. + * testsuite/ld-scripts/exclude-file-6.d: New file. + * testsuite/ld-scripts/exclude-file-6.map: New file. + * testsuite/ld-scripts/exclude-file-6.t: New file. + * NEWS: Mention the changes. + 2017-07-27 Georg-Johann Lay PR ld/21849 diff --git a/ld/NEWS b/ld/NEWS index 1f5060c6cbe..13932657dc6 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,12 @@ -*- text -*- +* Tighten linker script grammar around file name specifiers to prevent the use + of SORT_BY_ALIGNMENT and SORT_BY_INIT_PRIORITY on filenames. These would + previously be accepted but had no effect. + +* The EXCLUDE_FILE directive can now be placed within any SORT_* directive + within input section lists. + Changes in 2.29: * Support for -z shstk in the x86 ELF linker to generate diff --git a/ld/ldgram.y b/ld/ldgram.y index 4c1efdc2ede..771d990a5c2 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -48,8 +48,8 @@ static enum section_type sectype; static lang_memory_region_type *region; -bfd_boolean ldgram_had_keep = FALSE; -char *ldgram_vers_current_lang = NULL; +static bfd_boolean ldgram_had_keep = FALSE; +static char *ldgram_vers_current_lang = NULL; #define ERROR_NAME_MAX 20 static char *error_names[ERROR_NAME_MAX]; @@ -92,13 +92,13 @@ static int error_index; %type opt_exp_without_type opt_subalign opt_align %type fill_opt fill_exp %type exclude_name_list -%type section_NAME_list +%type section_name_list %type sect_flag_list %type sect_flags %type memspec_opt casesymlist %type memspec_at_opt %type wildcard_name -%type wildcard_spec +%type section_name_spec filename_spec wildcard_maybe_exclude %token INT %token NAME LNAME %type length @@ -447,7 +447,7 @@ wildcard_name: } ; -wildcard_spec: +wildcard_maybe_exclude: wildcard_name { $$.name = $1; @@ -462,68 +462,63 @@ wildcard_spec: $$.exclude_name_list = $3; $$.section_flag_list = NULL; } - | SORT_BY_NAME '(' wildcard_name ')' + ; + +filename_spec: + wildcard_maybe_exclude + | SORT_BY_NAME '(' wildcard_maybe_exclude ')' { - $$.name = $3; + $$ = $3; $$.sorted = by_name; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_ALIGNMENT '(' wildcard_name ')' + | SORT_NONE '(' wildcard_maybe_exclude ')' + { + $$ = $3; + $$.sorted = by_none; + } + ; + +section_name_spec: + wildcard_maybe_exclude + | SORT_BY_NAME '(' wildcard_maybe_exclude ')' { - $$.name = $3; + $$ = $3; + $$.sorted = by_name; + } + | SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' + { + $$ = $3; $$.sorted = by_alignment; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_NONE '(' wildcard_name ')' + | SORT_NONE '(' wildcard_maybe_exclude ')' { - $$.name = $3; + $$ = $3; $$.sorted = by_none; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' + | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')' { - $$.name = $5; + $$ = $5; $$.sorted = by_name_alignment; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')' + | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')' { - $$.name = $5; + $$ = $5; $$.sorted = by_name; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')' + | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')' { - $$.name = $5; + $$ = $5; $$.sorted = by_alignment_name; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' + | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')' { - $$.name = $5; + $$ = $5; $$.sorted = by_alignment; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } - | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' + | SORT_BY_INIT_PRIORITY '(' wildcard_maybe_exclude ')' { - $$.name = $7; - $$.sorted = by_name; - $$.exclude_name_list = $5; - $$.section_flag_list = NULL; - } - | SORT_BY_INIT_PRIORITY '(' wildcard_name ')' - { - $$.name = $3; + $$ = $3; $$.sorted = by_init_priority; - $$.exclude_name_list = NULL; - $$.section_flag_list = NULL; } ; @@ -598,8 +593,8 @@ exclude_name_list: } ; -section_NAME_list: - section_NAME_list opt_comma wildcard_spec +section_name_list: + section_name_list opt_comma section_name_spec { struct wildcard_list *tmp; tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); @@ -608,7 +603,7 @@ section_NAME_list: $$ = tmp; } | - wildcard_spec + section_name_spec { struct wildcard_list *tmp; tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); @@ -637,11 +632,11 @@ input_section_spec_no_keep: tmp.section_flag_list = $1; lang_add_wild (&tmp, NULL, ldgram_had_keep); } - | '[' section_NAME_list ']' + | '[' section_name_list ']' { lang_add_wild (NULL, $2, ldgram_had_keep); } - | sect_flags '[' section_NAME_list ']' + | sect_flags '[' section_name_list ']' { struct wildcard_spec tmp; tmp.name = NULL; @@ -650,11 +645,11 @@ input_section_spec_no_keep: tmp.section_flag_list = $1; lang_add_wild (&tmp, $3, ldgram_had_keep); } - | wildcard_spec '(' section_NAME_list ')' + | filename_spec '(' section_name_list ')' { lang_add_wild (&$1, $3, ldgram_had_keep); } - | sect_flags wildcard_spec '(' section_NAME_list ')' + | sect_flags filename_spec '(' section_name_list ')' { $2.section_flag_list = $1; lang_add_wild (&$2, $4, ldgram_had_keep); diff --git a/ld/ldlang.c b/ld/ldlang.c index 726bc8e3846..b8b214dfdb0 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -61,7 +61,6 @@ static struct obstack map_obstack; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free static const char *entry_symbol_default = "start"; -static bfd_boolean placed_commons = FALSE; static bfd_boolean map_head_is_link_order = FALSE; static lang_output_section_statement_type *default_common_section; static bfd_boolean map_option_f; @@ -4414,7 +4413,7 @@ print_wild_statement (lang_wild_statement_type *w, } if (w->filenames_sorted) - minfo ("SORT("); + minfo ("SORT_BY_NAME("); if (w->filename != NULL) minfo ("%s", w->filename); else @@ -4425,8 +4424,44 @@ print_wild_statement (lang_wild_statement_type *w, minfo ("("); for (sec = w->section_list; sec; sec = sec->next) { - if (sec->spec.sorted) - minfo ("SORT("); + int closing_paren = 0; + + switch (sec->spec.sorted) + { + case none: + break; + + case by_name: + minfo ("SORT_BY_NAME("); + closing_paren = 1; + break; + + case by_alignment: + minfo ("SORT_BY_ALIGNMENT("); + closing_paren = 1; + break; + + case by_name_alignment: + minfo ("SORT_BY_NAME(SORT_BY_ALIGNMENT("); + closing_paren = 2; + break; + + case by_alignment_name: + minfo ("SORT_BY_ALIGNMENT(SORT_BY_NAME("); + closing_paren = 2; + break; + + case by_none: + minfo ("SORT_NONE("); + closing_paren = 1; + break; + + case by_init_priority: + minfo ("SORT_BY_INIT_PRIORITY("); + closing_paren = 1; + break; + } + if (sec->spec.exclude_name_list != NULL) { name_list *tmp; @@ -4439,8 +4474,8 @@ print_wild_statement (lang_wild_statement_type *w, minfo ("%s", sec->spec.name); else minfo ("*"); - if (sec->spec.sorted) - minfo (")"); + for (;closing_paren > 0; closing_paren--) + minfo (")"); if (sec->next) minfo (" "); } @@ -7238,9 +7273,6 @@ lang_add_wild (struct wildcard_spec *filespec, curr != NULL; section_list = curr, curr = next) { - if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0) - placed_commons = TRUE; - next = curr->next; curr->next = section_list; } diff --git a/ld/testsuite/ld-scripts/align.exp b/ld/testsuite/ld-scripts/align.exp index a41db721b89..ba229af74b1 100644 --- a/ld/testsuite/ld-scripts/align.exp +++ b/ld/testsuite/ld-scripts/align.exp @@ -47,6 +47,9 @@ if ![ld_link $ld tmpdir/align "$LDFLAGS -T $srcdir/$subdir/align.t tmpdir/align. if ![is_aout_format] { run_dump_test align2a run_dump_test align2b + run_dump_test align3 + run_dump_test align4 + run_dump_test align5 } run_dump_test align2c set LDFLAGS "$saved_LDFLAGS" diff --git a/ld/testsuite/ld-scripts/align3.d b/ld/testsuite/ld-scripts/align3.d new file mode 100644 index 00000000000..384d91a9e1b --- /dev/null +++ b/ld/testsuite/ld-scripts/align3.d @@ -0,0 +1,3 @@ +# source: align2a.s +# ld: -T align3.t +# error: .*:4: syntax error diff --git a/ld/testsuite/ld-scripts/align3.t b/ld/testsuite/ld-scripts/align3.t new file mode 100644 index 00000000000..5c9e5bfff96 --- /dev/null +++ b/ld/testsuite/ld-scripts/align3.t @@ -0,0 +1,10 @@ +SECTIONS +{ + .text : { + SORT_BY_ALIGNMENT (*) (.text .text.*) + } + + .data : { + SORT_BY_ALIGNMENT (*) (.data .data.*) + } +} \ No newline at end of file diff --git a/ld/testsuite/ld-scripts/align4.d b/ld/testsuite/ld-scripts/align4.d new file mode 100644 index 00000000000..661738aa21e --- /dev/null +++ b/ld/testsuite/ld-scripts/align4.d @@ -0,0 +1,3 @@ +# source: align2a.s +# ld: -T align4.t +# error: .*:4: syntax error diff --git a/ld/testsuite/ld-scripts/align4.t b/ld/testsuite/ld-scripts/align4.t new file mode 100644 index 00000000000..fc809057004 --- /dev/null +++ b/ld/testsuite/ld-scripts/align4.t @@ -0,0 +1,10 @@ +SECTIONS +{ + .text : { + SORT_BY_INIT_PRIORITY (*) (.text .text.*) + } + + .data : { + SORT_BY_INIT_PRIORITY (*) (.data .data.*) + } +} \ No newline at end of file diff --git a/ld/testsuite/ld-scripts/align5.d b/ld/testsuite/ld-scripts/align5.d new file mode 100644 index 00000000000..880b6fbb014 --- /dev/null +++ b/ld/testsuite/ld-scripts/align5.d @@ -0,0 +1,7 @@ +# source: align2a.s +# ld: -T align5.t +# nm: -n + +#... +.*foo +#... \ No newline at end of file diff --git a/ld/testsuite/ld-scripts/align5.t b/ld/testsuite/ld-scripts/align5.t new file mode 100644 index 00000000000..a0b33e58be0 --- /dev/null +++ b/ld/testsuite/ld-scripts/align5.t @@ -0,0 +1,12 @@ +SECTIONS +{ + .text : { + SORT_NONE (*) (.text .text.*) + } + + .data : { + SORT_NONE (*) (.data .data.*) + foo = .; + } + /DISCARD/ : {*(*)} +} diff --git a/ld/testsuite/ld-scripts/exclude-file-5.d b/ld/testsuite/ld-scripts/exclude-file-5.d new file mode 100644 index 00000000000..dc7040b0cc2 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-5.d @@ -0,0 +1,5 @@ +#source: exclude-file-a.s +#source: exclude-file-b.s +#ld: -T exclude-file-5.t +#map: exclude-file-5.map + diff --git a/ld/testsuite/ld-scripts/exclude-file-5.map b/ld/testsuite/ld-scripts/exclude-file-5.map new file mode 100644 index 00000000000..9148fd697c2 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-5.map @@ -0,0 +1,8 @@ +#... +\.data +0x[0-9a-f]+ +0x[0-9a-f]+ + \*\(SORT_BY_NAME\(EXCLUDE_FILE\(\*-b\.o\) \.data\)\) + \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o + \*\(SORT_BY_NAME\(EXCLUDE_FILE\(\*-a\.o\) \.data\.\*\)\) + \.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-5.t b/ld/testsuite/ld-scripts/exclude-file-5.t new file mode 100644 index 00000000000..e20f5ae198a --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-5.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data : { + * (SORT_BY_NAME (EXCLUDE_FILE (*-b.o) .data)) + * (SORT_BY_NAME (SORT_BY_NAME (EXCLUDE_FILE (*-a.o) .data.*))) + } + + /DISCARD/ : { + * (*) + } +} diff --git a/ld/testsuite/ld-scripts/exclude-file-6.d b/ld/testsuite/ld-scripts/exclude-file-6.d new file mode 100644 index 00000000000..7bc9d659b39 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-6.d @@ -0,0 +1,5 @@ +#source: exclude-file-a.s +#source: exclude-file-b.s +#ld: -T exclude-file-6.t +#map: exclude-file-6.map + diff --git a/ld/testsuite/ld-scripts/exclude-file-6.map b/ld/testsuite/ld-scripts/exclude-file-6.map new file mode 100644 index 00000000000..42e1b38157e --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-6.map @@ -0,0 +1,8 @@ +#... +\.data +0x[0-9a-f]+ +0x[0-9a-f]+ + \*\(SORT_BY_ALIGNMENT\(SORT_BY_NAME\(EXCLUDE_FILE\(\*-b\.o\) \.data\)\)\) + \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o + \*\(SORT_BY_NAME\(SORT_BY_ALIGNMENT\(EXCLUDE_FILE\(\*-a\.o\) \.data\.\*\)\)\) + \.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-6.t b/ld/testsuite/ld-scripts/exclude-file-6.t new file mode 100644 index 00000000000..437e24043ce --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-6.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data : { + * (SORT_BY_ALIGNMENT (SORT_BY_NAME (EXCLUDE_FILE (*-b.o) .data))) + * (SORT_BY_NAME (SORT_BY_ALIGNMENT (EXCLUDE_FILE (*-a.o) .data.*))) + } + + /DISCARD/ : { + * (*) + } +} diff --git a/ld/testsuite/ld-scripts/exclude-file-7.d b/ld/testsuite/ld-scripts/exclude-file-7.d new file mode 100644 index 00000000000..89704153292 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-7.d @@ -0,0 +1,5 @@ +#source: exclude-file-a.s +#source: exclude-file-b.s +#ld: -T exclude-file-7.t +#map: exclude-file-7.map + diff --git a/ld/testsuite/ld-scripts/exclude-file-7.map b/ld/testsuite/ld-scripts/exclude-file-7.map new file mode 100644 index 00000000000..eb1d0a8ce20 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-7.map @@ -0,0 +1,8 @@ +#... +\.data +0x[0-9a-f]+ +0x[0-9a-f]+ + \*\(SORT_BY_INIT_PRIORITY\(EXCLUDE_FILE\(\*-b\.o\) \.data\)\) + \.data +0x[0-9a-f]+ +0x[0-9a-f]+ tmpdir/exclude-file-a\.o + \*\(SORT_BY_ALIGNMENT\(EXCLUDE_FILE\(\*-a\.o\) \.data\.\*\)\) + \.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-7.t b/ld/testsuite/ld-scripts/exclude-file-7.t new file mode 100644 index 00000000000..200096e4ed9 --- /dev/null +++ b/ld/testsuite/ld-scripts/exclude-file-7.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data : { + * (SORT_BY_INIT_PRIORITY (EXCLUDE_FILE (*-b.o) .data)) + * (SORT_BY_ALIGNMENT (SORT_BY_ALIGNMENT (EXCLUDE_FILE (*-a.o) .data.*))) + } + + /DISCARD/ : { + * (*) + } +} -- 2.30.2