diff options
author | Alan Modra <amodra@gmail.com> | 2015-10-28 17:18:13 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-10-28 17:51:10 +1030 |
commit | 199af1503922ce2134d774a78be0d9e2ae055ab1 (patch) | |
tree | dd1fcec6689ca3acbd5ef488fc0f5db79581fb1e /ld/emultempl | |
parent | 26656b1dc6c00f2eea0d329cc2637aebf3da1458 (diff) | |
download | fsf-binutils-gdb-199af1503922ce2134d774a78be0d9e2ae055ab1.zip fsf-binutils-gdb-199af1503922ce2134d774a78be0d9e2ae055ab1.tar.gz fsf-binutils-gdb-199af1503922ce2134d774a78be0d9e2ae055ab1.tar.bz2 |
Orphan output section with multiple input sections
If given input sections with differing flags, we'd like to place the
section according to the final output section flags.
bfd/
PR ld/19162
* elflink.c (_bfd_elf_gc_mark_reloc): Move code iterating over
linker input bfds..
* section.c (bfd_get_next_section_by_name): ..to here. Add ibfd param.
(bfd_get_linker_section): Adjust bfd_get_next_section_by_name call.
* tekhex.c (first_phase): Likewise.
* elflink.c (bfd_elf_gc_sections): Likewise.
* bfd-in2.h: Regenerate.
ld/
PR ld/19162
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Check flags
before calling _bfd_elf_match_sections_by_type. Merge flags for
any other input sections that might match a new output section to
decide placement.
Diffstat (limited to 'ld/emultempl')
-rw-r--r-- | ld/emultempl/elf32.em | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 1dc215f..629c414 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1852,6 +1852,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s, int isdyn = 0; int iself = s->owner->xvec->flavour == bfd_target_elf_flavour; unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL; + flagword flags; + asection *nexts; if (!bfd_link_relocatable (&link_info) && link_info.combreloc @@ -1890,11 +1892,11 @@ gld${EMULATION_NAME}_place_orphan (asection *s, if (os->bfd_section != NULL && (os->bfd_section->flags == 0 - || (_bfd_elf_match_sections_by_type (link_info.output_bfd, - os->bfd_section, - s->owner, s) - && ((s->flags ^ os->bfd_section->flags) - & (SEC_LOAD | SEC_ALLOC)) == 0))) + || (((s->flags ^ os->bfd_section->flags) + & (SEC_LOAD | SEC_ALLOC)) == 0 + && _bfd_elf_match_sections_by_type (link_info.output_bfd, + os->bfd_section, + s->owner, s)))) { /* We already have an output section statement with this name, and its bfd section has compatible flags. @@ -1950,28 +1952,41 @@ gld${EMULATION_NAME}_place_orphan (asection *s, stored right after the program headers where the OS can read it in the first page. */ + 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) + && _bfd_elf_match_sections_by_type (nexts->owner, nexts, s->owner, s)) + flags = (((flags ^ SEC_READONLY) | (nexts->flags ^ SEC_READONLY)) + ^ SEC_READONLY); place = NULL; - if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0) + if ((flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0) place = &hold[orphan_nonalloc]; - else if ((s->flags & SEC_ALLOC) == 0) + else if ((flags & SEC_ALLOC) == 0) ; - else if ((s->flags & SEC_LOAD) != 0 + else if ((flags & SEC_LOAD) != 0 && ((iself && sh_type == SHT_NOTE) || (!iself && CONST_STRNEQ (secname, ".note")))) place = &hold[orphan_interp]; - else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0) + else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0) place = &hold[orphan_bss]; - else if ((s->flags & SEC_SMALL_DATA) != 0) + else if ((flags & SEC_SMALL_DATA) != 0) place = &hold[orphan_sdata]; - else if ((s->flags & SEC_THREAD_LOCAL) != 0) + else if ((flags & SEC_THREAD_LOCAL) != 0) place = &hold[orphan_tdata]; - else if ((s->flags & SEC_READONLY) == 0) + else if ((flags & SEC_READONLY) == 0) place = &hold[orphan_data]; else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL)) || (!iself && CONST_STRNEQ (secname, ".rel"))) - && (s->flags & SEC_LOAD) != 0) + && (flags & SEC_LOAD) != 0) place = &hold[orphan_rel]; - else if ((s->flags & SEC_CODE) == 0) + else if ((flags & SEC_CODE) == 0) place = &hold[orphan_rodata]; else place = &hold[orphan_text]; |