diff options
-rw-r--r-- | ld/ChangeLog | 13 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 5 | ||||
-rw-r--r-- | ld/emultempl/mmo.em | 18 | ||||
-rw-r--r-- | ld/emultempl/pe.em | 25 | ||||
-rw-r--r-- | ld/emultempl/pep.em | 25 | ||||
-rw-r--r-- | ld/ldlang.c | 6 | ||||
-rw-r--r-- | ld/ldlang.h | 2 |
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 *, |