diff --git a/ld/ChangeLog b/ld/ChangeLog index 7c60d9bbe4..a9eb7c8f44 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2015-07-28 Andrew Burgess + + * ld.h (enum orphan_handling_enum): New. + (ld_config_type): Remove warn_orphan, add orphan_handling. + * ldemul.c (ldemul_place_orphan): Remove warning about orphan + sections. + * ldlang.c (ldlang_place_orphan): New function. + (lang_place_orphans): Call ldlang_place_orphan. + * ldlex.h (enum option_values): Remove OPTION_WARN_ORPHAN and + OPTION_NO_WARN_ORPHAN, add OPTION_ORPHAN_HANDLING. + * lexsup.c (ld_options): Remove 'warn-orphan' and + 'no-warn-orphan', add 'orphan-handling'. + (parse_args): Remove handling for OPTION_WARN_ORPHAN and + OPTION_NO_WARN_ORPHAN, add handling for OPTION_ORPHAN_HANDLING. + * NEWS: Replace text about --warn-orphan with --orphan-handling. + * ld.texinfo (Options): Remove --warn-orphan entry and add + entry on --orphan-handling. + (Orphan Sections): Add reference to relevant command line options. + 2015-09-03 Nick Clifton * ld.texinfo (--build-id): Fix typo. The COFF/PE build-id section diff --git a/ld/NEWS b/ld/NEWS index f9ef88dac5..864384b5d8 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -6,7 +6,11 @@ * New command line option for ELF targets to compress DWARF debug sections, --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]. -* Add --warn-orphan option to report orphan sections. +* New command line option, --orphan-handling=[place|warn|error|discard], to + adjust how orphan sections are handled. The default is 'place' which gives + the current behaviour, 'warn' and 'error' issue a warning or error + respectively when orphan sections are found, and 'discard' will discard all + orphan sections. * Add support for LLVM plugin. diff --git a/ld/ld.h b/ld/ld.h index e6ebaae90f..d84ec4e634 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -207,6 +207,25 @@ extern args_type command_line; typedef int token_code_type; +/* Different ways we can handle orphan sections. */ + +enum orphan_handling_enum { + /* The classic strategy, find a suitable section to place the orphan + into. */ + orphan_handling_place = 0, + + /* Discard any orphan sections as though they were assign to the section + /DISCARD/. */ + orphan_handling_discard, + + /* Find somewhere to place the orphan section, as with + ORPHAN_HANDLING_PLACE, but also issue a warning. */ + orphan_handling_warn, + + /* Issue a fatal error if any orphan sections are found. */ + orphan_handling_error, +}; + typedef struct { bfd_boolean magic_demand_paged; bfd_boolean make_executable; @@ -229,8 +248,8 @@ typedef struct { /* If TRUE, only warn once about a particular undefined symbol. */ bfd_boolean warn_once; - /* If TRUE, issue warning messages when orphan sections are encountered. */ - bfd_boolean warn_orphan; + /* How should we deal with orphan sections. */ + enum orphan_handling_enum orphan_handling; /* If TRUE, warn if multiple global-pointers are needed (Alpha only). */ diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 2c78a07c3c..d20a59fd34 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1001,6 +1001,35 @@ with @samp{-Ur}; once the constructor table has been built, it cannot be added to. Use @samp{-Ur} only for the last partial link, and @samp{-r} for the others. +@kindex --orphan-handling=@var{MODE} +@cindex orphan sections +@cindex sections, orphan +@item --orphan-handling=@var{MODE} +Control how orphan sections are handled. An orphan section is one not +specifically mentioned in a linker script. @xref{Orphan Sections}. + +@var{MODE} can have any of the following values: + +@table @code +@item place +Orphan sections are placed into a suitable output section following +the strategy described in @ref{Orphan Sections}. The option +@samp{--unique} also effects how sections are placed. + +@item discard +All orphan sections are discarded, by placing them in the +@samp{/DISCARD/} section (@pxref{Output Section Discarding}). + +@item warn +The linker will place the orphan section as for @code{place} and also +issue a warning. + +@item error +The linker will exit with an error if any orphan section is found. +@end table + +The default if @samp{--orphan-handling} is not given is @code{place}. + @kindex --unique[=@var{SECTION}] @item --unique[=@var{SECTION}] Creates a separate output section for every input section matching @@ -2105,17 +2134,6 @@ option causes a warning to be issued whenever this case occurs. Only warn once for each undefined symbol, rather than once per module which refers to it. -@kindex --warn-orphan -@kindex --no-warn-orphan -@cindex warnings, on orphan sections -@cindex orphan sections, warnings on -@item --warn-orphan -The @option{--warn-orphan} option tells the linker to generate a -warning message whenever it has to place an orphan section into the -output file. @xref{Orphan Sections}. The @option{--no-warn-orphan} -option restores the default behaviour of just silently placing these -sections. - @kindex --warn-section-align @cindex warnings, on section alignment @cindex section alignment, warnings on @@ -5569,6 +5587,10 @@ at the end of the file. For ELF targets, the attribute of the section includes section type as well as section flag. +The command line options @samp{--orphan-handling} and @samp{--unique} +(@pxref{Options,,Command Line Options}) can be used to control which +output sections an orphan is placed in. + If an orphaned section's name is representable as a C identifier then the linker will automatically @pxref{PROVIDE} two symbols: __start_SECNAME and __stop_SECNAME, where SECNAME is the name of the diff --git a/ld/ldemul.c b/ld/ldemul.c index 596418e911..22c79744d9 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -120,10 +120,6 @@ ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search, lang_output_section_statement_type * ldemul_place_orphan (asection *s, const char *name, int constraint) { - if (config.warn_orphan) - einfo (_("%P: Warning: input section '%s' from file '%B' is not mentioned in linker script\n"), - name, s->owner); - if (ld_emulation->place_orphan) return (*ld_emulation->place_orphan) (s, name, constraint); return NULL; diff --git a/ld/ldlang.c b/ld/ldlang.c index 6ee3f84310..3d2cc99495 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6102,6 +6102,55 @@ lang_one_common (struct bfd_link_hash_entry *h, void *info) return TRUE; } +/* Handle a single orphan section S, placing the orphan into an appropriate + output section. The effects of the --orphan-handling command line + option are handled here. */ + +static void +ldlang_place_orphan (asection *s) +{ + if (config.orphan_handling == orphan_handling_discard) + { + lang_output_section_statement_type *os; + os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0, + TRUE); + if (os->addr_tree == NULL + && (bfd_link_relocatable (&link_info) + || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) + os->addr_tree = exp_intop (0); + lang_add_section (&os->children, s, NULL, os); + } + else + { + lang_output_section_statement_type *os; + const char *name = s->name; + int constraint = 0; + + if (config.orphan_handling == orphan_handling_error) + einfo ("%X%P: error: unplaced orphan section `%A' from `%B'.\n", + s, s->owner); + + if (config.unique_orphan_sections || unique_section_p (s, NULL)) + constraint = SPECIAL; + + os = ldemul_place_orphan (s, name, constraint); + if (os == NULL) + { + os = lang_output_section_statement_lookup (name, constraint, TRUE); + if (os->addr_tree == NULL + && (bfd_link_relocatable (&link_info) + || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) + os->addr_tree = exp_intop (0); + lang_add_section (&os->children, s, NULL, os); + } + + if (config.orphan_handling == orphan_handling_warn) + einfo ("%P: warning: orphan section `%A' from `%B' being " + "placed in section `%s'.\n", + s, s->owner, os->name); + } +} + /* Run through the input files and ensure that every input section has somewhere to go. If one is found without a destination then create an input request and place it into the statement tree. */ @@ -6141,27 +6190,7 @@ lang_place_orphans (void) } } else - { - const char *name = s->name; - int constraint = 0; - - if (config.unique_orphan_sections - || unique_section_p (s, NULL)) - constraint = SPECIAL; - - if (!ldemul_place_orphan (s, name, constraint)) - { - lang_output_section_statement_type *os; - os = lang_output_section_statement_lookup (name, - constraint, - TRUE); - if (os->addr_tree == NULL - && (bfd_link_relocatable (&link_info) - || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) - os->addr_tree = exp_intop (0); - lang_add_section (&os->children, s, NULL, os); - } - } + ldlang_place_orphan (s); } } } diff --git a/ld/ldlex.h b/ld/ldlex.h index 59bd14f653..5629ef19f1 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -85,8 +85,6 @@ enum option_values OPTION_NO_WARN_FATAL, OPTION_WARN_MULTIPLE_GP, OPTION_WARN_ONCE, - OPTION_WARN_ORPHAN, - OPTION_NO_WARN_ORPHAN, OPTION_WARN_SECTION_ALIGN, OPTION_SPLIT_BY_RELOC, OPTION_SPLIT_BY_FILE , @@ -144,6 +142,7 @@ enum option_values OPTION_POP_STATE, OPTION_PRINT_MEMORY_USAGE, OPTION_REQUIRE_DEFINED_SYMBOL, + OPTION_ORPHAN_HANDLING, }; /* The initial parser states. */ diff --git a/ld/lexsup.c b/ld/lexsup.c index ace1803356..5dc56dc148 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -492,10 +492,6 @@ static const struct ld_option ld_options[] = '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES }, { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES }, - { {"warn-orphan", no_argument, NULL, OPTION_WARN_ORPHAN}, - '\0', NULL, N_("Warn if any orphan sections are encountered"), TWO_DASHES }, - { {"no-warn-orphan", no_argument, NULL, OPTION_NO_WARN_ORPHAN}, - '\0', NULL, N_("Do not warn if orphan sections are encountered (default)"), TWO_DASHES }, { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN}, '\0', NULL, N_("Warn if start of section changes due to alignment"), TWO_DASHES }, @@ -528,6 +524,9 @@ static const struct ld_option ld_options[] = TWO_DASHES }, { {"print-memory-usage", no_argument, NULL, OPTION_PRINT_MEMORY_USAGE}, '\0', NULL, N_("Report target memory usage"), TWO_DASHES }, + { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, + '\0', N_("=MODE"), N_("Control how orphan sections are handled."), + TWO_DASHES }, }; #define OPTION_COUNT ARRAY_SIZE (ld_options) @@ -1375,12 +1374,6 @@ parse_args (unsigned argc, char **argv) case OPTION_WARN_ONCE: config.warn_once = TRUE; break; - case OPTION_WARN_ORPHAN: - config.warn_orphan = TRUE; - break; - case OPTION_NO_WARN_ORPHAN: - config.warn_orphan = FALSE; - break; case OPTION_WARN_SECTION_ALIGN: config.warn_section_align = TRUE; break; @@ -1515,6 +1508,20 @@ parse_args (unsigned argc, char **argv) case OPTION_PRINT_MEMORY_USAGE: command_line.print_memory_usage = TRUE; break; + + case OPTION_ORPHAN_HANDLING: + if (strcasecmp (optarg, "place") == 0) + config.orphan_handling = orphan_handling_place; + else if (strcasecmp (optarg, "warn") == 0) + config.orphan_handling = orphan_handling_warn; + else if (strcasecmp (optarg, "error") == 0) + config.orphan_handling = orphan_handling_error; + else if (strcasecmp (optarg, "discard") == 0) + config.orphan_handling = orphan_handling_discard; + else + einfo (_("%P%F: invalid argument to option" + " \"--orphan-handling\"\n")); + break; } } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 34ed02d1ab..5ca0f6cc65 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2015-07-28 Andrew Burgess + + * ld-elf/elf.exp: Switch to rely on run_dump_test. + * ld-elf/orphan-5.l: Update expected output. + * ld-elf/orphan-5.d: New file. + * ld-elf/orphan-6.d: New file. + * ld-elf/orphan-6.l: New file. + * ld-elf/orphan-7.d: New file. + * ld-elf/orphan-7.map: New file. + * ld-elf/orphan-8.d: New file. + * ld-elf/orphan-8.map: New file. + 2015-09-03 H.J. Lu * ld-ifunc/ifunc-21-i386.s: Add tests for call, jmp, add, test. diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp index 55bcb7275b..e56c2054a6 100644 --- a/ld/testsuite/ld-elf/elf.exp +++ b/ld/testsuite/ld-elf/elf.exp @@ -124,18 +124,6 @@ foreach t $test_list { run_dump_test [file rootname $t] } -# Check that the --warn-orphan option works correctly. -run_ld_link_tests { - {"Report orphan sections" - "--script orphan.ld --warn-orphan" - "" - "" - {orphan.s} - { { ld "orphan-5.l" } } - "orphan" - } -} - if { [istarget *-*-linux*] || [istarget *-*-nacl*] || [istarget *-*-gnu*] } { diff --git a/ld/testsuite/ld-elf/orphan-5.d b/ld/testsuite/ld-elf/orphan-5.d new file mode 100644 index 0000000000..4f99cd0d51 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-5.d @@ -0,0 +1,4 @@ +#name: Report warning for orphan sections +#ld: --script orphan.ld --orphan-handling=warn +#source: orphan.s +#warning_output: orphan-5.l diff --git a/ld/testsuite/ld-elf/orphan-5.l b/ld/testsuite/ld-elf/orphan-5.l index 7b65af206e..20a9fe7c76 100644 --- a/ld/testsuite/ld-elf/orphan-5.l +++ b/ld/testsuite/ld-elf/orphan-5.l @@ -1,5 +1,5 @@ #... -.*Warning: input section '.notbad' from file 'tmpdir/orphan.o' is not mentioned in linker script +.*warning: orphan section `\.notbad' from `tmpdir/orphan\.o' being placed in section `\.notbad'\. #... -.*Warning: input section '.note.bar' from file 'tmpdir/orphan.o' is not mentioned in linker script +.*warning: orphan section `\.note\.bar' from `tmpdir/orphan\.o' being placed in section `\.note\.bar'\. #... diff --git a/ld/testsuite/ld-elf/orphan-6.d b/ld/testsuite/ld-elf/orphan-6.d new file mode 100644 index 0000000000..c6565fbab5 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-6.d @@ -0,0 +1,4 @@ +#name: Report error for orphan sections +#ld: --script orphan.ld --orphan-handling=error +#source: orphan.s +#error_output: orphan-6.l diff --git a/ld/testsuite/ld-elf/orphan-6.l b/ld/testsuite/ld-elf/orphan-6.l new file mode 100644 index 0000000000..5ac7895c1c --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-6.l @@ -0,0 +1,5 @@ +#... +.*error: unplaced orphan section `\.notbad' from `tmpdir/orphan\.o'\. +#... +.*error: unplaced orphan section `\.note\.bar' from `tmpdir/orphan\.o'\. +#... diff --git a/ld/testsuite/ld-elf/orphan-7.d b/ld/testsuite/ld-elf/orphan-7.d new file mode 100644 index 0000000000..01d6e8020f --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-7.d @@ -0,0 +1,4 @@ +#name: Discard orphan sections +#ld: --script orphan.ld --orphan-handling=discard +#source: orphan.s +#map: orphan-7.map diff --git a/ld/testsuite/ld-elf/orphan-7.map b/ld/testsuite/ld-elf/orphan-7.map new file mode 100644 index 0000000000..52cc359d34 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-7.map @@ -0,0 +1,7 @@ + +Discarded input sections + + \.notbad 0x0+ 0x4 tmpdir/.*\.o + \.note\.bar 0x0+ 0x4 tmpdir/.*\.o + +#... diff --git a/ld/testsuite/ld-elf/orphan-8.d b/ld/testsuite/ld-elf/orphan-8.d new file mode 100644 index 0000000000..bbd7288dc8 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-8.d @@ -0,0 +1,4 @@ +#name: Place orphan sections +#ld: --script orphan.ld --orphan-handling=place +#source: orphan.s +#map: orphan-8.map diff --git a/ld/testsuite/ld-elf/orphan-8.map b/ld/testsuite/ld-elf/orphan-8.map new file mode 100644 index 0000000000..b672978580 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-8.map @@ -0,0 +1,7 @@ +#... +.notbad 0x0000000000000004 0x4 + .notbad 0x0000000000000004 0x4 tmpdir/dump0.o +#... +.note.bar 0x0000000000000010 0x4 + .note.bar 0x0000000000000010 0x4 tmpdir/dump0.o +#...