qsort: elf_sort_sections use of target_index

elf_sort_sections tried to ensure a stable qsort by using target_index
as the final comparison, but target_index hasn't been set by anything
at the time elf_sort_sections was run.  This patch arrange to have
target_index set.

	* elf.c (_bfd_elf_map_sections_to_segments): Init target_index
	for sections about to be sorted.
	(assign_file_positions_for_load_sections): Likewise.
	(elf_sort_sections): Don't bother optimising both TOEND case.
	* elflink.c (bfd_elf_final_link): Reset target_index.
This commit is contained in:
Alan Modra 2019-10-14 13:50:48 +10:30
parent 8c1c5e5de4
commit 48db329734
3 changed files with 23 additions and 10 deletions

View File

@ -1,3 +1,11 @@
2019-10-14 Alan Modra <amodra@gmail.com>
* elf.c (_bfd_elf_map_sections_to_segments): Init target_index
for sections about to be sorted.
(assign_file_positions_for_load_sections): Likewise.
(elf_sort_sections): Don't bother optimising both TOEND case.
* elflink.c (bfd_elf_final_link): Reset target_index.
2019-10-14 Alan Modra <amodra@gmail.com>
* elflink.c (elf_get_linked_section_vma): Delete.

View File

@ -4703,6 +4703,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
{
if ((s->flags & SEC_ALLOC) != 0)
{
/* target_index is unused until bfd_elf_final_link
starts output of section symbols. Use it to make
qsort stable. */
s->target_index = i;
sections[i] = s;
++i;
/* A wrapping section potentially clashes with header. */
@ -5270,14 +5274,7 @@ elf_sort_sections (const void *arg1, const void *arg2)
if (TOEND (sec1))
{
if (TOEND (sec2))
{
/* If the indices are the same, do not return 0
here, but continue to try the next comparison. */
if (sec1->target_index - sec2->target_index != 0)
return sec1->target_index - sec2->target_index;
}
else
if (!TOEND (sec2))
return 1;
}
else if (TOEND (sec2))
@ -5479,8 +5476,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (m->count > 1
&& !(elf_elfheader (abfd)->e_type == ET_CORE
&& m->p_type == PT_NOTE))
qsort (m->sections, (size_t) m->count, sizeof (asection *),
elf_sort_sections);
{
for (i = 0; i < m->count; i++)
m->sections[i]->target_index = i;
qsort (m->sections, (size_t) m->count, sizeof (asection *),
elf_sort_sections);
}
/* An ELF segment (described by Elf_Internal_Phdr) may contain a
number of sections with contents contributing to both p_filesz

View File

@ -12048,6 +12048,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
goto error_return;
}
/* _bfd_elf_compute_section_file_positions makes temporary use
of target_index. Reset it. */
o->target_index = 0;
/* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
to count upwards while actually outputting the relocations. */
esdo->rel.count = 0;