ld: Extend options for altering orphan handling behaviour.

Replace the options --warn-orphan and --no-warn-orphan with a single
option --orphan-handling=MODE, where mode can be place, warn, error, and
discard.

Mode 'place' is the default, and is the current behaviour, placing the
orphan section into a suitable output section.

Mode 'warn' is the same as '--warn-orphan'.  The orphan is also placed
using the same algorithm as for 'place'.

Mode 'error' is the same as '--warn-orphan' and '--fatal-warnings'.

Mode 'discard' assigns all output sections to the /DISCARD/ section.

ld/ChangeLog:

	* 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.

ld/testsuite/ChangeLog:

	* 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.
This commit is contained in:
Andrew Burgess 2015-07-28 19:20:37 +01:00
parent e65b52456b
commit c005eb9e34
18 changed files with 195 additions and 65 deletions

View file

@ -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);
}
}
}