summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Malcomson <matthew.malcomson@arm.com>2022-02-21 13:18:27 +0000
committerMatthew Malcomson <matthew.malcomson@arm.com>2022-02-21 13:19:20 +0000
commit396742bf3607f0212d7bae1ea7238c34e7562164 (patch)
tree2435e7d0547fd3d1edd1e25dd0f3bb69c542c4ca
parent4a74b265839c80c669156e19948540214fd2d117 (diff)
downloadbinutils-gdb-396742bf3607f0212d7bae1ea7238c34e7562164.tar.gz
Rework the resize_sections function
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.
-rw-r--r--bfd/elfnn-aarch64.c92
1 files changed, 25 insertions, 67 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 071532f480b..00f64e35034 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -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