aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog13
-rw-r--r--ld/emultempl/elf32.em5
-rw-r--r--ld/emultempl/mmo.em18
-rw-r--r--ld/emultempl/pe.em25
-rw-r--r--ld/emultempl/pep.em25
-rw-r--r--ld/ldlang.c6
-rw-r--r--ld/ldlang.h2
7 files changed, 76 insertions, 18 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index d187c0c..69363e1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,16 @@
+2015-10-29 Alan Modra <amodra@gmail.com>
+
+ 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.
+
2015-10-29 Matthias Klose <doko@ubuntu.com>
* ld.texinfo (Options <-rpath>): Fix typo.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 629c414..0405d4f 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2003,8 +2003,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
}
after = place->os;
if (after == NULL)
- after = lang_output_section_find_by_flags
- (s, &place->os, _bfd_elf_match_sections_by_type);
+ after
+ = lang_output_section_find_by_flags (s, flags, &place->os,
+ _bfd_elf_match_sections_by_type);
if (after == NULL)
/* *ABS* is always the first output section statement. */
after = &lang_output_section_statement.head->output_section_statement;
diff --git a/ld/emultempl/mmo.em b/ld/emultempl/mmo.em
index 47f77d8..8949aed 100644
--- a/ld/emultempl/mmo.em
+++ b/ld/emultempl/mmo.em
@@ -88,6 +88,8 @@ mmo_place_orphan (asection *s,
lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
size_t i;
+ flagword flags;
+ asection *nexts;
/* We have nothing to say for anything other than a final link or
for sections that are excluded. */
@@ -109,9 +111,21 @@ mmo_place_orphan (asection *s,
A section without contents can have SEC_LOAD == 0, but we still
want it attached to a sane section so the symbols appear as
expected. */
- if ((s->flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
+ flags = s->flags;
+ nexts = s;
+ while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts)) != NULL)
+ 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);
+ if ((flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
- if ((s->flags & holds[i].nonzero_flags) != 0)
+ if ((flags & holds[i].nonzero_flags) != 0)
{
place = &holds[i].orphansave;
if (place->os == NULL)
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 04a7f5c..0370c5a 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -2209,6 +2209,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)
{
@@ -2226,14 +2228,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]);
@@ -2248,7 +2262,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
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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 5c7ea9f..3841afc 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1499,11 +1499,12 @@ next_matching_output_section_statement (lang_output_section_statement_type *os,
lang_output_section_statement_type *
lang_output_section_find_by_flags (const asection *sec,
+ flagword sec_flags,
lang_output_section_statement_type **exact,
lang_match_sec_type_func match_type)
{
lang_output_section_statement_type *first, *look, *found;
- flagword look_flags, sec_flags, differ;
+ flagword look_flags, differ;
/* We know the first statement on this list is *ABS*. May as well
skip it. */
@@ -1511,7 +1512,6 @@ lang_output_section_find_by_flags (const asection *sec,
first = first->next;
/* First try for an exact match. */
- sec_flags = sec->flags;
found = NULL;
for (look = first; look; look = look->next)
{
@@ -1695,7 +1695,7 @@ lang_output_section_find_by_flags (const asection *sec,
if (found || !match_type)
return found;
- return lang_output_section_find_by_flags (sec, NULL, NULL);
+ return lang_output_section_find_by_flags (sec, sec_flags, NULL, NULL);
}
/* Find the last output section before given output statement.
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 4b7e65d..32e5196 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -592,7 +592,7 @@ extern void lang_process
extern void ldlang_add_file
(lang_input_statement_type *);
extern lang_output_section_statement_type *lang_output_section_find_by_flags
- (const asection *, lang_output_section_statement_type **,
+ (const asection *, flagword, lang_output_section_statement_type **,
lang_match_sec_type_func);
extern lang_output_section_statement_type *lang_insert_orphan
(asection *, const char *, int, lang_output_section_statement_type *,