aboutsummaryrefslogtreecommitdiff
path: root/bfd
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 /bfd
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 'bfd')
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/elflink.c21
-rw-r--r--bfd/section.c20
-rw-r--r--bfd/tekhex.c6
5 files changed, 34 insertions, 26 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1ef747e..3f9a3de 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2015-10-28 Alan Modra <amodra@gmail.com>
+
+ 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.
+
2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com>
Christophe Monat <christophe.monat@st.com>
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f381f06..85fa3ab 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1810,7 +1810,7 @@ void bfd_section_list_clear (bfd *);
asection *bfd_get_section_by_name (bfd *abfd, const char *name);
-asection *bfd_get_next_section_by_name (asection *sec);
+asection *bfd_get_next_section_by_name (bfd *ibfd, asection *sec);
asection *bfd_get_linker_section (bfd *abfd, const char *name);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1cfdd31..1b41c79 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12179,8 +12179,6 @@ _bfd_elf_gc_mark_reloc (struct bfd_link_info *info,
rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie, &start_stop);
while (rsec != NULL)
{
- asection *s;
-
if (!rsec->gc_mark)
{
if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour
@@ -12191,22 +12189,7 @@ _bfd_elf_gc_mark_reloc (struct bfd_link_info *info,
}
if (!start_stop)
break;
- s = bfd_get_next_section_by_name (rsec);
- if (s == NULL)
- {
- bfd *i = rsec->owner;
-
- if (i != NULL)
- {
- while ((i = i->link.next) != NULL)
- {
- s = bfd_get_section_by_name (i, rsec->name);
- if (s != NULL)
- break;
- }
- }
- }
- rsec = s;
+ rsec = bfd_get_next_section_by_name (rsec->owner, rsec);
}
return TRUE;
}
@@ -12757,7 +12740,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
&& (sec->flags & SEC_LINKER_CREATED) == 0)
elf_eh_frame_section (sub) = sec;
fini_reloc_cookie_for_section (&cookie, sec);
- sec = bfd_get_next_section_by_name (sec);
+ sec = bfd_get_next_section_by_name (NULL, sec);
}
}
diff --git a/bfd/section.c b/bfd/section.c
index 834a9ab..247d98a 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -903,16 +903,18 @@ FUNCTION
bfd_get_next_section_by_name
SYNOPSIS
- asection *bfd_get_next_section_by_name (asection *sec);
+ asection *bfd_get_next_section_by_name (bfd *ibfd, asection *sec);
DESCRIPTION
Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
return the next most recently created section attached to the same
- BFD with the same name. Return NULL if no such section exists.
+ BFD with the same name, or if no such section exists in the same BFD and
+ IBFD is non-NULL, the next section with the same name in any input
+ BFD following IBFD. Return NULL on finding no section.
*/
asection *
-bfd_get_next_section_by_name (asection *sec)
+bfd_get_next_section_by_name (bfd *ibfd, asection *sec)
{
struct section_hash_entry *sh;
const char *name;
@@ -930,6 +932,16 @@ bfd_get_next_section_by_name (asection *sec)
&& strcmp (sh->root.string, name) == 0)
return &sh->section;
+ if (ibfd != NULL)
+ {
+ while ((ibfd = ibfd->link.next) != NULL)
+ {
+ asection *s = bfd_get_section_by_name (ibfd, name);
+ if (s != NULL)
+ return s;
+ }
+ }
+
return NULL;
}
@@ -951,7 +963,7 @@ bfd_get_linker_section (bfd *abfd, const char *name)
asection *sec = bfd_get_section_by_name (abfd, name);
while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0)
- sec = bfd_get_next_section_by_name (sec);
+ sec = bfd_get_next_section_by_name (NULL, sec);
return sec;
}
diff --git a/bfd/tekhex.c b/bfd/tekhex.c
index ccc68f9..951c327 100644
--- a/bfd/tekhex.c
+++ b/bfd/tekhex.c
@@ -459,7 +459,8 @@ first_phase (bfd *abfd, int type, char *src, char * src_end)
else
{
if (alt_section == NULL)
- alt_section = bfd_get_next_section_by_name (section);
+ alt_section
+ = bfd_get_next_section_by_name (NULL, section);
if (alt_section == NULL)
alt_section = bfd_make_section_anyway_with_flags
(abfd, section->name,
@@ -476,7 +477,8 @@ first_phase (bfd *abfd, int type, char *src, char * src_end)
else
{
if (alt_section == NULL)
- alt_section = bfd_get_next_section_by_name (section);
+ alt_section
+ = bfd_get_next_section_by_name (NULL, section);
if (alt_section == NULL)
alt_section = bfd_make_section_anyway_with_flags
(abfd, section->name,