aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-10-28 17:18:13 +1030
committerAlan Modra <amodra@gmail.com>2015-10-28 17:51:10 +1030
commit199af1503922ce2134d774a78be0d9e2ae055ab1 (patch)
treedd1fcec6689ca3acbd5ef488fc0f5db79581fb1e /ld
parent26656b1dc6c00f2eea0d329cc2637aebf3da1458 (diff)
downloadfsf-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')
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/emultempl/elf32.em43
2 files changed, 37 insertions, 14 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 359fc19..5b9ac97 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-28 Alan Modra <amodra@gmail.com>
+
+ 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.
+
2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com>
Christophe Monat <christophe.monat@st.com>
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];