]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Rework the resize_sections function
authorMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 21 Feb 2022 13:18:27 +0000 (13:18 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 21 Feb 2022 13:19:20 +0000 (13:19 +0000)
Now instead of iterating through relocations recording changes to make
and sorting those changes according to the section VMA before going on
to make the changes in section VMA order, we instead modify the sections
as we iterate through relocations.

This change can be done now that the alignment is always done, even if
the VMA of the start and end was good for precise bounds and now that
padding is added via an expression rather than setting the point to a
specific location.  Having these two things means that changing the
layout of earlier sections does not affect the precise bounds property
of later sections.

It also makes things easier that we keep the padding of a section inside
that section, so can tell whether a section has the correct size just
from the size of the section rather recording in an out-of-bounds manner
which sections have had their padding assigned.

This patch makes no functional change, but simply changes the code to be
more readable.

bfd/elfnn-aarch64.c

index 071532f480bc88b25ed3e69c5d4e174a74531441..00f64e35034cbe439cc74b7d59f31afb2738a84e 100644 (file)
@@ -4828,53 +4828,33 @@ c64_valid_cap_range (bfd_vma *basep, bfd_vma *limitp, unsigned *alignmentp)
   return FALSE;
 }
 
-struct sec_change_queue
-{
-  asection *sec;
-  struct sec_change_queue *next;
-};
-
-/* Queue up the change, sorted in order of the output section vma.  */
-
-static void
-queue_section_padding (struct sec_change_queue **queue, asection *sec)
+/* Check if the bounds of section SEC will get rounded off in the Morello
+   capability format and if it would, adjust the section to ensure any
+   capability spanning this section would have its bounds precise.  */
+static inline void
+ensure_precisely_bounded_section (asection *sec,
+                                 struct elf_aarch64_link_hash_table *htab,
+                                 void (*c64_pad_section) (asection *, bfd_vma))
 {
-  struct sec_change_queue *q = *queue, *last_q = NULL, *n;
+  bfd_vma low = sec->vma;
+  bfd_vma high = sec->vma + sec->size;
+  unsigned alignment;
 
-  while (q != NULL)
+  bfd_boolean did_change = FALSE;
+  if (!c64_valid_cap_range (&low, &high, &alignment))
     {
-      if (q->sec->vma > sec->vma)
-       break;
-      last_q = q;
-      q = q->next;
+      bfd_vma padding = high - low - sec->size;
+      c64_pad_section (sec, padding);
+      did_change = TRUE;
     }
-
-  n = bfd_zmalloc (sizeof (struct sec_change_queue));
-
-  if (last_q == NULL)
-    *queue = n;
-  else
+  if (sec->alignment_power < alignment)
     {
-      n->next = q;
-      last_q->next = n;
+      sec->alignment_power = alignment;
+      did_change = TRUE;
     }
 
-  n->sec = sec;
-}
-
-/* Check if the bounds covering all sections between LOW_SEC and HIGH_SEC will
-   get rounded off in the Morello capability format and if it does, queue up a
-   change to fix up the section layout.  */
-static inline void
-record_section_change (asection *sec, struct sec_change_queue **queue)
-{
-  bfd_vma low = sec->vma;
-  bfd_vma high = sec->vma + sec->size;
-  unsigned alignment;
-
-  if (!c64_valid_cap_range (&low, &high, &alignment)
-      || sec->alignment_power < alignment)
-    queue_section_padding (queue, sec);
+  if (did_change)
+    (*htab->layout_sections_again) ();
 }
 
 /* Make sure that all capabilities that refer to sections have bounds that
@@ -4911,8 +4891,6 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
        || (elf_elfheader (output_bfd)->e_flags & EF_AARCH64_CHERI_PURECAP)))
     return;
 
-  struct sec_change_queue *queue = NULL;
-
   /* First, walk through all the relocations to find those referring to linker
      defined and ldscript defined symbols since we set their range to their
      output sections.  */
@@ -4975,7 +4953,7 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
              os = h->root.u.def.section->output_section;
 
              if (h->root.linker_def)
-               record_section_change (os, &queue);
+               ensure_precisely_bounded_section (os, htab, c64_pad_section);
              else if (h->root.ldscript_def)
                {
                  const char *name = h->root.root.string;
@@ -4991,40 +4969,20 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
                                                 section_start_symbol, &value);
 
                      if (os != NULL)
-                       record_section_change (os, &queue);
+                       ensure_precisely_bounded_section (os, htab,
+                                                         c64_pad_section);
                    }
                  /* XXX We're overfitting here because the offset of H within
                     the output section is not yet resolved and ldscript
                     defined symbols do not have input section information.  */
                  else
-                   record_section_change (os, &queue);
+                   ensure_precisely_bounded_section (os, htab,
+                                                     c64_pad_section);
                }
            }
        }
     }
 
-  /* Sequentially add alignment and padding as required.  */
-  while (queue)
-    {
-      bfd_vma low = queue->sec->vma;
-      bfd_vma high = queue->sec->vma + queue->sec->size;
-
-      if (!c64_valid_cap_range (&low, &high, &align))
-       {
-         bfd_vma padding = high - low - queue->sec->size;
-         c64_pad_section (queue->sec, padding);
-       }
-      if (queue->sec->alignment_power < align)
-       queue->sec->alignment_power = align;
-
-      (*htab->layout_sections_again) ();
-
-      struct sec_change_queue *queue_free = queue;
-
-      queue = queue->next;
-      free (queue_free);
-    }
-
   /* Next, walk through output sections to find the PCC span and add a padding
      at the end to ensure that PCC bounds don't bleed into neighbouring
      sections.  For now PCC needs to encompass all code sections, .got, .plt