aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/pep.em
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-10-29 16:16:22 +1030
committerAlan Modra <amodra@gmail.com>2015-10-29 19:42:50 +1030
commit936384714fa8b0f7ca8cc3b5637394461bc998c8 (patch)
tree2dbee0b6a2d5c5b00506e43e5e24c7090f284345 /ld/emultempl/pep.em
parentd85063237a6a579905f9a3ead5749fb4e931dec3 (diff)
downloadbinutils-936384714fa8b0f7ca8cc3b5637394461bc998c8.zip
binutils-936384714fa8b0f7ca8cc3b5637394461bc998c8.tar.gz
binutils-936384714fa8b0f7ca8cc3b5637394461bc998c8.tar.bz2
Re: Orphan output section with multiple input sections
The last patch missed handling the case where the ideal place to put an orphan was after a non-existent output section statement, as can happen when not using the builtin linker scripts. This patch uses the updated flags for that case too, and extends the support to mmo and pe. PR ld/19162 * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Pass updated flags to lang_output_section_find_by_flags. * emultempl/mmo.em (mmo_place_orphan): Merge flags for any other input sections that might match a new output section to decide placement. * emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Likewise. * emultempl/pep.em (gld_${EMULATION_NAME}_place_orphan): Likewise. * ldlang.c (lang_output_section_find_by_flags): Add sec_flags param. * ldlang.h (lang_output_section_find_by_flags): Update prototype.
Diffstat (limited to 'ld/emultempl/pep.em')
-rw-r--r--ld/emultempl/pep.em25
1 files changed, 20 insertions, 5 deletions
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 0b740c3..91de501 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1980,6 +1980,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
struct orphan_save *place;
lang_output_section_statement_type *after;
etree_type *address;
+ flagword flags;
+ asection *nexts;
if (!orphan_init_done)
{
@@ -1997,14 +1999,26 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
/* Try to put the new output section in a reasonable place based
on the section name and section flags. */
+ flags = s->flags;
+ nexts = s;
+ while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts)))
+ if (nexts->output_section == NULL
+ && (nexts->flags & SEC_EXCLUDE) == 0
+ && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
+ && (nexts->owner->flags & DYNAMIC) == 0
+ && nexts->owner->usrdata != NULL
+ && !(((lang_input_statement_type *) nexts->owner->usrdata)
+ ->flags.just_syms))
+ flags = (((flags ^ SEC_READONLY) | (nexts->flags ^ SEC_READONLY))
+ ^ SEC_READONLY);
place = NULL;
- if ((s->flags & SEC_ALLOC) == 0)
+ if ((flags & SEC_ALLOC) == 0)
;
- else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
place = &hold[orphan_bss];
- else if ((s->flags & SEC_READONLY) == 0)
+ else if ((flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
- else if ((s->flags & SEC_CODE) == 0)
+ else if ((flags & SEC_CODE) == 0)
{
place = (!strncmp (secname, ".idata\$", 7) ? &hold[orphan_idata]
: &hold[orphan_rodata]);
@@ -2019,7 +2033,8 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
place->os = lang_output_section_find (place->name);
after = place->os;
if (after == NULL)
- after = lang_output_section_find_by_flags (s, &place->os, NULL);
+ after = lang_output_section_find_by_flags (s, flags, &place->os,
+ NULL);
if (after == NULL)
/* *ABS* is always the first output section statement. */
after = (&lang_output_section_statement.head