/* Emulation code used by all ELF targets.
- Copyright (C) 1991-2021 Free Software Foundation, Inc.
+ Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
/* Add IS to data kept for OS. */
-static bfd_boolean
+static bool
add_link_order_input_section (lang_input_section_type *is,
lang_output_section_statement_type *os)
{
os_info->isec[os_info->count].idx = os_info->count;
os_info->count++;
s = is->section;
- if ((s->flags & SEC_LINKER_CREATED) == 0
- && elf_section_data (s) != NULL
+ if (bfd_get_flavour (s->owner) == bfd_target_elf_flavour
+ && (s->flags & SEC_LINKER_CREATED) == 0
&& elf_linked_to_section (s) != NULL)
os_info->ordered++;
- return FALSE;
+ return false;
}
/* Run over the linker's statement list, extracting info about input
sections attached to each output section. */
-static bfd_boolean
+static bool
link_order_scan (lang_statement_union_type *u,
lang_output_section_statement_type *os)
{
asection *s;
- bfd_boolean ret = FALSE;
+ bool ret = false;
for (; u != NULL; u = u->header.next)
{
{
case lang_wild_statement_enum:
if (link_order_scan (u->wild_statement.children.head, os))
- ret = TRUE;
+ ret = true;
break;
case lang_constructors_statement_enum:
if (link_order_scan (constructor_list.head, os))
- ret = TRUE;
+ ret = true;
break;
case lang_output_section_statement_enum:
if (u->output_section_statement.constraint != -1
&& link_order_scan (u->output_section_statement.children.head,
&u->output_section_statement))
- ret = TRUE;
+ ret = true;
break;
case lang_group_statement_enum:
if (link_order_scan (u->group_statement.children.head, os))
- ret = TRUE;
+ ret = true;
break;
case lang_input_section_enum:
s = u->input_section.section;
|| ((s->output_section->flags & (SEC_LOAD | SEC_THREAD_LOCAL))
== (SEC_LOAD | SEC_THREAD_LOCAL))))
if (add_link_order_input_section (&u->input_section, os))
- ret = TRUE;
+ ret = true;
break;
default:
break;
{
const struct os_sections_input *ai = a;
const struct os_sections_input *bi = b;
- asection *asec = elf_linked_to_section (ai->is->section);
- asection *bsec = elf_linked_to_section (bi->is->section);
+ asection *asec = NULL;
+ asection *bsec = NULL;
bfd_vma apos, bpos;
+ if (bfd_get_flavour (ai->is->section->owner) == bfd_target_elf_flavour)
+ asec = elf_linked_to_section (ai->is->section);
+ if (bfd_get_flavour (bi->is->section->owner) == bfd_target_elf_flavour)
+ bsec = elf_linked_to_section (bi->is->section);
+
/* Place unordered sections before ordered sections. */
if (asec == NULL || bsec == NULL)
{
else 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;
- else if (asec->size > bsec->size)
- return 1;
+ if (! bfd_link_relocatable (&link_info))
+ {
+ /* The only way we should get matching LMAs is when the first of
+ the two sections has zero size, or asec and bsec are the
+ same section. */
+ if (asec->size < bsec->size)
+ return -1;
+ else 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
+ anyway, and fall back to idx to make the result reproducible across
qsort implementations. */
apos = asec->output_section->vma + asec->output_offset;
bpos = bsec->output_section->vma + bsec->output_offset;
return -1;
else if (apos > bpos)
return 1;
-
- return asec->id - bsec->id;
+ else
+ return ai->idx - bi->idx;
}
/* Rearrange sections with SHF_LINK_ORDER into the same order as their
linked sections. */
-static bfd_boolean
+static bool
fixup_link_order (lang_output_section_statement_type *os)
{
struct os_sections *os_info = os->data;
if (os_info->isec[i].idx != i)
break;
if (i == os_info->count)
- return FALSE;
+ return false;
/* Now reorder the linker input section statements to reflect the
proper sorting. The is done by rewriting the existing statements
}
free (save_s);
free (orig_is);
- return TRUE;
+ return true;
}
void
-ldelf_map_segments (bfd_boolean need_layout)
+ldelf_map_segments (bool need_layout)
{
int tries = 10;
- static bfd_boolean done_link_order_scan = FALSE;
+ static bool done_link_order_scan = false;
do
{
lang_relax_sections (need_layout);
- need_layout = FALSE;
+ need_layout = false;
- if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour)
+ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
{
lang_output_section_statement_type *os;
if (!done_link_order_scan)
{
link_order_scan (statement_list.head, NULL);
- done_link_order_scan = TRUE;
+ done_link_order_scan = true;
}
for (os = (void *) lang_os_list.head; os != NULL; os = os->next)
{
&& bfd_link_relocatable (&link_info))
{
einfo (_("%F%P: "
- "%pA has both ordered and unordered sections"),
+ "%pA has both ordered and unordered sections\n"),
os->bfd_section);
return;
}
if (os_info->count > 1
&& fixup_link_order (os))
- need_layout = TRUE;
+ need_layout = true;
}
}
}
- if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
+ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
&& !bfd_link_relocatable (&link_info))
{
bfd_size_type phdr_size;
if (lang_phdr_list == NULL)
elf_seg_map (link_info.output_bfd) = NULL;
if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
- &link_info))
+ &link_info,
+ &need_layout))
einfo (_("%F%P: map sections to segments failed: %E\n"));
if (phdr_size != elf_program_header_size (link_info.output_bfd))
if (tries > 6)
/* The first few times we allow any change to
phdr_size . */
- need_layout = TRUE;
+ need_layout = true;
else if (phdr_size
< elf_program_header_size (link_info.output_bfd))
/* After that we only allow the size to grow. */
- need_layout = TRUE;
+ need_layout = true;
else
elf_program_header_size (link_info.output_bfd) = phdr_size;
}
while (need_layout && --tries);
if (tries == 0)
- einfo (_("%F%P: looping in map_segments"));
+ einfo (_("%F%P: looping in map_segments\n"));
- if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
+ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
&& lang_phdr_list == NULL)
{
/* If we don't have user supplied phdrs, strip zero-sized dynamic
if (bed->elf_backend_strip_zero_sized_dynamic_sections
&& !bed->elf_backend_strip_zero_sized_dynamic_sections
(&link_info))
- einfo (_("%F%P: failed to strip zero-sized dynamic sections"));
+ einfo (_("%F%P: failed to strip zero-sized dynamic sections\n"));
}
}
if (arg->next_i == 0)
arg->next_i = 1;
- if (arg->next_i >= _bfd_elf_strtab_len (arg->strtab))
+ /* Hunt through strings until we fall off the end or find one with
+ a nonzero refcount. */
+ do
{
- arg->next_i = 0;
- return NULL;
+ if (arg->next_i >= _bfd_elf_strtab_len (arg->strtab))
+ {
+ arg->next_i = 0;
+ return NULL;
+ }
+
+ ret = _bfd_elf_strtab_str (arg->strtab, arg->next_i++, &off);
}
+ while (ret == NULL);
- ret = _bfd_elf_strtab_str (arg->strtab, arg->next_i++, &off);
*offset = off;
/* If we've overflowed, we cannot share any further strings: the CTF