+2015-07-28 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * 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 <nickc@redhat.com>
* ld.texinfo (--build-id): Fix typo. The COFF/PE build-id section
* 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.
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;
/* 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). */
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
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
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
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;
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. */
}
}
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);
}
}
}
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 ,
OPTION_POP_STATE,
OPTION_PRINT_MEMORY_USAGE,
OPTION_REQUIRE_DEFINED_SYMBOL,
+ OPTION_ORPHAN_HANDLING,
};
/* The initial parser states. */
'\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 },
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)
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;
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;
}
}
+2015-07-28 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * 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 <hongjiu.lu@intel.com>
* ld-ifunc/ifunc-21-i386.s: Add tests for call, jmp, add, test.
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*] } {
--- /dev/null
+#name: Report warning for orphan sections
+#ld: --script orphan.ld --orphan-handling=warn
+#source: orphan.s
+#warning_output: orphan-5.l
#...
-.*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'\.
#...
--- /dev/null
+#name: Report error for orphan sections
+#ld: --script orphan.ld --orphan-handling=error
+#source: orphan.s
+#error_output: orphan-6.l
--- /dev/null
+#...
+.*error: unplaced orphan section `\.notbad' from `tmpdir/orphan\.o'\.
+#...
+.*error: unplaced orphan section `\.note\.bar' from `tmpdir/orphan\.o'\.
+#...
--- /dev/null
+#name: Discard orphan sections
+#ld: --script orphan.ld --orphan-handling=discard
+#source: orphan.s
+#map: orphan-7.map
--- /dev/null
+
+Discarded input sections
+
+ \.notbad 0x0+ 0x4 tmpdir/.*\.o
+ \.note\.bar 0x0+ 0x4 tmpdir/.*\.o
+
+#...
--- /dev/null
+#name: Place orphan sections
+#ld: --script orphan.ld --orphan-handling=place
+#source: orphan.s
+#map: orphan-8.map
--- /dev/null
+#...
+.notbad 0x0000000000000004 0x4
+ .notbad 0x0000000000000004 0x4 tmpdir/dump0.o
+#...
+.note.bar 0x0000000000000010 0x4
+ .note.bar 0x0000000000000010 0x4 tmpdir/dump0.o
+#...