- return TRUE;
-}
-
-
-/* Compare two sections based on the locations of the sections they are
- linked to. Used by elf_fixup_link_order. */
-
-static int
-compare_link_order (const void *a, const void *b)
-{
- const struct bfd_link_order *alo = *(const struct bfd_link_order **) a;
- const struct bfd_link_order *blo = *(const struct bfd_link_order **) b;
- asection *asec = elf_linked_to_section (alo->u.indirect.section);
- asection *bsec = elf_linked_to_section (blo->u.indirect.section);
- bfd_vma apos = asec->output_section->lma + asec->output_offset;
- bfd_vma bpos = bsec->output_section->lma + bsec->output_offset;
-
- if (apos < bpos)
- return -1;
- if (apos > bpos)
- return 1;
-
- /* The only way we should get matching LMAs is when the first of two
- sections has zero size. */
- if (asec->size < bsec->size)
- return -1;
- if (asec->size > bsec->size)
- return 1;
-
- /* If they are both zero size then they almost certainly have the same
- VMA and thus are not ordered with respect to each other. Test VMA
- anyway, and fall back to id to make the result reproducible across
- qsort implementations. */
- apos = asec->output_section->vma + asec->output_offset;
- bpos = bsec->output_section->vma + bsec->output_offset;
- if (apos < bpos)
- return -1;
- if (apos > bpos)
- return 1;
-
- return asec->id - bsec->id;
-}
-
-
-/* Looks for sections with SHF_LINK_ORDER set. Rearranges them into the same
- order as their linked sections. Returns false if this could not be done
- because an output section includes both ordered and unordered
- sections. Ideally we'd do this in the linker proper. */
-
-static bfd_boolean
-elf_fixup_link_order (bfd *abfd, asection *o)
-{
- size_t seen_linkorder;
- size_t seen_other;
- size_t n;
- struct bfd_link_order *p;
- bfd *sub;
- struct bfd_link_order **sections;
- asection *other_sec, *linkorder_sec;
- bfd_vma offset; /* Octets. */
-
- other_sec = NULL;
- linkorder_sec = NULL;
- seen_other = 0;
- seen_linkorder = 0;
- for (p = o->map_head.link_order; p != NULL; p = p->next)
- {
- if (p->type == bfd_indirect_link_order)
- {
- asection *s = p->u.indirect.section;
- sub = s->owner;
- if ((s->flags & SEC_LINKER_CREATED) == 0
- && bfd_get_flavour (sub) == bfd_target_elf_flavour
- && elf_section_data (s) != NULL
- && elf_linked_to_section (s) != NULL)
- {
- seen_linkorder++;
- linkorder_sec = s;
- }
- else
- {
- seen_other++;
- other_sec = s;
- }
- }
- else
- seen_other++;
-
- if (seen_other && seen_linkorder)
- {
- if (other_sec && linkorder_sec)
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pA has both ordered [`%pA' in %pB] "
- "and unordered [`%pA' in %pB] sections"),
- o, linkorder_sec, linkorder_sec->owner,
- other_sec, other_sec->owner);
- else
- _bfd_error_handler
- (_("%pA has both ordered and unordered sections"), o);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
- }
-
- if (!seen_linkorder)
- return TRUE;
-
- sections = bfd_malloc (seen_linkorder * sizeof (*sections));
- if (sections == NULL)
- return FALSE;
-
- seen_linkorder = 0;
- for (p = o->map_head.link_order; p != NULL; p = p->next)
- sections[seen_linkorder++] = p;
-
- /* Sort the input sections in the order of their linked section. */
- qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order);
-
- /* Change the offsets of the sections. */
- offset = 0;
- for (n = 0; n < seen_linkorder; n++)
- {
- bfd_vma mask;
- asection *s = sections[n]->u.indirect.section;
- unsigned int opb = bfd_octets_per_byte (abfd, s);
-
- mask = ~(bfd_vma) 0 << s->alignment_power * opb;
- offset = (offset + ~mask) & mask;
- sections[n]->offset = s->output_offset = offset / opb;
- offset += sections[n]->size;
- }
-
- free (sections);
- return TRUE;