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.
This commit is contained in:
parent
26656b1dc6
commit
199af15039
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue