Automatic date update in version.in
[binutils-gdb.git] / ld / ldelfgen.c
index 8014e2229b97e78a6931a60c48264cb3fecb9f33..58b37c65bc92bcb765570436a7893d04908bf40c 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -52,7 +52,7 @@ struct os_sections
 
 /* 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)
 {
@@ -79,22 +79,22 @@ add_link_order_input_section (lang_input_section_type *is,
   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)
     {
@@ -102,21 +102,21 @@ link_order_scan (lang_statement_union_type *u,
        {
        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;
@@ -127,7 +127,7 @@ link_order_scan (lang_statement_union_type *u,
                  || ((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;
@@ -144,10 +144,15 @@ compare_link_order (const void *a, const void *b)
 {
   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)
     {
@@ -166,16 +171,20 @@ compare_link_order (const void *a, const void *b)
   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;
@@ -183,14 +192,14 @@ compare_link_order (const void *a, const void *b)
     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;
@@ -218,7 +227,7 @@ fixup_link_order (lang_output_section_statement_type *os)
     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
@@ -242,27 +251,27 @@ fixup_link_order (lang_output_section_statement_type *os)
       }
   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)
            {
@@ -273,18 +282,18 @@ ldelf_map_segments (bfd_boolean need_layout)
                      && 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;
@@ -295,7 +304,8 @@ ldelf_map_segments (bfd_boolean need_layout)
          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))
@@ -303,11 +313,11 @@ ldelf_map_segments (bfd_boolean need_layout)
              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;
            }
@@ -316,9 +326,9 @@ ldelf_map_segments (bfd_boolean need_layout)
   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
@@ -328,7 +338,7 @@ ldelf_map_segments (bfd_boolean need_layout)
       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"));
     }
 }
 
@@ -370,13 +380,20 @@ ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
   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