aboutsummaryrefslogtreecommitdiff
path: root/packages/gcc/8.5.0
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gcc/8.5.0')
-rw-r--r--packages/gcc/8.5.0/0026-aarch64-Explicitly-handle-frames-with-no-saved-regis.patch43
-rw-r--r--packages/gcc/8.5.0/0027-aarch64-Add-bytes_below_hard_fp-to-frame-info.patch165
-rw-r--r--packages/gcc/8.5.0/0028-aarch64-Rename-locals_offset-to-bytes_above_locals.patch94
-rw-r--r--packages/gcc/8.5.0/0029-aarch64-Rename-hard_fp_offset-to-bytes_above_hard_fp.patch130
-rw-r--r--packages/gcc/8.5.0/0030-aarch64-Tweak-frame_size-comment.patch35
-rw-r--r--packages/gcc/8.5.0/0031-Backport-check-function-bodies-support.patch211
-rw-r--r--packages/gcc/8.5.0/0032-aarch64-Make-stack-smash-canary-protect-saved-regist.patch259
7 files changed, 937 insertions, 0 deletions
diff --git a/packages/gcc/8.5.0/0026-aarch64-Explicitly-handle-frames-with-no-saved-regis.patch b/packages/gcc/8.5.0/0026-aarch64-Explicitly-handle-frames-with-no-saved-regis.patch
new file mode 100644
index 00000000..7e32ce8e
--- /dev/null
+++ b/packages/gcc/8.5.0/0026-aarch64-Explicitly-handle-frames-with-no-saved-regis.patch
@@ -0,0 +1,43 @@
+From f9e1c86b3397faa8dee4bbaeaf8b56492e3a63df Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Fri, 16 Jun 2023 17:00:51 +0100
+Subject: [PATCH 26/32] aarch64: Explicitly handle frames with no saved
+ registers
+
+If a frame has no saved registers, it can be allocated in one go.
+There is no need to treat the areas below and above the saved
+registers as separate.
+
+This is a no-op as thing stand, since a leaf function will have
+no outgoing arguments, and so all the frame will be above where
+the saved registers normally go.
+
+gcc/
+ * config/aarch64/aarch64.c (aarch64_layout_frame): Explicitly
+ allocate the frame in one go if there are no saved registers.
+---
+ gcc/config/aarch64/aarch64.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index 4ad73220337f..ed9e2a28f914 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -4215,9 +4215,11 @@ aarch64_layout_frame (void)
+ max_push_offset = 256;
+
+ HOST_WIDE_INT const_size, const_fp_offset;
+- if (cfun->machine->frame.frame_size.is_constant (&const_size)
+- && const_size < max_push_offset
+- && known_eq (crtl->outgoing_args_size, 0))
++ if (cfun->machine->frame.saved_regs_size == 0)
++ cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size;
++ else if (cfun->machine->frame.frame_size.is_constant (&const_size)
++ && const_size < max_push_offset
++ && known_eq (crtl->outgoing_args_size, 0))
+ {
+ /* Simple, small frame with no outgoing arguments:
+ stp reg1, reg2, [sp, -frame_size]!
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0027-aarch64-Add-bytes_below_hard_fp-to-frame-info.patch b/packages/gcc/8.5.0/0027-aarch64-Add-bytes_below_hard_fp-to-frame-info.patch
new file mode 100644
index 00000000..f9ee88d6
--- /dev/null
+++ b/packages/gcc/8.5.0/0027-aarch64-Add-bytes_below_hard_fp-to-frame-info.patch
@@ -0,0 +1,165 @@
+From b4780c8d6cbd3fc8f2997dd7dcd360b3039c6690 Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Fri, 16 Jun 2023 16:55:12 +0100
+Subject: [PATCH 27/32] aarch64: Add bytes_below_hard_fp to frame info
+
+The frame layout code currently hard-codes the assumption that
+the number of bytes below the saved registers is equal to the
+size of the outgoing arguments. This patch abstracts that
+value into a new field of aarch64_frame.
+
+gcc/
+ * config/aarch64/aarch64.h (aarch64_frame::bytes_below_hard_fp): New
+ field.
+ * config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it,
+ and use it instead of crtl->outgoing_args_size.
+ (aarch64_get_separate_components): Use bytes_below_hard_fp instead
+ of outgoing_args_size.
+ (aarch64_process_components): Likewise.
+---
+ gcc/config/aarch64/aarch64.c | 40 ++++++++++++++++++++----------------
+ gcc/config/aarch64/aarch64.h | 6 +++++-
+ 2 files changed, 27 insertions(+), 19 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index ed9e2a28f914..996c898888cd 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -4136,6 +4136,8 @@ aarch64_layout_frame (void)
+ last_fp_reg = regno;
+ }
+
++ cfun->machine->frame.bytes_below_hard_fp = crtl->outgoing_args_size;
++
+ if (cfun->machine->frame.emit_frame_chain)
+ {
+ /* FP and LR are placed in the linkage record. */
+@@ -4195,11 +4197,11 @@ aarch64_layout_frame (void)
+ STACK_BOUNDARY / BITS_PER_UNIT);
+
+ /* Both these values are already aligned. */
+- gcc_assert (multiple_p (crtl->outgoing_args_size,
++ gcc_assert (multiple_p (cfun->machine->frame.bytes_below_hard_fp,
+ STACK_BOUNDARY / BITS_PER_UNIT));
+ cfun->machine->frame.frame_size
+ = (cfun->machine->frame.hard_fp_offset
+- + crtl->outgoing_args_size);
++ + cfun->machine->frame.bytes_below_hard_fp);
+
+ cfun->machine->frame.locals_offset = cfun->machine->frame.saved_varargs_size;
+
+@@ -4219,23 +4221,23 @@ aarch64_layout_frame (void)
+ cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size;
+ else if (cfun->machine->frame.frame_size.is_constant (&const_size)
+ && const_size < max_push_offset
+- && known_eq (crtl->outgoing_args_size, 0))
++ && known_eq (cfun->machine->frame.bytes_below_hard_fp, 0))
+ {
+- /* Simple, small frame with no outgoing arguments:
++ /* Simple, small frame with no data below the saved registers.
+ stp reg1, reg2, [sp, -frame_size]!
+ stp reg3, reg4, [sp, 16] */
+ cfun->machine->frame.callee_adjust = const_size;
+ }
+- else if (known_lt (crtl->outgoing_args_size
++ else if (known_lt (cfun->machine->frame.bytes_below_hard_fp
+ + cfun->machine->frame.saved_regs_size, 512)
+ && !(cfun->calls_alloca
+ && known_lt (cfun->machine->frame.hard_fp_offset,
+ max_push_offset)))
+ {
+- /* Frame with small outgoing arguments:
++ /* Frame with small area below the saved registers:
+ sub sp, sp, frame_size
+- stp reg1, reg2, [sp, outgoing_args_size]
+- stp reg3, reg4, [sp, outgoing_args_size + 16] */
++ stp reg1, reg2, [sp, bytes_below_hard_fp]
++ stp reg3, reg4, [sp, bytes_below_hard_fp + 16] */
+ cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size;
+ cfun->machine->frame.callee_offset
+ = cfun->machine->frame.frame_size - cfun->machine->frame.hard_fp_offset;
+@@ -4243,22 +4245,23 @@ aarch64_layout_frame (void)
+ else if (cfun->machine->frame.hard_fp_offset.is_constant (&const_fp_offset)
+ && const_fp_offset < max_push_offset)
+ {
+- /* Frame with large outgoing arguments but a small local area:
++ /* Frame with large area below the saved registers, but with a
++ small area above:
+ stp reg1, reg2, [sp, -hard_fp_offset]!
+ stp reg3, reg4, [sp, 16]
+- sub sp, sp, outgoing_args_size */
++ sub sp, sp, bytes_below_hard_fp */
+ cfun->machine->frame.callee_adjust = const_fp_offset;
+ cfun->machine->frame.final_adjust
+ = cfun->machine->frame.frame_size - cfun->machine->frame.callee_adjust;
+ }
+ else
+ {
+- /* Frame with large local area and outgoing arguments using frame pointer:
++ /* General case:
+ sub sp, sp, hard_fp_offset
+ stp x29, x30, [sp, 0]
+ add x29, sp, 0
+ stp reg3, reg4, [sp, 16]
+- sub sp, sp, outgoing_args_size */
++ sub sp, sp, bytes_below_hard_fp */
+ cfun->machine->frame.initial_adjust = cfun->machine->frame.hard_fp_offset;
+ cfun->machine->frame.final_adjust
+ = cfun->machine->frame.frame_size - cfun->machine->frame.initial_adjust;
+@@ -4666,9 +4669,11 @@ aarch64_get_separate_components (void)
+ if (aarch64_register_saved_on_entry (regno))
+ {
+ poly_int64 offset = cfun->machine->frame.reg_offset[regno];
++
++ /* Get the offset relative to the register we'll use. */
+ if (!frame_pointer_needed)
+- offset += cfun->machine->frame.frame_size
+- - cfun->machine->frame.hard_fp_offset;
++ offset += cfun->machine->frame.bytes_below_hard_fp;
++
+ /* Check that we can access the stack slot of the register with one
+ direct load with no adjustments needed. */
+ if (offset_12bit_unsigned_scaled_p (DImode, offset))
+@@ -4786,8 +4791,8 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+ rtx reg = gen_rtx_REG (mode, regno);
+ poly_int64 offset = cfun->machine->frame.reg_offset[regno];
+ if (!frame_pointer_needed)
+- offset += cfun->machine->frame.frame_size
+- - cfun->machine->frame.hard_fp_offset;
++ offset += cfun->machine->frame.bytes_below_hard_fp;
++
+ rtx addr = plus_constant (Pmode, ptr_reg, offset);
+ rtx mem = gen_frame_mem (mode, addr);
+
+@@ -4828,8 +4833,7 @@ aarch64_process_components (sbitmap components, bool prologue_p)
+ /* REGNO2 can be saved/restored in a pair with REGNO. */
+ rtx reg2 = gen_rtx_REG (mode, regno2);
+ if (!frame_pointer_needed)
+- offset2 += cfun->machine->frame.frame_size
+- - cfun->machine->frame.hard_fp_offset;
++ offset2 += cfun->machine->frame.bytes_below_hard_fp;
+ rtx addr2 = plus_constant (Pmode, ptr_reg, offset2);
+ rtx mem2 = gen_frame_mem (mode, addr2);
+ rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2)
+diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
+index f4d27fa64580..cac7a57ed475 100644
+--- a/gcc/config/aarch64/aarch64.h
++++ b/gcc/config/aarch64/aarch64.h
+@@ -647,9 +647,13 @@ struct GTY (()) aarch64_frame
+ HOST_WIDE_INT saved_varargs_size;
+
+ /* The size of the saved callee-save int/FP registers. */
+-
+ HOST_WIDE_INT saved_regs_size;
+
++ /* The number of bytes between the bottom of the static frame (the bottom
++ of the outgoing arguments) and the hard frame pointer. This value is
++ always a multiple of STACK_BOUNDARY. */
++ poly_int64 bytes_below_hard_fp;
++
+ /* Offset from the base of the frame (incomming SP) to the
+ top of the locals area. This value is always a multiple of
+ STACK_BOUNDARY. */
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0028-aarch64-Rename-locals_offset-to-bytes_above_locals.patch b/packages/gcc/8.5.0/0028-aarch64-Rename-locals_offset-to-bytes_above_locals.patch
new file mode 100644
index 00000000..c96071e2
--- /dev/null
+++ b/packages/gcc/8.5.0/0028-aarch64-Rename-locals_offset-to-bytes_above_locals.patch
@@ -0,0 +1,94 @@
+From 746f8815cf7efc16c6973420e74b2560b82a644c Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Tue, 27 Jun 2023 11:25:40 +0100
+Subject: [PATCH 28/32] aarch64: Rename locals_offset to bytes_above_locals
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+locals_offset was described as:
+
+ /* Offset from the base of the frame (incomming SP) to the
+ top of the locals area. This value is always a multiple of
+ STACK_BOUNDARY. */
+
+This is implicitly an “upside down” view of the frame: the incoming
+SP is at offset 0, and anything N bytes below the incoming SP is at
+offset N (rather than -N).
+
+However, reg_offset instead uses a “right way up” view; that is,
+it views offsets in address terms. Something above X is at a
+positive offset from X and something below X is at a negative
+offset from X.
+
+Also, even on FRAME_GROWS_DOWNWARD targets like AArch64,
+target-independent code views offsets in address terms too:
+locals are allocated at negative offsets to virtual_stack_vars.
+
+It seems confusing to have *_offset fields of the same structure
+using different polarities like this. This patch tries to avoid
+that by renaming locals_offset to bytes_above_locals.
+
+gcc/
+ * config/aarch64/aarch64.h (aarch64_frame::locals_offset): Rename to...
+ (aarch64_frame::bytes_above_locals): ...this.
+ * config/aarch64/aarch64.c (aarch64_layout_frame)
+ (aarch64_initial_elimination_offset): Update accordingly.
+---
+ gcc/config/aarch64/aarch64.c | 9 +++++----
+ gcc/config/aarch64/aarch64.h | 6 +++---
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index 996c898888cd..32a9857cb111 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -4203,7 +4203,8 @@ aarch64_layout_frame (void)
+ = (cfun->machine->frame.hard_fp_offset
+ + cfun->machine->frame.bytes_below_hard_fp);
+
+- cfun->machine->frame.locals_offset = cfun->machine->frame.saved_varargs_size;
++ cfun->machine->frame.bytes_above_locals
++ = cfun->machine->frame.saved_varargs_size;
+
+ cfun->machine->frame.initial_adjust = 0;
+ cfun->machine->frame.final_adjust = 0;
+@@ -7628,14 +7629,14 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
+
+ if (from == FRAME_POINTER_REGNUM)
+ return cfun->machine->frame.hard_fp_offset
+- - cfun->machine->frame.locals_offset;
++ - cfun->machine->frame.bytes_above_locals;
+ }
+
+ if (to == STACK_POINTER_REGNUM)
+ {
+ if (from == FRAME_POINTER_REGNUM)
+- return cfun->machine->frame.frame_size
+- - cfun->machine->frame.locals_offset;
++ return cfun->machine->frame.frame_size
++ - cfun->machine->frame.bytes_above_locals;
+ }
+
+ return cfun->machine->frame.frame_size;
+diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
+index cac7a57ed475..eb69e38bd537 100644
+--- a/gcc/config/aarch64/aarch64.h
++++ b/gcc/config/aarch64/aarch64.h
+@@ -654,10 +654,10 @@ struct GTY (()) aarch64_frame
+ always a multiple of STACK_BOUNDARY. */
+ poly_int64 bytes_below_hard_fp;
+
+- /* Offset from the base of the frame (incomming SP) to the
+- top of the locals area. This value is always a multiple of
++ /* The number of bytes between the top of the locals area and the top
++ of the frame (the incomming SP). This value is always a multiple of
+ STACK_BOUNDARY. */
+- poly_int64 locals_offset;
++ poly_int64 bytes_above_locals;
+
+ /* Offset from the base of the frame (incomming SP) to the
+ hard_frame_pointer. This value is always a multiple of
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0029-aarch64-Rename-hard_fp_offset-to-bytes_above_hard_fp.patch b/packages/gcc/8.5.0/0029-aarch64-Rename-hard_fp_offset-to-bytes_above_hard_fp.patch
new file mode 100644
index 00000000..385b7594
--- /dev/null
+++ b/packages/gcc/8.5.0/0029-aarch64-Rename-hard_fp_offset-to-bytes_above_hard_fp.patch
@@ -0,0 +1,130 @@
+From 8711ad4ae2c4c9fa693bab65a6a2fe0b191f7678 Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Tue, 27 Jun 2023 11:28:11 +0100
+Subject: [PATCH 29/32] aarch64: Rename hard_fp_offset to bytes_above_hard_fp
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Similarly to the previous locals_offset patch, hard_fp_offset
+was described as:
+
+ /* Offset from the base of the frame (incomming SP) to the
+ hard_frame_pointer. This value is always a multiple of
+ STACK_BOUNDARY. */
+ poly_int64 hard_fp_offset;
+
+which again took an “upside-down” view: higher offsets meant lower
+addresses. This patch renames the field to bytes_above_hard_fp instead.
+
+gcc/
+ * config/aarch64/aarch64.h (aarch64_frame::hard_fp_offset): Rename
+ to...
+ (aarch64_frame::bytes_above_hard_fp): ...this.
+ * config/aarch64/aarch64.c (aarch64_layout_frame)
+ (aarch64_expand_prologue): Update accordingly.
+ (aarch64_initial_elimination_offset): Likewise.
+---
+ gcc/config/aarch64/aarch64.c | 21 +++++++++++----------
+ gcc/config/aarch64/aarch64.h | 6 +++---
+ 2 files changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index 32a9857cb111..861e928ebdc2 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -4191,7 +4191,7 @@ aarch64_layout_frame (void)
+ HOST_WIDE_INT varargs_and_saved_regs_size
+ = offset + cfun->machine->frame.saved_varargs_size;
+
+- cfun->machine->frame.hard_fp_offset
++ cfun->machine->frame.bytes_above_hard_fp
+ = aligned_upper_bound (varargs_and_saved_regs_size
+ + get_frame_size (),
+ STACK_BOUNDARY / BITS_PER_UNIT);
+@@ -4200,7 +4200,7 @@ aarch64_layout_frame (void)
+ gcc_assert (multiple_p (cfun->machine->frame.bytes_below_hard_fp,
+ STACK_BOUNDARY / BITS_PER_UNIT));
+ cfun->machine->frame.frame_size
+- = (cfun->machine->frame.hard_fp_offset
++ = (cfun->machine->frame.bytes_above_hard_fp
+ + cfun->machine->frame.bytes_below_hard_fp);
+
+ cfun->machine->frame.bytes_above_locals
+@@ -4232,7 +4232,7 @@ aarch64_layout_frame (void)
+ else if (known_lt (cfun->machine->frame.bytes_below_hard_fp
+ + cfun->machine->frame.saved_regs_size, 512)
+ && !(cfun->calls_alloca
+- && known_lt (cfun->machine->frame.hard_fp_offset,
++ && known_lt (cfun->machine->frame.bytes_above_hard_fp,
+ max_push_offset)))
+ {
+ /* Frame with small area below the saved registers:
+@@ -4241,14 +4241,14 @@ aarch64_layout_frame (void)
+ stp reg3, reg4, [sp, bytes_below_hard_fp + 16] */
+ cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size;
+ cfun->machine->frame.callee_offset
+- = cfun->machine->frame.frame_size - cfun->machine->frame.hard_fp_offset;
++ = cfun->machine->frame.frame_size - cfun->machine->frame.bytes_above_hard_fp;
+ }
+- else if (cfun->machine->frame.hard_fp_offset.is_constant (&const_fp_offset)
++ else if (cfun->machine->frame.bytes_above_hard_fp.is_constant (&const_fp_offset)
+ && const_fp_offset < max_push_offset)
+ {
+ /* Frame with large area below the saved registers, but with a
+ small area above:
+- stp reg1, reg2, [sp, -hard_fp_offset]!
++ stp reg1, reg2, [sp, -bytes_above_hard_fp]!
+ stp reg3, reg4, [sp, 16]
+ sub sp, sp, bytes_below_hard_fp */
+ cfun->machine->frame.callee_adjust = const_fp_offset;
+@@ -4258,12 +4258,13 @@ aarch64_layout_frame (void)
+ else
+ {
+ /* General case:
+- sub sp, sp, hard_fp_offset
++ sub sp, sp, bytes_above_hard_fp
+ stp x29, x30, [sp, 0]
+ add x29, sp, 0
+ stp reg3, reg4, [sp, 16]
+ sub sp, sp, bytes_below_hard_fp */
+- cfun->machine->frame.initial_adjust = cfun->machine->frame.hard_fp_offset;
++ cfun->machine->frame.initial_adjust
++ = cfun->machine->frame.bytes_above_hard_fp;
+ cfun->machine->frame.final_adjust
+ = cfun->machine->frame.frame_size - cfun->machine->frame.initial_adjust;
+ }
+@@ -7625,10 +7626,10 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
+ if (to == HARD_FRAME_POINTER_REGNUM)
+ {
+ if (from == ARG_POINTER_REGNUM)
+- return cfun->machine->frame.hard_fp_offset;
++ return cfun->machine->frame.bytes_above_hard_fp;
+
+ if (from == FRAME_POINTER_REGNUM)
+- return cfun->machine->frame.hard_fp_offset
++ return cfun->machine->frame.bytes_above_hard_fp
+ - cfun->machine->frame.bytes_above_locals;
+ }
+
+diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
+index eb69e38bd537..55ef6ae08a54 100644
+--- a/gcc/config/aarch64/aarch64.h
++++ b/gcc/config/aarch64/aarch64.h
+@@ -659,10 +659,10 @@ struct GTY (()) aarch64_frame
+ STACK_BOUNDARY. */
+ poly_int64 bytes_above_locals;
+
+- /* Offset from the base of the frame (incomming SP) to the
+- hard_frame_pointer. This value is always a multiple of
++ /* The number of bytes between the hard_frame_pointer and the top of
++ the frame (the incomming SP). This value is always a multiple of
+ STACK_BOUNDARY. */
+- poly_int64 hard_fp_offset;
++ poly_int64 bytes_above_hard_fp;
+
+ /* The size of the frame. This value is the offset from base of the
+ frame (incomming SP) to the stack_pointer. This value is always
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0030-aarch64-Tweak-frame_size-comment.patch b/packages/gcc/8.5.0/0030-aarch64-Tweak-frame_size-comment.patch
new file mode 100644
index 00000000..129a7179
--- /dev/null
+++ b/packages/gcc/8.5.0/0030-aarch64-Tweak-frame_size-comment.patch
@@ -0,0 +1,35 @@
+From d1cfa6a4f7c148000b9cd591479accf001fc739b Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Thu, 22 Jun 2023 22:26:30 +0100
+Subject: [PATCH 30/32] aarch64: Tweak frame_size comment
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch fixes another case in which a value was described with
+an “upside-down” view.
+
+gcc/
+ * config/aarch64/aarch64.h (aarch64_frame::frame_size): Tweak comment.
+---
+ gcc/config/aarch64/aarch64.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
+index 55ef6ae08a54..fbcfb9891b73 100644
+--- a/gcc/config/aarch64/aarch64.h
++++ b/gcc/config/aarch64/aarch64.h
+@@ -664,8 +664,8 @@ struct GTY (()) aarch64_frame
+ STACK_BOUNDARY. */
+ poly_int64 bytes_above_hard_fp;
+
+- /* The size of the frame. This value is the offset from base of the
+- frame (incomming SP) to the stack_pointer. This value is always
++ /* The size of the frame, i.e. the number of bytes between the bottom
++ of the outgoing arguments and the incoming SP. This value is always
+ a multiple of STACK_BOUNDARY. */
+ poly_int64 frame_size;
+
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0031-Backport-check-function-bodies-support.patch b/packages/gcc/8.5.0/0031-Backport-check-function-bodies-support.patch
new file mode 100644
index 00000000..ba96f85e
--- /dev/null
+++ b/packages/gcc/8.5.0/0031-Backport-check-function-bodies-support.patch
@@ -0,0 +1,211 @@
+From 30455227307a5b078d8d857f337d931191c2d9f0 Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Tue, 15 Aug 2023 19:05:30 +0100
+Subject: [PATCH 31/32] Backport check-function-bodies support
+
+---
+ gcc/testsuite/lib/scanasm.exp | 191 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 191 insertions(+)
+
+diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
+index e653b1e7597e..191d38686cd3 100644
+--- a/gcc/testsuite/lib/scanasm.exp
++++ b/gcc/testsuite/lib/scanasm.exp
+@@ -542,3 +542,194 @@ proc scan-lto-assembler { args } {
+ verbose "output_file: $output_file"
+ dg-scan "scan-assembler" 1 $testcase $output_file $args
+ }
++
++# Read assembly file FILENAME and store a mapping from function names
++# to function bodies in array RESULT. FILENAME has already been uploaded
++# locally where necessary and is known to exist.
++
++proc parse_function_bodies { filename result } {
++ upvar $result up_result
++
++ # Regexp for the start of a function definition (name in \1).
++ set label {^([a-zA-Z_]\S+):$}
++
++ # Regexp for the end of a function definition.
++ set terminator {^\s*\.size}
++
++ # Regexp for lines that aren't interesting.
++ set fluff {^\s*(?:\.|//|@|$)}
++
++ set fd [open $filename r]
++ set in_function 0
++ while { [gets $fd line] >= 0 } {
++ if { [regexp $label $line dummy function_name] } {
++ set in_function 1
++ set function_body ""
++ } elseif { $in_function } {
++ if { [regexp $terminator $line] } {
++ set up_result($function_name) $function_body
++ set in_function 0
++ } elseif { ![regexp $fluff $line] } {
++ append function_body $line "\n"
++ }
++ }
++ }
++ close $fd
++}
++
++# FUNCTIONS is an array that maps function names to function bodies.
++# Return true if it contains a definition of function NAME and if
++# that definition matches BODY_REGEXP.
++
++proc check_function_body { functions name body_regexp } {
++ upvar $functions up_functions
++
++ if { ![info exists up_functions($name)] } {
++ return 0
++ }
++ set fn_res [regexp "^$body_regexp\$" $up_functions($name)]
++ if { !$fn_res } {
++ verbose -log "body: $body_regexp"
++ verbose -log "against: $up_functions($name)"
++ }
++ return $fn_res
++}
++
++# Check the implementations of functions against expected output. Used as:
++#
++# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } }
++#
++# See sourcebuild.texi for details.
++
++proc check-function-bodies { args } {
++ if { [llength $args] < 2 } {
++ error "too few arguments to check-function-bodies"
++ }
++ if { [llength $args] > 4 } {
++ error "too many arguments to check-function-bodies"
++ }
++
++ if { [llength $args] >= 3 } {
++ set required_flags [lindex $args 2]
++
++ upvar 2 dg-extra-tool-flags extra_tool_flags
++ set flags $extra_tool_flags
++
++ global torture_current_flags
++ if { [info exists torture_current_flags] } {
++ append flags " " $torture_current_flags
++ }
++ foreach required_flag $required_flags {
++ switch -- $required_flag {
++ target -
++ xfail {
++ error "misplaced $required_flag in check-function-bodies"
++ }
++ }
++ }
++ foreach required_flag $required_flags {
++ if { ![regexp " $required_flag " $flags] } {
++ return
++ }
++ }
++ }
++
++ set xfail_all 0
++ if { [llength $args] >= 4 } {
++ switch [dg-process-target [lindex $args 3]] {
++ "S" { }
++ "N" { return }
++ "F" { set xfail_all 1 }
++ "P" { }
++ }
++ }
++
++ set testcase [testname-for-summary]
++ # The name might include a list of options; extract the file name.
++ set filename [lindex $testcase 0]
++
++ global srcdir
++ set input_filename "$srcdir/$filename"
++ set output_filename "[file rootname [file tail $filename]].s"
++
++ set prefix [lindex $args 0]
++ set prefix_len [string length $prefix]
++ set terminator [lindex $args 1]
++ if { [string equal $terminator ""] } {
++ set terminator "*/"
++ }
++ set terminator_len [string length $terminator]
++
++ set have_bodies 0
++ if { [is_remote host] } {
++ remote_upload host "$filename"
++ }
++ if { [file exists $output_filename] } {
++ parse_function_bodies $output_filename functions
++ set have_bodies 1
++ } else {
++ verbose -log "$testcase: output file does not exist"
++ }
++
++ set count 0
++ set function_regexp ""
++ set label {^(\S+):$}
++
++ set lineno 1
++ set fd [open $input_filename r]
++ set in_function 0
++ while { [gets $fd line] >= 0 } {
++ if { [string equal -length $prefix_len $line $prefix] } {
++ set line [string trim [string range $line $prefix_len end]]
++ if { !$in_function } {
++ if { [regexp "^(.*?\\S)\\s+{(.*)}\$" $line dummy \
++ line selector] } {
++ set selector [dg-process-target $selector]
++ } else {
++ set selector "P"
++ }
++ if { ![regexp $label $line dummy function_name] } {
++ close $fd
++ error "check-function-bodies: line $lineno does not have a function label"
++ }
++ set in_function 1
++ set function_regexp ""
++ } elseif { [string equal $line "("] } {
++ append function_regexp "(?:"
++ } elseif { [string equal $line "|"] } {
++ append function_regexp "|"
++ } elseif { [string equal $line ")"] } {
++ append function_regexp ")"
++ } elseif { [string equal $line "..."] } {
++ append function_regexp ".*"
++ } else {
++ append function_regexp "\t" $line "\n"
++ }
++ } elseif { [string equal -length $terminator_len $line $terminator] } {
++ if { ![string equal $selector "N"] } {
++ if { $xfail_all || [string equal $selector "F"] } {
++ setup_xfail "*-*-*"
++ }
++ set testname "$testcase check-function-bodies $function_name"
++ if { !$have_bodies } {
++ unresolved $testname
++ } elseif { [check_function_body functions $function_name \
++ $function_regexp] } {
++ pass $testname
++ } else {
++ fail $testname
++ }
++ }
++ set in_function 0
++ incr count
++ }
++ incr lineno
++ }
++ close $fd
++ if { $in_function } {
++ error "check-function-bodies: missing \"$terminator\""
++ }
++ if { $count == 0 } {
++ error "check-function-bodies: no matches found"
++ }
++}
+--
+2.42.0
+
diff --git a/packages/gcc/8.5.0/0032-aarch64-Make-stack-smash-canary-protect-saved-regist.patch b/packages/gcc/8.5.0/0032-aarch64-Make-stack-smash-canary-protect-saved-regist.patch
new file mode 100644
index 00000000..b074c42d
--- /dev/null
+++ b/packages/gcc/8.5.0/0032-aarch64-Make-stack-smash-canary-protect-saved-regist.patch
@@ -0,0 +1,259 @@
+From ee9111b567ddcd2f1b16da4f38b69b1b979df9ef Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <richard.sandiford@arm.com>
+Date: Thu, 15 Jun 2023 19:16:52 +0100
+Subject: [PATCH 32/32] aarch64: Make stack smash canary protect saved
+ registers
+
+AArch64 normally puts the saved registers near the bottom of the frame,
+immediately above any dynamic allocations. But this means that a
+stack-smash attack on those dynamic allocations could overwrite the
+saved registers without needing to reach as far as the stack smash
+canary.
+
+The same thing could also happen for variable-sized arguments that are
+passed by value, since those are allocated before a call and popped on
+return.
+
+This patch avoids that by putting the locals (and thus the canary) below
+the saved registers when stack smash protection is active.
+
+The patch fixes CVE-2023-4039.
+
+gcc/
+ * config/aarch64/aarch64.c (aarch64_save_regs_above_locals_p):
+ New function.
+ (aarch64_layout_frame): Use it to decide whether locals should
+ go above or below the saved registers.
+ (aarch64_expand_prologue): Update stack layout comment.
+ Emit a stack tie after the final adjustment.
+
+gcc/testsuite/
+ * gcc.target/aarch64/stack-protector-8.c: New test.
+ * gcc.target/aarch64/stack-protector-9.c: Likewise.
+---
+ gcc/config/aarch64/aarch64.c | 46 ++++++++++++--
+ .../gcc.target/aarch64/stack-protector-8.c | 62 +++++++++++++++++++
+ .../gcc.target/aarch64/stack-protector-9.c | 33 ++++++++++
+ 3 files changed, 137 insertions(+), 4 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
+ create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
+
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index 861e928ebdc2..5c0e3fd484da 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -4078,6 +4078,20 @@ aarch64_output_probe_stack_range (rtx reg1, rtx reg2)
+ return "";
+ }
+
++/* Return true if the current function should save registers above
++ the locals area, rather than below it. */
++
++static bool
++aarch64_save_regs_above_locals_p ()
++{
++ /* When using stack smash protection, make sure that the canary slot
++ comes between the locals and the saved registers. Otherwise,
++ it would be possible for a carefully sized smash attack to change
++ the saved registers (particularly LR and FP) without reaching the
++ canary. */
++ return crtl->stack_protect_guard;
++}
++
+ /* Mark the registers that need to be saved by the callee and calculate
+ the size of the callee-saved registers area and frame record (both FP
+ and LR may be omitted). */
+@@ -4138,6 +4152,16 @@ aarch64_layout_frame (void)
+
+ cfun->machine->frame.bytes_below_hard_fp = crtl->outgoing_args_size;
+
++ bool regs_at_top_p = aarch64_save_regs_above_locals_p ();
++
++ if (regs_at_top_p)
++ {
++ cfun->machine->frame.bytes_below_hard_fp += get_frame_size ();
++ cfun->machine->frame.bytes_below_hard_fp
++ = aligned_upper_bound (cfun->machine->frame.bytes_below_hard_fp,
++ STACK_BOUNDARY / BITS_PER_UNIT);
++ }
++
+ if (cfun->machine->frame.emit_frame_chain)
+ {
+ /* FP and LR are placed in the linkage record. */
+@@ -4191,9 +4215,11 @@ aarch64_layout_frame (void)
+ HOST_WIDE_INT varargs_and_saved_regs_size
+ = offset + cfun->machine->frame.saved_varargs_size;
+
++ cfun->machine->frame.bytes_above_hard_fp = varargs_and_saved_regs_size;
++ if (!regs_at_top_p)
++ cfun->machine->frame.bytes_above_hard_fp += get_frame_size ();
+ cfun->machine->frame.bytes_above_hard_fp
+- = aligned_upper_bound (varargs_and_saved_regs_size
+- + get_frame_size (),
++ = aligned_upper_bound (cfun->machine->frame.bytes_above_hard_fp,
+ STACK_BOUNDARY / BITS_PER_UNIT);
+
+ /* Both these values are already aligned. */
+@@ -4205,6 +4231,9 @@ aarch64_layout_frame (void)
+
+ cfun->machine->frame.bytes_above_locals
+ = cfun->machine->frame.saved_varargs_size;
++ if (regs_at_top_p)
++ cfun->machine->frame.bytes_above_locals
++ += cfun->machine->frame.saved_regs_size;
+
+ cfun->machine->frame.initial_adjust = 0;
+ cfun->machine->frame.final_adjust = 0;
+@@ -4912,10 +4941,10 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg,
+ | for register varargs |
+ | |
+ +-------------------------------+
+- | local variables | <-- frame_pointer_rtx
++ | local variables (1) | <-- frame_pointer_rtx
+ | |
+ +-------------------------------+
+- | padding0 | \
++ | padding (1) | \
+ +-------------------------------+ |
+ | callee-saved registers | | frame.saved_regs_size
+ +-------------------------------+ |
+@@ -4923,6 +4952,10 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg,
+ +-------------------------------+ |
+ | FP' | / <- hard_frame_pointer_rtx (aligned)
+ +-------------------------------+
++ | local variables (2) |
++ +-------------------------------+
++ | padding (2) |
++ +-------------------------------+
+ | dynamic allocation |
+ +-------------------------------+
+ | padding |
+@@ -4932,6 +4965,9 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg,
+ +-------------------------------+
+ | | <-- stack_pointer_rtx (aligned)
+
++ The regions marked (1) and (2) are mutually exclusive. (2) is used
++ when aarch64_save_regs_above_locals_p is true.
++
+ Dynamic stack allocations via alloca() decrease stack_pointer_rtx
+ but leave frame_pointer_rtx and hard_frame_pointer_rtx
+ unchanged. */
+@@ -5042,6 +5078,8 @@ aarch64_expand_prologue (void)
+ aarch64_save_callee_saves (DFmode, callee_offset, V0_REGNUM, V31_REGNUM,
+ callee_adjust != 0 || emit_frame_chain);
+ aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed);
++ if (emit_frame_chain && maybe_ne (final_adjust, 0))
++ emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx));
+ }
+
+ /* Return TRUE if we can use a simple_return insn.
+diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
+new file mode 100644
+index 000000000000..b808735762fd
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c
+@@ -0,0 +1,62 @@
++/* { dg-options " -O -fstack-protector-strong" } */
++/* { dg-final { check-function-bodies "**" "" } } */
++
++void g(void *);
++
++/*
++** test1:
++** sub sp, sp, #304
++** stp x29, x30, \[sp, #?272\]
++** add x29, sp, #?272
++** str (x[0-9]+), \[sp, #?288\]
++** ...
++** ldr (x[0-9]+), \[\1\]
++** str \2, \[sp, #?264\]
++** mov \2, *0
++** add x0, sp, #?8
++** bl g
++** ...
++** ldr x[0-9]+, \[\1\]
++** ...
++** bne .*
++** ...
++** ldr \1, \[sp, #?288\]
++** ldp x29, x30, \[sp, #?272\]
++** add sp, sp, #?304
++** ret
++** bl __stack_chk_fail
++*/
++int test1() {
++ int y[0x40];
++ g(y);
++ return 1;
++}
++
++/*
++** test2:
++** stp x29, x30, \[sp, #?-32\]!
++** mov x29, sp
++** str (x[0-9]+), \[sp, #?16\]
++** sub sp, sp, #1040
++** ...
++** ldr (x[0-9]+), \[\1\]
++** str \2, \[sp, #?1032\]
++** mov \2, *0
++** add x0, sp, #?8
++** bl g
++** ...
++** ldr x[0-9]+, \[\1\]
++** ...
++** bne .*
++** ...
++** add sp, sp, #?1040
++** ldr \1, \[sp, #?16\]
++** ldp x29, x30, \[sp\], #?32
++** ret
++** bl __stack_chk_fail
++*/
++int test2() {
++ int y[0x100];
++ g(y);
++ return 1;
++}
+diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
+new file mode 100644
+index 000000000000..58f322aa480a
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c
+@@ -0,0 +1,33 @@
++/* { dg-options "-O2 -mcpu=neoverse-v1 -fstack-protector-all" } */
++/* { dg-final { check-function-bodies "**" "" } } */
++
++/*
++** main:
++** ...
++** stp x29, x30, \[sp, #?-[0-9]+\]!
++** ...
++** sub sp, sp, #[0-9]+
++** ...
++** str x[0-9]+, \[x29, #?-8\]
++** ...
++*/
++int f(const char *);
++void g(void *);
++int main(int argc, char* argv[])
++{
++ int a;
++ int b;
++ char c[2+f(argv[1])];
++ int d[0x100];
++ char y;
++
++ y=42; a=4; b=10;
++ c[0] = 'h'; c[1] = '\0';
++
++ c[f(argv[2])] = '\0';
++
++ __builtin_printf("%d %d\n%s\n", a, b, c);
++ g(d);
++
++ return 0;
++}
+--
+2.42.0
+