diff options
Diffstat (limited to 'meta/recipes-devtools/gcc')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.3/0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch | 119 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.3/0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch | 204 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.3/0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch | 600 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.3/0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch | 659 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5.inc (renamed from meta/recipes-devtools/gcc/gcc-9.3.inc) | 19 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0002-gcc-poison-system-directories.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0002-gcc-poison-system-directories.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0002-libstdc-Fix-inconsistent-noexcept-specific-for-valar.patch | 44 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0004-64-bit-multilib-hack.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0004-64-bit-multilib-hack.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0005-optional-libstdc.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0005-optional-libstdc.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0006-COLLECT_GCC_OPTIONS.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0006-COLLECT_GCC_OPTIONS.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0008-fortran-cross-compile-hack.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0008-fortran-cross-compile-hack.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0009-cpp-honor-sysroot.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0009-cpp-honor-sysroot.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0010-MIPS64-Default-to-N64-ABI.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0010-MIPS64-Default-to-N64-ABI.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0012-gcc-Fix-argument-list-too-long-error.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0012-gcc-Fix-argument-list-too-long-error.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0013-Disable-sdt.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0013-Disable-sdt.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0014-libtool.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0014-libtool.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0018-export-CPP.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0018-export-CPP.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0019-Ensure-target-gcc-headers-can-be-included.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0019-Ensure-target-gcc-headers-can-be-included.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0023-aarch64-Add-support-for-musl-ldso.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0023-aarch64-Add-support-for-musl-ldso.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0025-handle-sysroot-support-for-nativesdk-gcc.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0025-handle-sysroot-support-for-nativesdk-gcc.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0027-Fix-various-_FOR_BUILD-and-related-variables.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0027-Fix-various-_FOR_BUILD-and-related-variables.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0030-ldbl128-config.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0030-ldbl128-config.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0033-sync-gcc-stddef.h-with-musl.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0033-sync-gcc-stddef.h-with-musl.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0034-fix-segmentation-fault-in-precompiled-header-generat.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0034-fix-segmentation-fault-in-precompiled-header-generat.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0035-Fix-for-testsuite-failure.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0035-Fix-for-testsuite-failure.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0036-Re-introduce-spe-commandline-options.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0036-Re-introduce-spe-commandline-options.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch (renamed from meta/recipes-devtools/gcc/gcc-9.3/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-9.5/CVE-2023-4039.patch | 1506 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-common.inc | 3 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-cross-canadian_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-cross-canadian_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-cross_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-cross_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-crosssdk_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-crosssdk_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-runtime_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-runtime_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-sanitizers_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-sanitizers_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-shared-source.inc | 3 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-source.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-source_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc-source_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc_9.5.bb (renamed from meta/recipes-devtools/gcc/gcc_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/libgcc-initial_9.5.bb (renamed from meta/recipes-devtools/gcc/libgcc-initial_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/libgcc_9.5.bb (renamed from meta/recipes-devtools/gcc/libgcc_9.3.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/libgfortran_9.5.bb (renamed from meta/recipes-devtools/gcc/libgfortran_9.3.bb) | 0 |
59 files changed, 1566 insertions, 1592 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch b/meta/recipes-devtools/gcc/gcc-9.3/0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch deleted file mode 100644 index dc1039dcc8..0000000000 --- a/meta/recipes-devtools/gcc/gcc-9.3/0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | Upstream-Status: Backport [https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=97b668f9a8c6ec565c278a60e7d1492a6932e409] | ||
2 | Signed-off-by: Jon Mason <jon.mason@arm.com> | ||
3 | |||
4 | From 97b668f9a8c6ec565c278a60e7d1492a6932e409 Mon Sep 17 00:00:00 2001 | ||
5 | From: Matthias Klose <doko@ubuntu.com> | ||
6 | Date: Tue, 6 Oct 2020 13:41:37 +0200 | ||
7 | Subject: [PATCH] Backport fix for PR/tree-optimization/97236 - fix bad use of | ||
8 | VMAT_CONTIGUOUS | ||
9 | |||
10 | This avoids using VMAT_CONTIGUOUS with single-element interleaving | ||
11 | when using V1mode vectors. Instead keep VMAT_ELEMENTWISE but | ||
12 | continue to avoid load-lanes and gathers. | ||
13 | |||
14 | 2020-10-01 Richard Biener <rguenther@suse.de> | ||
15 | |||
16 | PR tree-optimization/97236 | ||
17 | * tree-vect-stmts.c (get_group_load_store_type): Keep | ||
18 | VMAT_ELEMENTWISE for single-element vectors. | ||
19 | |||
20 | * gcc.dg/vect/pr97236.c: New testcase. | ||
21 | |||
22 | (cherry picked from commit 1ab88985631dd2c5a5e3b5c0dce47cf8b6ed2f82) | ||
23 | --- | ||
24 | gcc/testsuite/gcc.dg/vect/pr97236.c | 43 +++++++++++++++++++++++++++++ | ||
25 | gcc/tree-vect-stmts.c | 20 ++++++-------- | ||
26 | 2 files changed, 52 insertions(+), 11 deletions(-) | ||
27 | create mode 100644 gcc/testsuite/gcc.dg/vect/pr97236.c | ||
28 | |||
29 | diff --git a/gcc/testsuite/gcc.dg/vect/pr97236.c b/gcc/testsuite/gcc.dg/vect/pr97236.c | ||
30 | new file mode 100644 | ||
31 | index 000000000000..9d3dc20d953d | ||
32 | --- /dev/null | ||
33 | +++ b/gcc/testsuite/gcc.dg/vect/pr97236.c | ||
34 | @@ -0,0 +1,43 @@ | ||
35 | +typedef unsigned char __uint8_t; | ||
36 | +typedef __uint8_t uint8_t; | ||
37 | +typedef struct plane_t { | ||
38 | + uint8_t *p_pixels; | ||
39 | + int i_lines; | ||
40 | + int i_pitch; | ||
41 | +} plane_t; | ||
42 | + | ||
43 | +typedef struct { | ||
44 | + plane_t p[5]; | ||
45 | +} picture_t; | ||
46 | + | ||
47 | +#define N 4 | ||
48 | + | ||
49 | +void __attribute__((noipa)) | ||
50 | +picture_Clone(picture_t *picture, picture_t *res) | ||
51 | +{ | ||
52 | + for (int i = 0; i < N; i++) { | ||
53 | + res->p[i].p_pixels = picture->p[i].p_pixels; | ||
54 | + res->p[i].i_lines = picture->p[i].i_lines; | ||
55 | + res->p[i].i_pitch = picture->p[i].i_pitch; | ||
56 | + } | ||
57 | +} | ||
58 | + | ||
59 | +int | ||
60 | +main() | ||
61 | +{ | ||
62 | + picture_t aaa, bbb; | ||
63 | + uint8_t pixels[10] = {1, 1, 1, 1, 1, 1, 1, 1}; | ||
64 | + | ||
65 | + for (unsigned i = 0; i < N; i++) | ||
66 | + aaa.p[i].p_pixels = pixels; | ||
67 | + | ||
68 | + picture_Clone (&aaa, &bbb); | ||
69 | + | ||
70 | + uint8_t c = 0; | ||
71 | + for (unsigned i = 0; i < N; i++) | ||
72 | + c += bbb.p[i].p_pixels[0]; | ||
73 | + | ||
74 | + if (c != N) | ||
75 | + __builtin_abort (); | ||
76 | + return 0; | ||
77 | +} | ||
78 | diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c | ||
79 | index 507f81b0a0e8..ffbba3441de2 100644 | ||
80 | --- a/gcc/tree-vect-stmts.c | ||
81 | +++ b/gcc/tree-vect-stmts.c | ||
82 | @@ -2355,25 +2355,23 @@ get_group_load_store_type (stmt_vec_info stmt_info, tree vectype, bool slp, | ||
83 | /* First cope with the degenerate case of a single-element | ||
84 | vector. */ | ||
85 | if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 1U)) | ||
86 | - *memory_access_type = VMAT_CONTIGUOUS; | ||
87 | + ; | ||
88 | |||
89 | /* Otherwise try using LOAD/STORE_LANES. */ | ||
90 | - if (*memory_access_type == VMAT_ELEMENTWISE | ||
91 | - && (vls_type == VLS_LOAD | ||
92 | - ? vect_load_lanes_supported (vectype, group_size, masked_p) | ||
93 | - : vect_store_lanes_supported (vectype, group_size, | ||
94 | - masked_p))) | ||
95 | + else if (vls_type == VLS_LOAD | ||
96 | + ? vect_load_lanes_supported (vectype, group_size, masked_p) | ||
97 | + : vect_store_lanes_supported (vectype, group_size, | ||
98 | + masked_p)) | ||
99 | { | ||
100 | *memory_access_type = VMAT_LOAD_STORE_LANES; | ||
101 | overrun_p = would_overrun_p; | ||
102 | } | ||
103 | |||
104 | /* If that fails, try using permuting loads. */ | ||
105 | - if (*memory_access_type == VMAT_ELEMENTWISE | ||
106 | - && (vls_type == VLS_LOAD | ||
107 | - ? vect_grouped_load_supported (vectype, single_element_p, | ||
108 | - group_size) | ||
109 | - : vect_grouped_store_supported (vectype, group_size))) | ||
110 | + else if (vls_type == VLS_LOAD | ||
111 | + ? vect_grouped_load_supported (vectype, single_element_p, | ||
112 | + group_size) | ||
113 | + : vect_grouped_store_supported (vectype, group_size)) | ||
114 | { | ||
115 | *memory_access_type = VMAT_CONTIGUOUS_PERMUTE; | ||
116 | overrun_p = would_overrun_p; | ||
117 | -- | ||
118 | 2.20.1 | ||
119 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch b/meta/recipes-devtools/gcc/gcc-9.3/0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch deleted file mode 100644 index a7e29f4bd7..0000000000 --- a/meta/recipes-devtools/gcc/gcc-9.3/0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | CVE: CVE-2020-13844 | ||
2 | Upstream-Status: Backport | ||
3 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
4 | |||
5 | From 20da13e395bde597d8337167c712039c8f923c3b Mon Sep 17 00:00:00 2001 | ||
6 | From: Matthew Malcomson <matthew.malcomson@arm.com> | ||
7 | Date: Thu, 9 Jul 2020 09:11:58 +0100 | ||
8 | Subject: [PATCH 1/3] aarch64: New Straight Line Speculation (SLS) mitigation | ||
9 | flags | ||
10 | |||
11 | Here we introduce the flags that will be used for straight line speculation. | ||
12 | |||
13 | The new flag introduced is `-mharden-sls=`. | ||
14 | This flag can take arguments of `none`, `all`, or a comma seperated list | ||
15 | of one or more of `retbr` or `blr`. | ||
16 | `none` indicates no special mitigation of the straight line speculation | ||
17 | vulnerability. | ||
18 | `all` requests all mitigations currently implemented. | ||
19 | `retbr` requests that the RET and BR instructions have a speculation | ||
20 | barrier inserted after them. | ||
21 | `blr` requests that BLR instructions are replaced by a BL to a function | ||
22 | stub using a BR with a speculation barrier after it. | ||
23 | |||
24 | Setting this on a per-function basis using attributes or the like is not | ||
25 | enabled, but may be in the future. | ||
26 | |||
27 | (cherry picked from commit a9ba2a9b77bec7eacaf066801f22d1c366a2bc86) | ||
28 | |||
29 | gcc/ChangeLog: | ||
30 | |||
31 | 2020-06-02 Matthew Malcomson <matthew.malcomson@arm.com> | ||
32 | |||
33 | * config/aarch64/aarch64-protos.h (aarch64_harden_sls_retbr_p): | ||
34 | New. | ||
35 | (aarch64_harden_sls_blr_p): New. | ||
36 | * config/aarch64/aarch64.c (enum aarch64_sls_hardening_type): | ||
37 | New. | ||
38 | (aarch64_harden_sls_retbr_p): New. | ||
39 | (aarch64_harden_sls_blr_p): New. | ||
40 | (aarch64_validate_sls_mitigation): New. | ||
41 | (aarch64_override_options): Parse options for SLS mitigation. | ||
42 | * config/aarch64/aarch64.opt (-mharden-sls): New option. | ||
43 | * doc/invoke.texi: Document new option. | ||
44 | --- | ||
45 | gcc/config/aarch64/aarch64-protos.h | 3 ++ | ||
46 | gcc/config/aarch64/aarch64.c | 76 +++++++++++++++++++++++++++++ | ||
47 | gcc/config/aarch64/aarch64.opt | 4 ++ | ||
48 | gcc/doc/invoke.texi | 12 +++++ | ||
49 | 4 files changed, 95 insertions(+) | ||
50 | |||
51 | diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h | ||
52 | index c083cad53..31493f412 100644 | ||
53 | --- a/gcc/config/aarch64/aarch64-protos.h | ||
54 | +++ b/gcc/config/aarch64/aarch64-protos.h | ||
55 | @@ -644,4 +644,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode); | ||
56 | |||
57 | bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT); | ||
58 | |||
59 | +extern bool aarch64_harden_sls_retbr_p (void); | ||
60 | +extern bool aarch64_harden_sls_blr_p (void); | ||
61 | + | ||
62 | #endif /* GCC_AARCH64_PROTOS_H */ | ||
63 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
64 | index b452a53af..269ff6c92 100644 | ||
65 | --- a/gcc/config/aarch64/aarch64.c | ||
66 | +++ b/gcc/config/aarch64/aarch64.c | ||
67 | @@ -11734,6 +11734,79 @@ aarch64_validate_mcpu (const char *str, const struct processor **res, | ||
68 | return false; | ||
69 | } | ||
70 | |||
71 | +/* Straight line speculation indicators. */ | ||
72 | +enum aarch64_sls_hardening_type | ||
73 | +{ | ||
74 | + SLS_NONE = 0, | ||
75 | + SLS_RETBR = 1, | ||
76 | + SLS_BLR = 2, | ||
77 | + SLS_ALL = 3, | ||
78 | +}; | ||
79 | +static enum aarch64_sls_hardening_type aarch64_sls_hardening; | ||
80 | + | ||
81 | +/* Return whether we should mitigatate Straight Line Speculation for the RET | ||
82 | + and BR instructions. */ | ||
83 | +bool | ||
84 | +aarch64_harden_sls_retbr_p (void) | ||
85 | +{ | ||
86 | + return aarch64_sls_hardening & SLS_RETBR; | ||
87 | +} | ||
88 | + | ||
89 | +/* Return whether we should mitigatate Straight Line Speculation for the BLR | ||
90 | + instruction. */ | ||
91 | +bool | ||
92 | +aarch64_harden_sls_blr_p (void) | ||
93 | +{ | ||
94 | + return aarch64_sls_hardening & SLS_BLR; | ||
95 | +} | ||
96 | + | ||
97 | +/* As of yet we only allow setting these options globally, in the future we may | ||
98 | + allow setting them per function. */ | ||
99 | +static void | ||
100 | +aarch64_validate_sls_mitigation (const char *const_str) | ||
101 | +{ | ||
102 | + char *token_save = NULL; | ||
103 | + char *str = NULL; | ||
104 | + | ||
105 | + if (strcmp (const_str, "none") == 0) | ||
106 | + { | ||
107 | + aarch64_sls_hardening = SLS_NONE; | ||
108 | + return; | ||
109 | + } | ||
110 | + if (strcmp (const_str, "all") == 0) | ||
111 | + { | ||
112 | + aarch64_sls_hardening = SLS_ALL; | ||
113 | + return; | ||
114 | + } | ||
115 | + | ||
116 | + char *str_root = xstrdup (const_str); | ||
117 | + str = strtok_r (str_root, ",", &token_save); | ||
118 | + if (!str) | ||
119 | + error ("invalid argument given to %<-mharden-sls=%>"); | ||
120 | + | ||
121 | + int temp = SLS_NONE; | ||
122 | + while (str) | ||
123 | + { | ||
124 | + if (strcmp (str, "blr") == 0) | ||
125 | + temp |= SLS_BLR; | ||
126 | + else if (strcmp (str, "retbr") == 0) | ||
127 | + temp |= SLS_RETBR; | ||
128 | + else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0) | ||
129 | + { | ||
130 | + error ("%<%s%> must be by itself for %<-mharden-sls=%>", str); | ||
131 | + break; | ||
132 | + } | ||
133 | + else | ||
134 | + { | ||
135 | + error ("invalid argument %<%s%> for %<-mharden-sls=%>", str); | ||
136 | + break; | ||
137 | + } | ||
138 | + str = strtok_r (NULL, ",", &token_save); | ||
139 | + } | ||
140 | + aarch64_sls_hardening = (aarch64_sls_hardening_type) temp; | ||
141 | + free (str_root); | ||
142 | +} | ||
143 | + | ||
144 | /* Parses CONST_STR for branch protection features specified in | ||
145 | aarch64_branch_protect_types, and set any global variables required. Returns | ||
146 | the parsing result and assigns LAST_STR to the last processed token from | ||
147 | @@ -11972,6 +12045,9 @@ aarch64_override_options (void) | ||
148 | selected_arch = NULL; | ||
149 | selected_tune = NULL; | ||
150 | |||
151 | + if (aarch64_harden_sls_string) | ||
152 | + aarch64_validate_sls_mitigation (aarch64_harden_sls_string); | ||
153 | + | ||
154 | if (aarch64_branch_protection_string) | ||
155 | aarch64_validate_mbranch_protection (aarch64_branch_protection_string); | ||
156 | |||
157 | diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt | ||
158 | index 3c6d1cc90..d27ab6df8 100644 | ||
159 | --- a/gcc/config/aarch64/aarch64.opt | ||
160 | +++ b/gcc/config/aarch64/aarch64.opt | ||
161 | @@ -71,6 +71,10 @@ mgeneral-regs-only | ||
162 | Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Save | ||
163 | Generate code which uses only the general registers. | ||
164 | |||
165 | +mharden-sls= | ||
166 | +Target RejectNegative Joined Var(aarch64_harden_sls_string) | ||
167 | +Generate code to mitigate against straight line speculation. | ||
168 | + | ||
169 | mfix-cortex-a53-835769 | ||
170 | Target Report Var(aarch64_fix_a53_err835769) Init(2) Save | ||
171 | Workaround for ARM Cortex-A53 Erratum number 835769. | ||
172 | diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi | ||
173 | index 2f7ffe456..5f04a7d2b 100644 | ||
174 | --- a/gcc/doc/invoke.texi | ||
175 | +++ b/gcc/doc/invoke.texi | ||
176 | @@ -638,6 +638,7 @@ Objective-C and Objective-C++ Dialects}. | ||
177 | -mpc-relative-literal-loads @gol | ||
178 | -msign-return-address=@var{scope} @gol | ||
179 | -mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]|@var{bti} @gol | ||
180 | +-mharden-sls=@var{opts} @gol | ||
181 | -march=@var{name} -mcpu=@var{name} -mtune=@var{name} @gol | ||
182 | -moverride=@var{string} -mverbose-cost-dump @gol | ||
183 | -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} @gol | ||
184 | @@ -15955,6 +15956,17 @@ argument @samp{leaf} can be used to extend the signing to include leaf | ||
185 | functions. | ||
186 | @samp{bti} turns on branch target identification mechanism. | ||
187 | |||
188 | +@item -mharden-sls=@var{opts} | ||
189 | +@opindex mharden-sls | ||
190 | +Enable compiler hardening against straight line speculation (SLS). | ||
191 | +@var{opts} is a comma-separated list of the following options: | ||
192 | +@table @samp | ||
193 | +@item retbr | ||
194 | +@item blr | ||
195 | +@end table | ||
196 | +In addition, @samp{-mharden-sls=all} enables all SLS hardening while | ||
197 | +@samp{-mharden-sls=none} disables all SLS hardening. | ||
198 | + | ||
199 | @item -msve-vector-bits=@var{bits} | ||
200 | @opindex msve-vector-bits | ||
201 | Specify the number of bits in an SVE vector register. This option only has | ||
202 | -- | ||
203 | 2.25.1 | ||
204 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch b/meta/recipes-devtools/gcc/gcc-9.3/0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch deleted file mode 100644 index c972088d2b..0000000000 --- a/meta/recipes-devtools/gcc/gcc-9.3/0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch +++ /dev/null | |||
@@ -1,600 +0,0 @@ | |||
1 | CVE: CVE-2020-13844 | ||
2 | Upstream-Status: Backport | ||
3 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
4 | |||
5 | From dc586a749228ecfb71f72ec2ca10e6f7b6874af3 Mon Sep 17 00:00:00 2001 | ||
6 | From: Matthew Malcomson <matthew.malcomson@arm.com> | ||
7 | Date: Thu, 9 Jul 2020 09:11:59 +0100 | ||
8 | Subject: [PATCH 2/3] aarch64: Introduce SLS mitigation for RET and BR | ||
9 | instructions | ||
10 | |||
11 | Instructions following RET or BR are not necessarily executed. In order | ||
12 | to avoid speculation past RET and BR we can simply append a speculation | ||
13 | barrier. | ||
14 | |||
15 | Since these speculation barriers will not be architecturally executed, | ||
16 | they are not expected to add a high performance penalty. | ||
17 | |||
18 | The speculation barrier is to be SB when targeting architectures which | ||
19 | have this enabled, and DSB SY + ISB otherwise. | ||
20 | |||
21 | We add tests for each of the cases where such an instruction was seen. | ||
22 | |||
23 | This is implemented by modifying each machine description pattern that | ||
24 | emits either a RET or a BR instruction. We choose not to use something | ||
25 | like `TARGET_ASM_FUNCTION_EPILOGUE` since it does not affect the | ||
26 | `indirect_jump`, `jump`, `sibcall_insn` and `sibcall_value_insn` | ||
27 | patterns and we find it preferable to implement the functionality in the | ||
28 | same way for every pattern. | ||
29 | |||
30 | There is one particular case which is slightly tricky. The | ||
31 | implementation of TARGET_ASM_TRAMPOLINE_TEMPLATE uses a BR which needs | ||
32 | to be mitigated against. The trampoline template is used *once* per | ||
33 | compilation unit, and the TRAMPOLINE_SIZE is exposed to the user via the | ||
34 | builtin macro __LIBGCC_TRAMPOLINE_SIZE__. | ||
35 | In the future we may implement function specific attributes to turn on | ||
36 | and off hardening on a per-function basis. | ||
37 | The fixed nature of the trampoline described above implies it will be | ||
38 | safer to ensure this speculation barrier is always used. | ||
39 | |||
40 | Testing: | ||
41 | Bootstrap and regtest done on aarch64-none-linux | ||
42 | Used a temporary hack(1) to use these options on every test in the | ||
43 | testsuite and a script to check that the output never emitted an | ||
44 | unmitigated RET or BR. | ||
45 | |||
46 | 1) Temporary hack was a change to the testsuite to always use | ||
47 | `-save-temps` and run a script on the assembly output of those | ||
48 | compilations which produced one to ensure every RET or BR is immediately | ||
49 | followed by a speculation barrier. | ||
50 | |||
51 | (cherry picked from be178ecd5ac1fe1510d960ff95c66d0ff831afe1) | ||
52 | |||
53 | gcc/ChangeLog: | ||
54 | |||
55 | * config/aarch64/aarch64-protos.h (aarch64_sls_barrier): New. | ||
56 | * config/aarch64/aarch64.c (aarch64_output_casesi): Emit | ||
57 | speculation barrier after BR instruction if needs be. | ||
58 | (aarch64_trampoline_init): Handle ptr_mode value & adjust size | ||
59 | of code copied. | ||
60 | (aarch64_sls_barrier): New. | ||
61 | (aarch64_asm_trampoline_template): Add needed barriers. | ||
62 | * config/aarch64/aarch64.h (AARCH64_ISA_SB): New. | ||
63 | (TARGET_SB): New. | ||
64 | (TRAMPOLINE_SIZE): Account for barrier. | ||
65 | * config/aarch64/aarch64.md (indirect_jump, *casesi_dispatch, | ||
66 | simple_return, *do_return, *sibcall_insn, *sibcall_value_insn): | ||
67 | Emit barrier if needs be, also account for possible barrier using | ||
68 | "sls_length" attribute. | ||
69 | (sls_length): New attribute. | ||
70 | (length): Determine default using any non-default sls_length | ||
71 | value. | ||
72 | |||
73 | gcc/testsuite/ChangeLog: | ||
74 | |||
75 | * gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c: New test. | ||
76 | * gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c: | ||
77 | New test. | ||
78 | * gcc.target/aarch64/sls-mitigation/sls-mitigation.exp: New file. | ||
79 | * lib/target-supports.exp (check_effective_target_aarch64_asm_sb_ok): | ||
80 | New proc. | ||
81 | --- | ||
82 | gcc/config/aarch64/aarch64-protos.h | 1 + | ||
83 | gcc/config/aarch64/aarch64.c | 41 +++++- | ||
84 | gcc/config/aarch64/aarch64.h | 10 +- | ||
85 | gcc/config/aarch64/aarch64.md | 75 ++++++++--- | ||
86 | .../sls-mitigation/sls-miti-retbr-pacret.c | 15 +++ | ||
87 | .../aarch64/sls-mitigation/sls-miti-retbr.c | 119 ++++++++++++++++++ | ||
88 | .../aarch64/sls-mitigation/sls-mitigation.exp | 73 +++++++++++ | ||
89 | gcc/testsuite/lib/target-supports.exp | 3 +- | ||
90 | 8 files changed, 312 insertions(+), 25 deletions(-) | ||
91 | create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c | ||
92 | create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c | ||
93 | create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp | ||
94 | |||
95 | diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h | ||
96 | index 31493f412..885eae893 100644 | ||
97 | --- a/gcc/config/aarch64/aarch64-protos.h | ||
98 | +++ b/gcc/config/aarch64/aarch64-protos.h | ||
99 | @@ -644,6 +644,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode); | ||
100 | |||
101 | bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT); | ||
102 | |||
103 | +const char *aarch64_sls_barrier (int); | ||
104 | extern bool aarch64_harden_sls_retbr_p (void); | ||
105 | extern bool aarch64_harden_sls_blr_p (void); | ||
106 | |||
107 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
108 | index 269ff6c92..dff61105c 100644 | ||
109 | --- a/gcc/config/aarch64/aarch64.c | ||
110 | +++ b/gcc/config/aarch64/aarch64.c | ||
111 | @@ -8412,8 +8412,8 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) | ||
112 | static void | ||
113 | aarch64_asm_trampoline_template (FILE *f) | ||
114 | { | ||
115 | - int offset1 = 16; | ||
116 | - int offset2 = 20; | ||
117 | + int offset1 = 24; | ||
118 | + int offset2 = 28; | ||
119 | |||
120 | if (aarch64_bti_enabled ()) | ||
121 | { | ||
122 | @@ -8436,6 +8436,17 @@ aarch64_asm_trampoline_template (FILE *f) | ||
123 | } | ||
124 | asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]); | ||
125 | |||
126 | + /* We always emit a speculation barrier. | ||
127 | + This is because the same trampoline template is used for every nested | ||
128 | + function. Since nested functions are not particularly common or | ||
129 | + performant we don't worry too much about the extra instructions to copy | ||
130 | + around. | ||
131 | + This is not yet a problem, since we have not yet implemented function | ||
132 | + specific attributes to choose between hardening against straight line | ||
133 | + speculation or not, but such function specific attributes are likely to | ||
134 | + happen in the future. */ | ||
135 | + asm_fprintf (f, "\tdsb\tsy\n\tisb\n"); | ||
136 | + | ||
137 | /* The trampoline needs an extra padding instruction. In case if BTI is | ||
138 | enabled the padding instruction is replaced by the BTI instruction at | ||
139 | the beginning. */ | ||
140 | @@ -8450,10 +8461,14 @@ static void | ||
141 | aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) | ||
142 | { | ||
143 | rtx fnaddr, mem, a_tramp; | ||
144 | - const int tramp_code_sz = 16; | ||
145 | + const int tramp_code_sz = 24; | ||
146 | |||
147 | /* Don't need to copy the trailing D-words, we fill those in below. */ | ||
148 | - emit_block_move (m_tramp, assemble_trampoline_template (), | ||
149 | + /* We create our own memory address in Pmode so that `emit_block_move` can | ||
150 | + use parts of the backend which expect Pmode addresses. */ | ||
151 | + rtx temp = convert_memory_address (Pmode, XEXP (m_tramp, 0)); | ||
152 | + emit_block_move (gen_rtx_MEM (BLKmode, temp), | ||
153 | + assemble_trampoline_template (), | ||
154 | GEN_INT (tramp_code_sz), BLOCK_OP_NORMAL); | ||
155 | mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz); | ||
156 | fnaddr = XEXP (DECL_RTL (fndecl), 0); | ||
157 | @@ -8640,6 +8655,8 @@ aarch64_output_casesi (rtx *operands) | ||
158 | output_asm_insn (buf, operands); | ||
159 | output_asm_insn (patterns[index][1], operands); | ||
160 | output_asm_insn ("br\t%3", operands); | ||
161 | + output_asm_insn (aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()), | ||
162 | + operands); | ||
163 | assemble_label (asm_out_file, label); | ||
164 | return ""; | ||
165 | } | ||
166 | @@ -18976,6 +18993,22 @@ aarch64_file_end_indicate_exec_stack () | ||
167 | #undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI | ||
168 | #undef GNU_PROPERTY_AARCH64_FEATURE_1_AND | ||
169 | |||
170 | +/* Helper function for straight line speculation. | ||
171 | + Return what barrier should be emitted for straight line speculation | ||
172 | + mitigation. | ||
173 | + When not mitigating against straight line speculation this function returns | ||
174 | + an empty string. | ||
175 | + When mitigating against straight line speculation, use: | ||
176 | + * SB when the v8.5-A SB extension is enabled. | ||
177 | + * DSB+ISB otherwise. */ | ||
178 | +const char * | ||
179 | +aarch64_sls_barrier (int mitigation_required) | ||
180 | +{ | ||
181 | + return mitigation_required | ||
182 | + ? (TARGET_SB ? "sb" : "dsb\tsy\n\tisb") | ||
183 | + : ""; | ||
184 | +} | ||
185 | + | ||
186 | /* Target-specific selftests. */ | ||
187 | |||
188 | #if CHECKING_P | ||
189 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
190 | index 772a97296..72ddc6fd9 100644 | ||
191 | --- a/gcc/config/aarch64/aarch64.h | ||
192 | +++ b/gcc/config/aarch64/aarch64.h | ||
193 | @@ -235,6 +235,7 @@ extern unsigned aarch64_architecture_version; | ||
194 | #define AARCH64_ISA_F16FML (aarch64_isa_flags & AARCH64_FL_F16FML) | ||
195 | #define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_RCPC8_4) | ||
196 | #define AARCH64_ISA_V8_5 (aarch64_isa_flags & AARCH64_FL_V8_5) | ||
197 | +#define AARCH64_ISA_SB (aarch64_isa_flags & AARCH64_FL_SB) | ||
198 | |||
199 | /* Crypto is an optional extension to AdvSIMD. */ | ||
200 | #define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO) | ||
201 | @@ -285,6 +286,9 @@ extern unsigned aarch64_architecture_version; | ||
202 | #define TARGET_FIX_ERR_A53_835769_DEFAULT 1 | ||
203 | #endif | ||
204 | |||
205 | +/* SB instruction is enabled through +sb. */ | ||
206 | +#define TARGET_SB (AARCH64_ISA_SB) | ||
207 | + | ||
208 | /* Apply the workaround for Cortex-A53 erratum 835769. */ | ||
209 | #define TARGET_FIX_ERR_A53_835769 \ | ||
210 | ((aarch64_fix_a53_err835769 == 2) \ | ||
211 | @@ -931,8 +935,10 @@ typedef struct | ||
212 | |||
213 | #define RETURN_ADDR_RTX aarch64_return_addr | ||
214 | |||
215 | -/* BTI c + 3 insns + 2 pointer-sized entries. */ | ||
216 | -#define TRAMPOLINE_SIZE (TARGET_ILP32 ? 24 : 32) | ||
217 | +/* BTI c + 3 insns | ||
218 | + + sls barrier of DSB + ISB. | ||
219 | + + 2 pointer-sized entries. */ | ||
220 | +#define TRAMPOLINE_SIZE (24 + (TARGET_ILP32 ? 8 : 16)) | ||
221 | |||
222 | /* Trampolines contain dwords, so must be dword aligned. */ | ||
223 | #define TRAMPOLINE_ALIGNMENT 64 | ||
224 | diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md | ||
225 | index cc5a887d4..494aee964 100644 | ||
226 | --- a/gcc/config/aarch64/aarch64.md | ||
227 | +++ b/gcc/config/aarch64/aarch64.md | ||
228 | @@ -331,10 +331,25 @@ | ||
229 | ;; Attribute that specifies whether the alternative uses MOVPRFX. | ||
230 | (define_attr "movprfx" "no,yes" (const_string "no")) | ||
231 | |||
232 | +;; Attribute to specify that an alternative has the length of a single | ||
233 | +;; instruction plus a speculation barrier. | ||
234 | +(define_attr "sls_length" "none,retbr,casesi" (const_string "none")) | ||
235 | + | ||
236 | (define_attr "length" "" | ||
237 | (cond [(eq_attr "movprfx" "yes") | ||
238 | (const_int 8) | ||
239 | - ] (const_int 4))) | ||
240 | + | ||
241 | + (eq_attr "sls_length" "retbr") | ||
242 | + (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 4) | ||
243 | + (match_test "TARGET_SB") (const_int 8)] | ||
244 | + (const_int 12)) | ||
245 | + | ||
246 | + (eq_attr "sls_length" "casesi") | ||
247 | + (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 16) | ||
248 | + (match_test "TARGET_SB") (const_int 20)] | ||
249 | + (const_int 24)) | ||
250 | + ] | ||
251 | + (const_int 4))) | ||
252 | |||
253 | ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has | ||
254 | ;; no predicated insns. | ||
255 | @@ -370,8 +385,12 @@ | ||
256 | (define_insn "indirect_jump" | ||
257 | [(set (pc) (match_operand:DI 0 "register_operand" "r"))] | ||
258 | "" | ||
259 | - "br\\t%0" | ||
260 | - [(set_attr "type" "branch")] | ||
261 | + { | ||
262 | + output_asm_insn ("br\\t%0", operands); | ||
263 | + return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()); | ||
264 | + } | ||
265 | + [(set_attr "type" "branch") | ||
266 | + (set_attr "sls_length" "retbr")] | ||
267 | ) | ||
268 | |||
269 | (define_insn "jump" | ||
270 | @@ -657,7 +676,7 @@ | ||
271 | "* | ||
272 | return aarch64_output_casesi (operands); | ||
273 | " | ||
274 | - [(set_attr "length" "16") | ||
275 | + [(set_attr "sls_length" "casesi") | ||
276 | (set_attr "type" "branch")] | ||
277 | ) | ||
278 | |||
279 | @@ -736,14 +755,18 @@ | ||
280 | [(return)] | ||
281 | "" | ||
282 | { | ||
283 | + const char *ret = NULL; | ||
284 | if (aarch64_return_address_signing_enabled () | ||
285 | && TARGET_ARMV8_3 | ||
286 | && !crtl->calls_eh_return) | ||
287 | - return "retaa"; | ||
288 | - | ||
289 | - return "ret"; | ||
290 | + ret = "retaa"; | ||
291 | + else | ||
292 | + ret = "ret"; | ||
293 | + output_asm_insn (ret, operands); | ||
294 | + return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()); | ||
295 | } | ||
296 | - [(set_attr "type" "branch")] | ||
297 | + [(set_attr "type" "branch") | ||
298 | + (set_attr "sls_length" "retbr")] | ||
299 | ) | ||
300 | |||
301 | (define_expand "return" | ||
302 | @@ -755,8 +778,12 @@ | ||
303 | (define_insn "simple_return" | ||
304 | [(simple_return)] | ||
305 | "aarch64_use_simple_return_insn_p ()" | ||
306 | - "ret" | ||
307 | - [(set_attr "type" "branch")] | ||
308 | + { | ||
309 | + output_asm_insn ("ret", operands); | ||
310 | + return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()); | ||
311 | + } | ||
312 | + [(set_attr "type" "branch") | ||
313 | + (set_attr "sls_length" "retbr")] | ||
314 | ) | ||
315 | |||
316 | (define_insn "*cb<optab><mode>1" | ||
317 | @@ -947,10 +974,16 @@ | ||
318 | (match_operand 1 "" "")) | ||
319 | (return)] | ||
320 | "SIBLING_CALL_P (insn)" | ||
321 | - "@ | ||
322 | - br\\t%0 | ||
323 | - b\\t%c0" | ||
324 | - [(set_attr "type" "branch, branch")] | ||
325 | + { | ||
326 | + if (which_alternative == 0) | ||
327 | + { | ||
328 | + output_asm_insn ("br\\t%0", operands); | ||
329 | + return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()); | ||
330 | + } | ||
331 | + return "b\\t%c0"; | ||
332 | + } | ||
333 | + [(set_attr "type" "branch, branch") | ||
334 | + (set_attr "sls_length" "retbr,none")] | ||
335 | ) | ||
336 | |||
337 | (define_insn "*sibcall_value_insn" | ||
338 | @@ -960,10 +993,16 @@ | ||
339 | (match_operand 2 "" ""))) | ||
340 | (return)] | ||
341 | "SIBLING_CALL_P (insn)" | ||
342 | - "@ | ||
343 | - br\\t%1 | ||
344 | - b\\t%c1" | ||
345 | - [(set_attr "type" "branch, branch")] | ||
346 | + { | ||
347 | + if (which_alternative == 0) | ||
348 | + { | ||
349 | + output_asm_insn ("br\\t%1", operands); | ||
350 | + return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()); | ||
351 | + } | ||
352 | + return "b\\t%c1"; | ||
353 | + } | ||
354 | + [(set_attr "type" "branch, branch") | ||
355 | + (set_attr "sls_length" "retbr,none")] | ||
356 | ) | ||
357 | |||
358 | ;; Call subroutine returning any type. | ||
359 | diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c | ||
360 | new file mode 100644 | ||
361 | index 000000000..7656123ee | ||
362 | --- /dev/null | ||
363 | +++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c | ||
364 | @@ -0,0 +1,15 @@ | ||
365 | +/* Avoid ILP32 since pacret is only available for LP64 */ | ||
366 | +/* { dg-do compile { target { ! ilp32 } } } */ | ||
367 | +/* { dg-additional-options "-mharden-sls=retbr -mbranch-protection=pac-ret -march=armv8.3-a" } */ | ||
368 | + | ||
369 | +/* Testing the do_return pattern for retaa. */ | ||
370 | +long retbr_subcall(void); | ||
371 | +long retbr_do_return_retaa(void) | ||
372 | +{ | ||
373 | + return retbr_subcall()+1; | ||
374 | +} | ||
375 | + | ||
376 | +/* Ensure there are no BR or RET instructions which are not directly followed | ||
377 | + by a speculation barrier. */ | ||
378 | +/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb)} } } */ | ||
379 | +/* { dg-final { scan-assembler-not {ret\t} } } */ | ||
380 | diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c | ||
381 | new file mode 100644 | ||
382 | index 000000000..573b30cdc | ||
383 | --- /dev/null | ||
384 | +++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c | ||
385 | @@ -0,0 +1,119 @@ | ||
386 | +/* We ensure that -Wpedantic is off since it complains about the trampolines | ||
387 | + we explicitly want to test. */ | ||
388 | +/* { dg-additional-options "-mharden-sls=retbr -Wno-pedantic " } */ | ||
389 | +/* | ||
390 | + Ensure that the SLS hardening of RET and BR leaves no unprotected RET/BR | ||
391 | + instructions. | ||
392 | + */ | ||
393 | +typedef int (foo) (int, int); | ||
394 | +typedef void (bar) (int, int); | ||
395 | +struct sls_testclass { | ||
396 | + foo *x; | ||
397 | + bar *y; | ||
398 | + int left; | ||
399 | + int right; | ||
400 | +}; | ||
401 | + | ||
402 | +int | ||
403 | +retbr_sibcall_value_insn (struct sls_testclass x) | ||
404 | +{ | ||
405 | + return x.x(x.left, x.right); | ||
406 | +} | ||
407 | + | ||
408 | +void | ||
409 | +retbr_sibcall_insn (struct sls_testclass x) | ||
410 | +{ | ||
411 | + x.y(x.left, x.right); | ||
412 | +} | ||
413 | + | ||
414 | +/* Aim to test two different returns. | ||
415 | + One that introduces a tail call in the middle of the function, and one that | ||
416 | + has a normal return. */ | ||
417 | +int | ||
418 | +retbr_multiple_returns (struct sls_testclass x) | ||
419 | +{ | ||
420 | + int temp; | ||
421 | + if (x.left % 10) | ||
422 | + return x.x(x.left, 100); | ||
423 | + else if (x.right % 20) | ||
424 | + { | ||
425 | + return x.x(x.left * x.right, 100); | ||
426 | + } | ||
427 | + temp = x.left % x.right; | ||
428 | + temp *= 100; | ||
429 | + temp /= 2; | ||
430 | + return temp % 3; | ||
431 | +} | ||
432 | + | ||
433 | +void | ||
434 | +retbr_multiple_returns_void (struct sls_testclass x) | ||
435 | +{ | ||
436 | + if (x.left % 10) | ||
437 | + { | ||
438 | + x.y(x.left, 100); | ||
439 | + } | ||
440 | + else if (x.right % 20) | ||
441 | + { | ||
442 | + x.y(x.left * x.right, 100); | ||
443 | + } | ||
444 | + return; | ||
445 | +} | ||
446 | + | ||
447 | +/* Testing the casesi jump via register. */ | ||
448 | +__attribute__ ((optimize ("Os"))) | ||
449 | +int | ||
450 | +retbr_casesi_dispatch (struct sls_testclass x) | ||
451 | +{ | ||
452 | + switch (x.left) | ||
453 | + { | ||
454 | + case -5: | ||
455 | + return -2; | ||
456 | + case -3: | ||
457 | + return -1; | ||
458 | + case 0: | ||
459 | + return 0; | ||
460 | + case 3: | ||
461 | + return 1; | ||
462 | + case 5: | ||
463 | + break; | ||
464 | + default: | ||
465 | + __builtin_unreachable (); | ||
466 | + } | ||
467 | + return x.right; | ||
468 | +} | ||
469 | + | ||
470 | +/* Testing the BR in trampolines is mitigated against. */ | ||
471 | +void f1 (void *); | ||
472 | +void f3 (void *, void (*)(void *)); | ||
473 | +void f2 (void *); | ||
474 | + | ||
475 | +int | ||
476 | +retbr_trampolines (void *a, int b) | ||
477 | +{ | ||
478 | + if (!b) | ||
479 | + { | ||
480 | + f1 (a); | ||
481 | + return 1; | ||
482 | + } | ||
483 | + if (b) | ||
484 | + { | ||
485 | + void retbr_tramp_internal (void *c) | ||
486 | + { | ||
487 | + if (c == a) | ||
488 | + f2 (c); | ||
489 | + } | ||
490 | + f3 (a, retbr_tramp_internal); | ||
491 | + } | ||
492 | + return 0; | ||
493 | +} | ||
494 | + | ||
495 | +/* Testing the indirect_jump pattern. */ | ||
496 | +void | ||
497 | +retbr_indirect_jump (int *buf) | ||
498 | +{ | ||
499 | + __builtin_longjmp(buf, 1); | ||
500 | +} | ||
501 | + | ||
502 | +/* Ensure there are no BR or RET instructions which are not directly followed | ||
503 | + by a speculation barrier. */ | ||
504 | +/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb|sb)} } } */ | ||
505 | diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp | ||
506 | new file mode 100644 | ||
507 | index 000000000..812250379 | ||
508 | --- /dev/null | ||
509 | +++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp | ||
510 | @@ -0,0 +1,73 @@ | ||
511 | +# Regression driver for SLS mitigation on AArch64. | ||
512 | +# Copyright (C) 2020 Free Software Foundation, Inc. | ||
513 | +# Contributed by ARM Ltd. | ||
514 | +# | ||
515 | +# This file is part of GCC. | ||
516 | +# | ||
517 | +# GCC is free software; you can redistribute it and/or modify it | ||
518 | +# under the terms of the GNU General Public License as published by | ||
519 | +# the Free Software Foundation; either version 3, or (at your option) | ||
520 | +# any later version. | ||
521 | +# | ||
522 | +# GCC is distributed in the hope that it will be useful, but | ||
523 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
524 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
525 | +# General Public License for more details. | ||
526 | +# | ||
527 | +# You should have received a copy of the GNU General Public License | ||
528 | +# along with GCC; see the file COPYING3. If not see | ||
529 | +# <http://www.gnu.org/licenses/>. */ | ||
530 | + | ||
531 | +# Exit immediately if this isn't an AArch64 target. | ||
532 | +if {![istarget aarch64*-*-*] } then { | ||
533 | + return | ||
534 | +} | ||
535 | + | ||
536 | +# Load support procs. | ||
537 | +load_lib gcc-dg.exp | ||
538 | +load_lib torture-options.exp | ||
539 | + | ||
540 | +# If a testcase doesn't have special options, use these. | ||
541 | +global DEFAULT_CFLAGS | ||
542 | +if ![info exists DEFAULT_CFLAGS] then { | ||
543 | + set DEFAULT_CFLAGS " " | ||
544 | +} | ||
545 | + | ||
546 | +# Initialize `dg'. | ||
547 | +dg-init | ||
548 | +torture-init | ||
549 | + | ||
550 | +# Use different architectures as well as the normal optimisation options. | ||
551 | +# (i.e. use both SB and DSB+ISB barriers). | ||
552 | + | ||
553 | +set save-dg-do-what-default ${dg-do-what-default} | ||
554 | +# Main loop. | ||
555 | +# Run with torture tests (i.e. a bunch of different optimisation levels) just | ||
556 | +# to increase test coverage. | ||
557 | +set dg-do-what-default assemble | ||
558 | +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ | ||
559 | + "-save-temps" $DEFAULT_CFLAGS | ||
560 | + | ||
561 | +# Run the same tests but this time with SB extension. | ||
562 | +# Since not all supported assemblers will support that extension we decide | ||
563 | +# whether to assemble or just compile based on whether the extension is | ||
564 | +# supported for the available assembler. | ||
565 | + | ||
566 | +set templist {} | ||
567 | +foreach x $DG_TORTURE_OPTIONS { | ||
568 | + lappend templist "$x -march=armv8.3-a+sb " | ||
569 | + lappend templist "$x -march=armv8-a+sb " | ||
570 | +} | ||
571 | +set-torture-options $templist | ||
572 | +if { [check_effective_target_aarch64_asm_sb_ok] } { | ||
573 | + set dg-do-what-default assemble | ||
574 | +} else { | ||
575 | + set dg-do-what-default compile | ||
576 | +} | ||
577 | +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ | ||
578 | + "-save-temps" $DEFAULT_CFLAGS | ||
579 | +set dg-do-what-default ${save-dg-do-what-default} | ||
580 | + | ||
581 | +# All done. | ||
582 | +torture-finish | ||
583 | +dg-finish | ||
584 | diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp | ||
585 | index ea9a50ccb..79482f9b6 100644 | ||
586 | --- a/gcc/testsuite/lib/target-supports.exp | ||
587 | +++ b/gcc/testsuite/lib/target-supports.exp | ||
588 | @@ -8579,7 +8579,8 @@ proc check_effective_target_aarch64_tiny { } { | ||
589 | # Create functions to check that the AArch64 assembler supports the | ||
590 | # various architecture extensions via the .arch_extension pseudo-op. | ||
591 | |||
592 | -foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve"} { | ||
593 | +foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve" | ||
594 | + "sb"} { | ||
595 | eval [string map [list FUNC $aarch64_ext] { | ||
596 | proc check_effective_target_aarch64_asm_FUNC_ok { } { | ||
597 | if { [istarget aarch64*-*-*] } { | ||
598 | -- | ||
599 | 2.25.1 | ||
600 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch b/meta/recipes-devtools/gcc/gcc-9.3/0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch deleted file mode 100644 index 6dffef0a34..0000000000 --- a/meta/recipes-devtools/gcc/gcc-9.3/0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch +++ /dev/null | |||
@@ -1,659 +0,0 @@ | |||
1 | CVE: CVE-2020-13844 | ||
2 | Upstream-Status: Backport | ||
3 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
4 | |||
5 | From 2155170525f93093b90a1a065e7ed71a925566e9 Mon Sep 17 00:00:00 2001 | ||
6 | From: Matthew Malcomson <matthew.malcomson@arm.com> | ||
7 | Date: Thu, 9 Jul 2020 09:11:59 +0100 | ||
8 | Subject: [PATCH 3/3] aarch64: Mitigate SLS for BLR instruction | ||
9 | |||
10 | This patch introduces the mitigation for Straight Line Speculation past | ||
11 | the BLR instruction. | ||
12 | |||
13 | This mitigation replaces BLR instructions with a BL to a stub which uses | ||
14 | a BR to jump to the original value. These function stubs are then | ||
15 | appended with a speculation barrier to ensure no straight line | ||
16 | speculation happens after these jumps. | ||
17 | |||
18 | When optimising for speed we use a set of stubs for each function since | ||
19 | this should help the branch predictor make more accurate predictions | ||
20 | about where a stub should branch. | ||
21 | |||
22 | When optimising for size we use one set of stubs for all functions. | ||
23 | This set of stubs can have human readable names, and we are using | ||
24 | `__call_indirect_x<N>` for register x<N>. | ||
25 | |||
26 | When BTI branch protection is enabled the BLR instruction can jump to a | ||
27 | `BTI c` instruction using any register, while the BR instruction can | ||
28 | only jump to a `BTI c` instruction using the x16 or x17 registers. | ||
29 | Hence, in order to ensure this transformation is safe we mov the value | ||
30 | of the original register into x16 and use x16 for the BR. | ||
31 | |||
32 | As an example when optimising for size: | ||
33 | a | ||
34 | BLR x0 | ||
35 | instruction would get transformed to something like | ||
36 | BL __call_indirect_x0 | ||
37 | where __call_indirect_x0 labels a thunk that contains | ||
38 | __call_indirect_x0: | ||
39 | MOV X16, X0 | ||
40 | BR X16 | ||
41 | <speculation barrier> | ||
42 | |||
43 | The first version of this patch used local symbols specific to a | ||
44 | compilation unit to try and avoid relocations. | ||
45 | This was mistaken since functions coming from the same compilation unit | ||
46 | can still be in different sections, and the assembler will insert | ||
47 | relocations at jumps between sections. | ||
48 | |||
49 | On any relocation the linker is permitted to emit a veneer to handle | ||
50 | jumps between symbols that are very far apart. The registers x16 and | ||
51 | x17 may be clobbered by these veneers. | ||
52 | Hence the function stubs cannot rely on the values of x16 and x17 being | ||
53 | the same as just before the function stub is called. | ||
54 | |||
55 | Similar can be said for the hot/cold partitioning of single functions, | ||
56 | so function-local stubs have the same restriction. | ||
57 | |||
58 | This updated version of the patch never emits function stubs for x16 and | ||
59 | x17, and instead forces other registers to be used. | ||
60 | |||
61 | Given the above, there is now no benefit to local symbols (since they | ||
62 | are not enough to avoid dealing with linker intricacies). This patch | ||
63 | now uses global symbols with hidden visibility each stored in their own | ||
64 | COMDAT section. This means stubs can be shared between compilation | ||
65 | units while still avoiding the PLT indirection. | ||
66 | |||
67 | This patch also removes the `__call_indirect_x30` stub (and | ||
68 | function-local equivalent) which would simply jump back to the original | ||
69 | location. | ||
70 | |||
71 | The function-local stubs are emitted to the assembly output file in one | ||
72 | chunk, which means we need not add the speculation barrier directly | ||
73 | after each one. | ||
74 | This is because we know for certain that the instructions directly after | ||
75 | the BR in all but the last function stub will be from another one of | ||
76 | these stubs and hence will not contain a speculation gadget. | ||
77 | Instead we add a speculation barrier at the end of the sequence of | ||
78 | stubs. | ||
79 | |||
80 | The global stubs are emitted in COMDAT/.linkonce sections by | ||
81 | themselves so that the linker can remove duplicates from multiple object | ||
82 | files. This means they are not emitted in one chunk, and each one must | ||
83 | include the speculation barrier. | ||
84 | |||
85 | Another difference is that since the global stubs are shared across | ||
86 | compilation units we do not know that all functions will be targeting an | ||
87 | architecture supporting the SB instruction. | ||
88 | Rather than provide multiple stubs for each architecture, we provide a | ||
89 | stub that will work for all architectures -- using the DSB+ISB barrier. | ||
90 | |||
91 | This mitigation does not apply for BLR instructions in the following | ||
92 | places: | ||
93 | - Some accesses to thread-local variables use a code sequence with a BLR | ||
94 | instruction. This code sequence is part of the binary interface between | ||
95 | compiler and linker. If this BLR instruction needs to be mitigated, it'd | ||
96 | probably be best to do so in the linker. It seems that the code sequence | ||
97 | for thread-local variable access is unlikely to lead to a Spectre Revalation | ||
98 | Gadget. | ||
99 | - PLT stubs are produced by the linker and each contain a BLR instruction. | ||
100 | It seems that at most only after the last PLT stub a Spectre Revalation | ||
101 | Gadget might appear. | ||
102 | |||
103 | Testing: | ||
104 | Bootstrap and regtest on AArch64 | ||
105 | (with BOOT_CFLAGS="-mharden-sls=retbr,blr") | ||
106 | Used a temporary hack(1) in gcc-dg.exp to use these options on every | ||
107 | test in the testsuite, a slight modification to emit the speculation | ||
108 | barrier after every function stub, and a script to check that the | ||
109 | output never emitted a BLR, or unmitigated BR or RET instruction. | ||
110 | Similar on an aarch64-none-elf cross-compiler. | ||
111 | |||
112 | 1) Temporary hack emitted a speculation barrier at the end of every stub | ||
113 | function, and used a script to ensure that: | ||
114 | a) Every RET or BR is immediately followed by a speculation barrier. | ||
115 | b) No BLR instruction is emitted by compiler. | ||
116 | |||
117 | (cherry picked from 96b7f495f9269d5448822e4fc28882edb35a58d7) | ||
118 | |||
119 | gcc/ChangeLog: | ||
120 | |||
121 | * config/aarch64/aarch64-protos.h (aarch64_indirect_call_asm): | ||
122 | New declaration. | ||
123 | * config/aarch64/aarch64.c (aarch64_regno_regclass): Handle new | ||
124 | stub registers class. | ||
125 | (aarch64_class_max_nregs): Likewise. | ||
126 | (aarch64_register_move_cost): Likewise. | ||
127 | (aarch64_sls_shared_thunks): Global array to store stub labels. | ||
128 | (aarch64_sls_emit_function_stub): New. | ||
129 | (aarch64_create_blr_label): New. | ||
130 | (aarch64_sls_emit_blr_function_thunks): New. | ||
131 | (aarch64_sls_emit_shared_blr_thunks): New. | ||
132 | (aarch64_asm_file_end): New. | ||
133 | (aarch64_indirect_call_asm): New. | ||
134 | (TARGET_ASM_FILE_END): Use aarch64_asm_file_end. | ||
135 | (TARGET_ASM_FUNCTION_EPILOGUE): Use | ||
136 | aarch64_sls_emit_blr_function_thunks. | ||
137 | * config/aarch64/aarch64.h (STB_REGNUM_P): New. | ||
138 | (enum reg_class): Add STUB_REGS class. | ||
139 | (machine_function): Introduce `call_via` array for | ||
140 | function-local stub labels. | ||
141 | * config/aarch64/aarch64.md (*call_insn, *call_value_insn): Use | ||
142 | aarch64_indirect_call_asm to emit code when hardening BLR | ||
143 | instructions. | ||
144 | * config/aarch64/constraints.md (Ucr): New constraint | ||
145 | representing registers for indirect calls. Is GENERAL_REGS | ||
146 | usually, and STUB_REGS when hardening BLR instruction against | ||
147 | SLS. | ||
148 | * config/aarch64/predicates.md (aarch64_general_reg): STUB_REGS class | ||
149 | is also a general register. | ||
150 | |||
151 | gcc/testsuite/ChangeLog: | ||
152 | |||
153 | * gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c: New test. | ||
154 | * gcc.target/aarch64/sls-mitigation/sls-miti-blr.c: New test. | ||
155 | --- | ||
156 | gcc/config/aarch64/aarch64-protos.h | 1 + | ||
157 | gcc/config/aarch64/aarch64.c | 225 +++++++++++++++++- | ||
158 | gcc/config/aarch64/aarch64.h | 15 ++ | ||
159 | gcc/config/aarch64/aarch64.md | 11 +- | ||
160 | gcc/config/aarch64/constraints.md | 9 + | ||
161 | gcc/config/aarch64/predicates.md | 3 +- | ||
162 | .../aarch64/sls-mitigation/sls-miti-blr-bti.c | 40 ++++ | ||
163 | .../aarch64/sls-mitigation/sls-miti-blr.c | 33 +++ | ||
164 | 8 files changed, 328 insertions(+), 9 deletions(-) | ||
165 | create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c | ||
166 | create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c | ||
167 | |||
168 | diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h | ||
169 | index 885eae893..2676e43ae 100644 | ||
170 | --- a/gcc/config/aarch64/aarch64-protos.h | ||
171 | +++ b/gcc/config/aarch64/aarch64-protos.h | ||
172 | @@ -645,6 +645,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode); | ||
173 | bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT); | ||
174 | |||
175 | const char *aarch64_sls_barrier (int); | ||
176 | +const char *aarch64_indirect_call_asm (rtx); | ||
177 | extern bool aarch64_harden_sls_retbr_p (void); | ||
178 | extern bool aarch64_harden_sls_blr_p (void); | ||
179 | |||
180 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
181 | index dff61105c..bc6c02c3a 100644 | ||
182 | --- a/gcc/config/aarch64/aarch64.c | ||
183 | +++ b/gcc/config/aarch64/aarch64.c | ||
184 | @@ -8190,6 +8190,9 @@ aarch64_label_mentioned_p (rtx x) | ||
185 | enum reg_class | ||
186 | aarch64_regno_regclass (unsigned regno) | ||
187 | { | ||
188 | + if (STUB_REGNUM_P (regno)) | ||
189 | + return STUB_REGS; | ||
190 | + | ||
191 | if (GP_REGNUM_P (regno)) | ||
192 | return GENERAL_REGS; | ||
193 | |||
194 | @@ -8499,6 +8502,7 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode) | ||
195 | unsigned int nregs; | ||
196 | switch (regclass) | ||
197 | { | ||
198 | + case STUB_REGS: | ||
199 | case TAILCALL_ADDR_REGS: | ||
200 | case POINTER_REGS: | ||
201 | case GENERAL_REGS: | ||
202 | @@ -10693,10 +10697,12 @@ aarch64_register_move_cost (machine_mode mode, | ||
203 | = aarch64_tune_params.regmove_cost; | ||
204 | |||
205 | /* Caller save and pointer regs are equivalent to GENERAL_REGS. */ | ||
206 | - if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS) | ||
207 | + if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS | ||
208 | + || to == STUB_REGS) | ||
209 | to = GENERAL_REGS; | ||
210 | |||
211 | - if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS) | ||
212 | + if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS | ||
213 | + || from == STUB_REGS) | ||
214 | from = GENERAL_REGS; | ||
215 | |||
216 | /* Moving between GPR and stack cost is the same as GP2GP. */ | ||
217 | @@ -19009,6 +19015,215 @@ aarch64_sls_barrier (int mitigation_required) | ||
218 | : ""; | ||
219 | } | ||
220 | |||
221 | +static GTY (()) tree aarch64_sls_shared_thunks[30]; | ||
222 | +static GTY (()) bool aarch64_sls_shared_thunks_needed = false; | ||
223 | +const char *indirect_symbol_names[30] = { | ||
224 | + "__call_indirect_x0", | ||
225 | + "__call_indirect_x1", | ||
226 | + "__call_indirect_x2", | ||
227 | + "__call_indirect_x3", | ||
228 | + "__call_indirect_x4", | ||
229 | + "__call_indirect_x5", | ||
230 | + "__call_indirect_x6", | ||
231 | + "__call_indirect_x7", | ||
232 | + "__call_indirect_x8", | ||
233 | + "__call_indirect_x9", | ||
234 | + "__call_indirect_x10", | ||
235 | + "__call_indirect_x11", | ||
236 | + "__call_indirect_x12", | ||
237 | + "__call_indirect_x13", | ||
238 | + "__call_indirect_x14", | ||
239 | + "__call_indirect_x15", | ||
240 | + "", /* "__call_indirect_x16", */ | ||
241 | + "", /* "__call_indirect_x17", */ | ||
242 | + "__call_indirect_x18", | ||
243 | + "__call_indirect_x19", | ||
244 | + "__call_indirect_x20", | ||
245 | + "__call_indirect_x21", | ||
246 | + "__call_indirect_x22", | ||
247 | + "__call_indirect_x23", | ||
248 | + "__call_indirect_x24", | ||
249 | + "__call_indirect_x25", | ||
250 | + "__call_indirect_x26", | ||
251 | + "__call_indirect_x27", | ||
252 | + "__call_indirect_x28", | ||
253 | + "__call_indirect_x29", | ||
254 | +}; | ||
255 | + | ||
256 | +/* Function to create a BLR thunk. This thunk is used to mitigate straight | ||
257 | + line speculation. Instead of a simple BLR that can be speculated past, | ||
258 | + we emit a BL to this thunk, and this thunk contains a BR to the relevant | ||
259 | + register. These thunks have the relevant speculation barries put after | ||
260 | + their indirect branch so that speculation is blocked. | ||
261 | + | ||
262 | + We use such a thunk so the speculation barriers are kept off the | ||
263 | + architecturally executed path in order to reduce the performance overhead. | ||
264 | + | ||
265 | + When optimizing for size we use stubs shared by the linked object. | ||
266 | + When optimizing for performance we emit stubs for each function in the hope | ||
267 | + that the branch predictor can better train on jumps specific for a given | ||
268 | + function. */ | ||
269 | +rtx | ||
270 | +aarch64_sls_create_blr_label (int regnum) | ||
271 | +{ | ||
272 | + gcc_assert (STUB_REGNUM_P (regnum)); | ||
273 | + if (optimize_function_for_size_p (cfun)) | ||
274 | + { | ||
275 | + /* For the thunks shared between different functions in this compilation | ||
276 | + unit we use a named symbol -- this is just for users to more easily | ||
277 | + understand the generated assembly. */ | ||
278 | + aarch64_sls_shared_thunks_needed = true; | ||
279 | + const char *thunk_name = indirect_symbol_names[regnum]; | ||
280 | + if (aarch64_sls_shared_thunks[regnum] == NULL) | ||
281 | + { | ||
282 | + /* Build a decl representing this function stub and record it for | ||
283 | + later. We build a decl here so we can use the GCC machinery for | ||
284 | + handling sections automatically (through `get_named_section` and | ||
285 | + `make_decl_one_only`). That saves us a lot of trouble handling | ||
286 | + the specifics of different output file formats. */ | ||
287 | + tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, | ||
288 | + get_identifier (thunk_name), | ||
289 | + build_function_type_list (void_type_node, | ||
290 | + NULL_TREE)); | ||
291 | + DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, | ||
292 | + NULL_TREE, void_type_node); | ||
293 | + TREE_PUBLIC (decl) = 1; | ||
294 | + TREE_STATIC (decl) = 1; | ||
295 | + DECL_IGNORED_P (decl) = 1; | ||
296 | + DECL_ARTIFICIAL (decl) = 1; | ||
297 | + make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); | ||
298 | + resolve_unique_section (decl, 0, false); | ||
299 | + aarch64_sls_shared_thunks[regnum] = decl; | ||
300 | + } | ||
301 | + | ||
302 | + return gen_rtx_SYMBOL_REF (Pmode, thunk_name); | ||
303 | + } | ||
304 | + | ||
305 | + if (cfun->machine->call_via[regnum] == NULL) | ||
306 | + cfun->machine->call_via[regnum] | ||
307 | + = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ()); | ||
308 | + return cfun->machine->call_via[regnum]; | ||
309 | +} | ||
310 | + | ||
311 | +/* Helper function for aarch64_sls_emit_blr_function_thunks and | ||
312 | + aarch64_sls_emit_shared_blr_thunks below. */ | ||
313 | +static void | ||
314 | +aarch64_sls_emit_function_stub (FILE *out_file, int regnum) | ||
315 | +{ | ||
316 | + /* Save in x16 and branch to that function so this transformation does | ||
317 | + not prevent jumping to `BTI c` instructions. */ | ||
318 | + asm_fprintf (out_file, "\tmov\tx16, x%d\n", regnum); | ||
319 | + asm_fprintf (out_file, "\tbr\tx16\n"); | ||
320 | +} | ||
321 | + | ||
322 | +/* Emit all BLR stubs for this particular function. | ||
323 | + Here we emit all the BLR stubs needed for the current function. Since we | ||
324 | + emit these stubs in a consecutive block we know there will be no speculation | ||
325 | + gadgets between each stub, and hence we only emit a speculation barrier at | ||
326 | + the end of the stub sequences. | ||
327 | + | ||
328 | + This is called in the TARGET_ASM_FUNCTION_EPILOGUE hook. */ | ||
329 | +void | ||
330 | +aarch64_sls_emit_blr_function_thunks (FILE *out_file) | ||
331 | +{ | ||
332 | + if (! aarch64_harden_sls_blr_p ()) | ||
333 | + return; | ||
334 | + | ||
335 | + bool any_functions_emitted = false; | ||
336 | + /* We must save and restore the current function section since this assembly | ||
337 | + is emitted at the end of the function. This means it can be emitted *just | ||
338 | + after* the cold section of a function. That cold part would be emitted in | ||
339 | + a different section. That switch would trigger a `.cfi_endproc` directive | ||
340 | + to be emitted in the original section and a `.cfi_startproc` directive to | ||
341 | + be emitted in the new section. Switching to the original section without | ||
342 | + restoring would mean that the `.cfi_endproc` emitted as a function ends | ||
343 | + would happen in a different section -- leaving an unmatched | ||
344 | + `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc` | ||
345 | + in the standard text section. */ | ||
346 | + section *save_text_section = in_section; | ||
347 | + switch_to_section (function_section (current_function_decl)); | ||
348 | + for (int regnum = 0; regnum < 30; ++regnum) | ||
349 | + { | ||
350 | + rtx specu_label = cfun->machine->call_via[regnum]; | ||
351 | + if (specu_label == NULL) | ||
352 | + continue; | ||
353 | + | ||
354 | + targetm.asm_out.print_operand (out_file, specu_label, 0); | ||
355 | + asm_fprintf (out_file, ":\n"); | ||
356 | + aarch64_sls_emit_function_stub (out_file, regnum); | ||
357 | + any_functions_emitted = true; | ||
358 | + } | ||
359 | + if (any_functions_emitted) | ||
360 | + /* Can use the SB if needs be here, since this stub will only be used | ||
361 | + by the current function, and hence for the current target. */ | ||
362 | + asm_fprintf (out_file, "\t%s\n", aarch64_sls_barrier (true)); | ||
363 | + switch_to_section (save_text_section); | ||
364 | +} | ||
365 | + | ||
366 | +/* Emit shared BLR stubs for the current compilation unit. | ||
367 | + Over the course of compiling this unit we may have converted some BLR | ||
368 | + instructions to a BL to a shared stub function. This is where we emit those | ||
369 | + stub functions. | ||
370 | + This function is for the stubs shared between different functions in this | ||
371 | + compilation unit. We share when optimizing for size instead of speed. | ||
372 | + | ||
373 | + This function is called through the TARGET_ASM_FILE_END hook. */ | ||
374 | +void | ||
375 | +aarch64_sls_emit_shared_blr_thunks (FILE *out_file) | ||
376 | +{ | ||
377 | + if (! aarch64_sls_shared_thunks_needed) | ||
378 | + return; | ||
379 | + | ||
380 | + for (int regnum = 0; regnum < 30; ++regnum) | ||
381 | + { | ||
382 | + tree decl = aarch64_sls_shared_thunks[regnum]; | ||
383 | + if (!decl) | ||
384 | + continue; | ||
385 | + | ||
386 | + const char *name = indirect_symbol_names[regnum]; | ||
387 | + switch_to_section (get_named_section (decl, NULL, 0)); | ||
388 | + ASM_OUTPUT_ALIGN (out_file, 2); | ||
389 | + targetm.asm_out.globalize_label (out_file, name); | ||
390 | + /* Only emits if the compiler is configured for an assembler that can | ||
391 | + handle visibility directives. */ | ||
392 | + targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); | ||
393 | + ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); | ||
394 | + ASM_OUTPUT_LABEL (out_file, name); | ||
395 | + aarch64_sls_emit_function_stub (out_file, regnum); | ||
396 | + /* Use the most conservative target to ensure it can always be used by any | ||
397 | + function in the translation unit. */ | ||
398 | + asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n"); | ||
399 | + ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl); | ||
400 | + } | ||
401 | +} | ||
402 | + | ||
403 | +/* Implement TARGET_ASM_FILE_END. */ | ||
404 | +void | ||
405 | +aarch64_asm_file_end () | ||
406 | +{ | ||
407 | + aarch64_sls_emit_shared_blr_thunks (asm_out_file); | ||
408 | + /* Since this function will be called for the ASM_FILE_END hook, we ensure | ||
409 | + that what would be called otherwise (e.g. `file_end_indicate_exec_stack` | ||
410 | + for FreeBSD) still gets called. */ | ||
411 | +#ifdef TARGET_ASM_FILE_END | ||
412 | + TARGET_ASM_FILE_END (); | ||
413 | +#endif | ||
414 | +} | ||
415 | + | ||
416 | +const char * | ||
417 | +aarch64_indirect_call_asm (rtx addr) | ||
418 | +{ | ||
419 | + gcc_assert (REG_P (addr)); | ||
420 | + if (aarch64_harden_sls_blr_p ()) | ||
421 | + { | ||
422 | + rtx stub_label = aarch64_sls_create_blr_label (REGNO (addr)); | ||
423 | + output_asm_insn ("bl\t%0", &stub_label); | ||
424 | + } | ||
425 | + else | ||
426 | + output_asm_insn ("blr\t%0", &addr); | ||
427 | + return ""; | ||
428 | +} | ||
429 | + | ||
430 | /* Target-specific selftests. */ | ||
431 | |||
432 | #if CHECKING_P | ||
433 | @@ -19529,6 +19744,12 @@ aarch64_libgcc_floating_mode_supported_p | ||
434 | #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests | ||
435 | #endif /* #if CHECKING_P */ | ||
436 | |||
437 | +#undef TARGET_ASM_FILE_END | ||
438 | +#define TARGET_ASM_FILE_END aarch64_asm_file_end | ||
439 | + | ||
440 | +#undef TARGET_ASM_FUNCTION_EPILOGUE | ||
441 | +#define TARGET_ASM_FUNCTION_EPILOGUE aarch64_sls_emit_blr_function_thunks | ||
442 | + | ||
443 | struct gcc_target targetm = TARGET_INITIALIZER; | ||
444 | |||
445 | #include "gt-aarch64.h" | ||
446 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
447 | index 72ddc6fd9..60682a100 100644 | ||
448 | --- a/gcc/config/aarch64/aarch64.h | ||
449 | +++ b/gcc/config/aarch64/aarch64.h | ||
450 | @@ -540,6 +540,16 @@ extern unsigned aarch64_architecture_version; | ||
451 | #define GP_REGNUM_P(REGNO) \ | ||
452 | (((unsigned) (REGNO - R0_REGNUM)) <= (R30_REGNUM - R0_REGNUM)) | ||
453 | |||
454 | +/* Registers known to be preserved over a BL instruction. This consists of the | ||
455 | + GENERAL_REGS without x16, x17, and x30. The x30 register is changed by the | ||
456 | + BL instruction itself, while the x16 and x17 registers may be used by | ||
457 | + veneers which can be inserted by the linker. */ | ||
458 | +#define STUB_REGNUM_P(REGNO) \ | ||
459 | + (GP_REGNUM_P (REGNO) \ | ||
460 | + && (REGNO) != R16_REGNUM \ | ||
461 | + && (REGNO) != R17_REGNUM \ | ||
462 | + && (REGNO) != R30_REGNUM) \ | ||
463 | + | ||
464 | #define FP_REGNUM_P(REGNO) \ | ||
465 | (((unsigned) (REGNO - V0_REGNUM)) <= (V31_REGNUM - V0_REGNUM)) | ||
466 | |||
467 | @@ -561,6 +571,7 @@ enum reg_class | ||
468 | { | ||
469 | NO_REGS, | ||
470 | TAILCALL_ADDR_REGS, | ||
471 | + STUB_REGS, | ||
472 | GENERAL_REGS, | ||
473 | STACK_REG, | ||
474 | POINTER_REGS, | ||
475 | @@ -580,6 +591,7 @@ enum reg_class | ||
476 | { \ | ||
477 | "NO_REGS", \ | ||
478 | "TAILCALL_ADDR_REGS", \ | ||
479 | + "STUB_REGS", \ | ||
480 | "GENERAL_REGS", \ | ||
481 | "STACK_REG", \ | ||
482 | "POINTER_REGS", \ | ||
483 | @@ -596,6 +608,7 @@ enum reg_class | ||
484 | { \ | ||
485 | { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ | ||
486 | { 0x00030000, 0x00000000, 0x00000000 }, /* TAILCALL_ADDR_REGS */\ | ||
487 | + { 0x3ffcffff, 0x00000000, 0x00000000 }, /* STUB_REGS */ \ | ||
488 | { 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \ | ||
489 | { 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ | ||
490 | { 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \ | ||
491 | @@ -735,6 +748,8 @@ typedef struct GTY (()) machine_function | ||
492 | struct aarch64_frame frame; | ||
493 | /* One entry for each hard register. */ | ||
494 | bool reg_is_wrapped_separately[LAST_SAVED_REGNUM]; | ||
495 | + /* One entry for each general purpose register. */ | ||
496 | + rtx call_via[SP_REGNUM]; | ||
497 | bool label_is_assembled; | ||
498 | } machine_function; | ||
499 | #endif | ||
500 | diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md | ||
501 | index 494aee964..ed8cf8ece 100644 | ||
502 | --- a/gcc/config/aarch64/aarch64.md | ||
503 | +++ b/gcc/config/aarch64/aarch64.md | ||
504 | @@ -908,15 +908,14 @@ | ||
505 | ) | ||
506 | |||
507 | (define_insn "*call_insn" | ||
508 | - [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "r, Usf")) | ||
509 | + [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucr, Usf")) | ||
510 | (match_operand 1 "" "")) | ||
511 | (clobber (reg:DI LR_REGNUM))] | ||
512 | "" | ||
513 | "@ | ||
514 | - blr\\t%0 | ||
515 | + * return aarch64_indirect_call_asm (operands[0]); | ||
516 | bl\\t%c0" | ||
517 | - [(set_attr "type" "call, call")] | ||
518 | -) | ||
519 | + [(set_attr "type" "call, call")]) | ||
520 | |||
521 | (define_expand "call_value" | ||
522 | [(parallel [(set (match_operand 0 "" "") | ||
523 | @@ -934,12 +933,12 @@ | ||
524 | |||
525 | (define_insn "*call_value_insn" | ||
526 | [(set (match_operand 0 "" "") | ||
527 | - (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "r, Usf")) | ||
528 | + (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "Ucr, Usf")) | ||
529 | (match_operand 2 "" ""))) | ||
530 | (clobber (reg:DI LR_REGNUM))] | ||
531 | "" | ||
532 | "@ | ||
533 | - blr\\t%1 | ||
534 | + * return aarch64_indirect_call_asm (operands[1]); | ||
535 | bl\\t%c1" | ||
536 | [(set_attr "type" "call, call")] | ||
537 | ) | ||
538 | diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md | ||
539 | index 21f9549e6..7756dbe83 100644 | ||
540 | --- a/gcc/config/aarch64/constraints.md | ||
541 | +++ b/gcc/config/aarch64/constraints.md | ||
542 | @@ -24,6 +24,15 @@ | ||
543 | (define_register_constraint "Ucs" "TAILCALL_ADDR_REGS" | ||
544 | "@internal Registers suitable for an indirect tail call") | ||
545 | |||
546 | +(define_register_constraint "Ucr" | ||
547 | + "aarch64_harden_sls_blr_p () ? STUB_REGS : GENERAL_REGS" | ||
548 | + "@internal Registers to be used for an indirect call. | ||
549 | + This is usually the general registers, but when we are hardening against | ||
550 | + Straight Line Speculation we disallow x16, x17, and x30 so we can use | ||
551 | + indirection stubs. These indirection stubs cannot use the above registers | ||
552 | + since they will be reached by a BL that may have to go through a linker | ||
553 | + veneer.") | ||
554 | + | ||
555 | (define_register_constraint "w" "FP_REGS" | ||
556 | "Floating point and SIMD vector registers.") | ||
557 | |||
558 | diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md | ||
559 | index 8e1b78421..4250aecb3 100644 | ||
560 | --- a/gcc/config/aarch64/predicates.md | ||
561 | +++ b/gcc/config/aarch64/predicates.md | ||
562 | @@ -32,7 +32,8 @@ | ||
563 | |||
564 | (define_predicate "aarch64_general_reg" | ||
565 | (and (match_operand 0 "register_operand") | ||
566 | - (match_test "REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS"))) | ||
567 | + (match_test "REGNO_REG_CLASS (REGNO (op)) == STUB_REGS | ||
568 | + || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS"))) | ||
569 | |||
570 | ;; Return true if OP a (const_int 0) operand. | ||
571 | (define_predicate "const0_operand" | ||
572 | diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c | ||
573 | new file mode 100644 | ||
574 | index 000000000..b1fb754c7 | ||
575 | --- /dev/null | ||
576 | +++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c | ||
577 | @@ -0,0 +1,40 @@ | ||
578 | +/* { dg-do compile } */ | ||
579 | +/* { dg-additional-options "-mharden-sls=blr -mbranch-protection=bti" } */ | ||
580 | +/* | ||
581 | + Ensure that the SLS hardening of BLR leaves no BLR instructions. | ||
582 | + Here we also check that there are no BR instructions with anything except an | ||
583 | + x16 or x17 register. This is because a `BTI c` instruction can be branched | ||
584 | + to using a BLR instruction using any register, but can only be branched to | ||
585 | + with a BR using an x16 or x17 register. | ||
586 | + */ | ||
587 | +typedef int (foo) (int, int); | ||
588 | +typedef void (bar) (int, int); | ||
589 | +struct sls_testclass { | ||
590 | + foo *x; | ||
591 | + bar *y; | ||
592 | + int left; | ||
593 | + int right; | ||
594 | +}; | ||
595 | + | ||
596 | +/* We test both RTL patterns for a call which returns a value and a call which | ||
597 | + does not. */ | ||
598 | +int blr_call_value (struct sls_testclass x) | ||
599 | +{ | ||
600 | + int retval = x.x(x.left, x.right); | ||
601 | + if (retval % 10) | ||
602 | + return 100; | ||
603 | + return 9; | ||
604 | +} | ||
605 | + | ||
606 | +int blr_call (struct sls_testclass x) | ||
607 | +{ | ||
608 | + x.y(x.left, x.right); | ||
609 | + if (x.left % 10) | ||
610 | + return 100; | ||
611 | + return 9; | ||
612 | +} | ||
613 | + | ||
614 | +/* { dg-final { scan-assembler-not {\tblr\t} } } */ | ||
615 | +/* { dg-final { scan-assembler-not {\tbr\tx(?!16|17)} } } */ | ||
616 | +/* { dg-final { scan-assembler {\tbr\tx(16|17)} } } */ | ||
617 | + | ||
618 | diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c | ||
619 | new file mode 100644 | ||
620 | index 000000000..88baffffe | ||
621 | --- /dev/null | ||
622 | +++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c | ||
623 | @@ -0,0 +1,33 @@ | ||
624 | +/* { dg-additional-options "-mharden-sls=blr -save-temps" } */ | ||
625 | +/* Ensure that the SLS hardening of BLR leaves no BLR instructions. | ||
626 | + We only test that all BLR instructions have been removed, not that the | ||
627 | + resulting code makes sense. */ | ||
628 | +typedef int (foo) (int, int); | ||
629 | +typedef void (bar) (int, int); | ||
630 | +struct sls_testclass { | ||
631 | + foo *x; | ||
632 | + bar *y; | ||
633 | + int left; | ||
634 | + int right; | ||
635 | +}; | ||
636 | + | ||
637 | +/* We test both RTL patterns for a call which returns a value and a call which | ||
638 | + does not. */ | ||
639 | +int blr_call_value (struct sls_testclass x) | ||
640 | +{ | ||
641 | + int retval = x.x(x.left, x.right); | ||
642 | + if (retval % 10) | ||
643 | + return 100; | ||
644 | + return 9; | ||
645 | +} | ||
646 | + | ||
647 | +int blr_call (struct sls_testclass x) | ||
648 | +{ | ||
649 | + x.y(x.left, x.right); | ||
650 | + if (x.left % 10) | ||
651 | + return 100; | ||
652 | + return 9; | ||
653 | +} | ||
654 | + | ||
655 | +/* { dg-final { scan-assembler-not {\tblr\t} } } */ | ||
656 | +/* { dg-final { scan-assembler {\tbr\tx[0-9][0-9]?} } } */ | ||
657 | -- | ||
658 | 2.25.1 | ||
659 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3.inc b/meta/recipes-devtools/gcc/gcc-9.5.inc index 1c8e3df51d..9bb41bbe24 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3.inc +++ b/meta/recipes-devtools/gcc/gcc-9.5.inc | |||
@@ -2,13 +2,13 @@ require gcc-common.inc | |||
2 | 2 | ||
3 | # Third digit in PV should be incremented after a minor release | 3 | # Third digit in PV should be incremented after a minor release |
4 | 4 | ||
5 | PV = "9.3.0" | 5 | PV = "9.5.0" |
6 | 6 | ||
7 | # BINV should be incremented to a revision after a minor gcc release | 7 | # BINV should be incremented to a revision after a minor gcc release |
8 | 8 | ||
9 | BINV = "9.3.0" | 9 | BINV = "9.5.0" |
10 | 10 | ||
11 | FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-9.3:${FILE_DIRNAME}/gcc-9.3/backport:" | 11 | FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-9.5:${FILE_DIRNAME}/gcc-9.5/backport:" |
12 | 12 | ||
13 | DEPENDS =+ "mpfr gmp libmpc zlib flex-native" | 13 | DEPENDS =+ "mpfr gmp libmpc zlib flex-native" |
14 | NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native flex-native" | 14 | NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native flex-native" |
@@ -69,16 +69,14 @@ SRC_URI = "\ | |||
69 | file://0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch \ | 69 | file://0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch \ |
70 | file://0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch \ | 70 | file://0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch \ |
71 | file://0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch \ | 71 | file://0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch \ |
72 | file://0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch \ | 72 | file://0002-libstdc-Fix-inconsistent-noexcept-specific-for-valar.patch \ |
73 | file://0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch \ | 73 | file://CVE-2023-4039.patch \ |
74 | file://0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch \ | ||
75 | file://0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch \ | ||
76 | " | 74 | " |
77 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}" | 75 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}" |
78 | SRC_URI[sha256sum] = "71e197867611f6054aa1119b13a0c0abac12834765fe2d81f35ac57f84f742d1" | 76 | SRC_URI[sha256sum] = "27769f64ef1d4cd5e2be8682c0c93f9887983e6cfd1a927ce5a0a2915a95cf8f" |
79 | # For dev release snapshotting | 77 | # For dev release snapshotting |
80 | #S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/official-gcc-${RELEASE}" | 78 | #S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/official-gcc-${RELEASE}" |
81 | #B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}" | 79 | B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}" |
82 | 80 | ||
83 | # Language Overrides | 81 | # Language Overrides |
84 | FORTRAN = "" | 82 | FORTRAN = "" |
@@ -123,3 +121,6 @@ EXTRA_OECONF_PATHS = "\ | |||
123 | --with-sysroot=/not/exist \ | 121 | --with-sysroot=/not/exist \ |
124 | --with-build-sysroot=${STAGING_DIR_TARGET} \ | 122 | --with-build-sysroot=${STAGING_DIR_TARGET} \ |
125 | " | 123 | " |
124 | |||
125 | # Is a binutils 2.26 issue, not gcc | ||
126 | CVE_CHECK_WHITELIST += "CVE-2021-37322" | ||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch b/meta/recipes-devtools/gcc/gcc-9.5/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch index 0d9222df17..0d9222df17 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0002-gcc-poison-system-directories.patch b/meta/recipes-devtools/gcc/gcc-9.5/0002-gcc-poison-system-directories.patch index f427ee67c1..f427ee67c1 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0002-gcc-poison-system-directories.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0002-gcc-poison-system-directories.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.5/0002-libstdc-Fix-inconsistent-noexcept-specific-for-valar.patch b/meta/recipes-devtools/gcc/gcc-9.5/0002-libstdc-Fix-inconsistent-noexcept-specific-for-valar.patch new file mode 100644 index 0000000000..506064bfc2 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-9.5/0002-libstdc-Fix-inconsistent-noexcept-specific-for-valar.patch | |||
@@ -0,0 +1,44 @@ | |||
1 | From 60d966708d7cf105dccf128d2b7a38b0b2580a1a Mon Sep 17 00:00:00 2001 | ||
2 | From: Jonathan Wakely <jwakely@redhat.com> | ||
3 | Date: Fri, 5 Nov 2021 21:42:20 +0000 | ||
4 | Subject: [PATCH] libstdc++: Fix inconsistent noexcept-specific for valarray | ||
5 | begin/end | ||
6 | |||
7 | These declarations should be noexcept after I added it to the | ||
8 | definitions in <valarray>. | ||
9 | |||
10 | libstdc++-v3/ChangeLog: | ||
11 | |||
12 | * include/bits/range_access.h (begin(valarray), end(valarray)): | ||
13 | Add noexcept. | ||
14 | |||
15 | (cherry picked from commit 2b2d97fc545635a0f6aa9c9ee3b017394bc494bf) | ||
16 | |||
17 | Upstream-Status: Backport [https://github.com/hkaelber/gcc/commit/2b2d97fc545635a0f6aa9c9ee3b017394bc494bf] | ||
18 | Signed-off-by: Virendra Thakur <virendrak@kpit.com> | ||
19 | |||
20 | --- | ||
21 | libstdc++-v3/include/bits/range_access.h | 8 ++++---- | ||
22 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
23 | |||
24 | diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h | ||
25 | index 3d99ea92027..4736e75fda1 100644 | ||
26 | --- a/libstdc++-v3/include/bits/range_access.h | ||
27 | +++ b/libstdc++-v3/include/bits/range_access.h | ||
28 | @@ -101,10 +101,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION | ||
29 | |||
30 | template<typename _Tp> class valarray; | ||
31 | // These overloads must be declared for cbegin and cend to use them. | ||
32 | - template<typename _Tp> _Tp* begin(valarray<_Tp>&); | ||
33 | - template<typename _Tp> const _Tp* begin(const valarray<_Tp>&); | ||
34 | - template<typename _Tp> _Tp* end(valarray<_Tp>&); | ||
35 | - template<typename _Tp> const _Tp* end(const valarray<_Tp>&); | ||
36 | + template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept; | ||
37 | + template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept; | ||
38 | + template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept; | ||
39 | + template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept; | ||
40 | |||
41 | /** | ||
42 | * @brief Return an iterator pointing to the first element of | ||
43 | -- | ||
44 | 2.25.1 \ No newline at end of file | ||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch b/meta/recipes-devtools/gcc/gcc-9.5/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch index 23ec5bce03..23ec5bce03 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0003-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0004-64-bit-multilib-hack.patch b/meta/recipes-devtools/gcc/gcc-9.5/0004-64-bit-multilib-hack.patch index 17ec8986c1..17ec8986c1 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0004-64-bit-multilib-hack.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0004-64-bit-multilib-hack.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0005-optional-libstdc.patch b/meta/recipes-devtools/gcc/gcc-9.5/0005-optional-libstdc.patch index 3c28aeac63..3c28aeac63 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0005-optional-libstdc.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0005-optional-libstdc.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0006-COLLECT_GCC_OPTIONS.patch b/meta/recipes-devtools/gcc/gcc-9.5/0006-COLLECT_GCC_OPTIONS.patch index 906f3a7317..906f3a7317 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0006-COLLECT_GCC_OPTIONS.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0006-COLLECT_GCC_OPTIONS.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch b/meta/recipes-devtools/gcc/gcc-9.5/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch index 68a876cb95..68a876cb95 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0007-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0008-fortran-cross-compile-hack.patch b/meta/recipes-devtools/gcc/gcc-9.5/0008-fortran-cross-compile-hack.patch index 6acd2b0cf9..6acd2b0cf9 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0008-fortran-cross-compile-hack.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0008-fortran-cross-compile-hack.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0009-cpp-honor-sysroot.patch b/meta/recipes-devtools/gcc/gcc-9.5/0009-cpp-honor-sysroot.patch index 5a9e527606..5a9e527606 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0009-cpp-honor-sysroot.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0009-cpp-honor-sysroot.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0010-MIPS64-Default-to-N64-ABI.patch b/meta/recipes-devtools/gcc/gcc-9.5/0010-MIPS64-Default-to-N64-ABI.patch index a8103b951e..a8103b951e 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0010-MIPS64-Default-to-N64-ABI.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0010-MIPS64-Default-to-N64-ABI.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch b/meta/recipes-devtools/gcc/gcc-9.5/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch index d9d563d0f7..d9d563d0f7 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0011-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0012-gcc-Fix-argument-list-too-long-error.patch b/meta/recipes-devtools/gcc/gcc-9.5/0012-gcc-Fix-argument-list-too-long-error.patch index f0b79ee145..f0b79ee145 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0012-gcc-Fix-argument-list-too-long-error.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0012-gcc-Fix-argument-list-too-long-error.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0013-Disable-sdt.patch b/meta/recipes-devtools/gcc/gcc-9.5/0013-Disable-sdt.patch index 455858354f..455858354f 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0013-Disable-sdt.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0013-Disable-sdt.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0014-libtool.patch b/meta/recipes-devtools/gcc/gcc-9.5/0014-libtool.patch index 2953859238..2953859238 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0014-libtool.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0014-libtool.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch b/meta/recipes-devtools/gcc/gcc-9.5/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch index d4445244e2..d4445244e2 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0015-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch b/meta/recipes-devtools/gcc/gcc-9.5/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch index 6f0833ccda..6f0833ccda 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0016-Use-the-multilib-config-files-from-B-instead-of-usin.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch b/meta/recipes-devtools/gcc/gcc-9.5/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch index 96da013bf2..96da013bf2 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0017-Avoid-using-libdir-from-.la-which-usually-points-to-.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0018-export-CPP.patch b/meta/recipes-devtools/gcc/gcc-9.5/0018-export-CPP.patch index 2385099c25..2385099c25 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0018-export-CPP.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0018-export-CPP.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0019-Ensure-target-gcc-headers-can-be-included.patch b/meta/recipes-devtools/gcc/gcc-9.5/0019-Ensure-target-gcc-headers-can-be-included.patch index e0129d1f96..e0129d1f96 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0019-Ensure-target-gcc-headers-can-be-included.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0019-Ensure-target-gcc-headers-can-be-included.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch b/meta/recipes-devtools/gcc/gcc-9.5/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch index 1d2182140f..1d2182140f 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0020-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch b/meta/recipes-devtools/gcc/gcc-9.5/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch index e363c7d445..e363c7d445 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0021-Don-t-search-host-directory-during-relink-if-inst_pr.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch b/meta/recipes-devtools/gcc/gcc-9.5/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch index 846c0de5e8..846c0de5e8 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0022-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0023-aarch64-Add-support-for-musl-ldso.patch b/meta/recipes-devtools/gcc/gcc-9.5/0023-aarch64-Add-support-for-musl-ldso.patch index 102d6fc742..102d6fc742 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0023-aarch64-Add-support-for-musl-ldso.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0023-aarch64-Add-support-for-musl-ldso.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch b/meta/recipes-devtools/gcc/gcc-9.5/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch index 443e0a2ca6..443e0a2ca6 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0024-libcc1-fix-libcc1-s-install-path-and-rpath.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0025-handle-sysroot-support-for-nativesdk-gcc.patch b/meta/recipes-devtools/gcc/gcc-9.5/0025-handle-sysroot-support-for-nativesdk-gcc.patch index 59ac97eaed..59ac97eaed 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0025-handle-sysroot-support-for-nativesdk-gcc.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0025-handle-sysroot-support-for-nativesdk-gcc.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch b/meta/recipes-devtools/gcc/gcc-9.5/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch index abfa7516da..abfa7516da 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0026-Search-target-sysroot-gcc-version-specific-dirs-with.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0027-Fix-various-_FOR_BUILD-and-related-variables.patch b/meta/recipes-devtools/gcc/gcc-9.5/0027-Fix-various-_FOR_BUILD-and-related-variables.patch index ae8acc7f13..ae8acc7f13 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0027-Fix-various-_FOR_BUILD-and-related-variables.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0027-Fix-various-_FOR_BUILD-and-related-variables.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch b/meta/recipes-devtools/gcc/gcc-9.5/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch index 52a5d97aef..52a5d97aef 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0028-nios2-Define-MUSL_DYNAMIC_LINKER.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch b/meta/recipes-devtools/gcc/gcc-9.5/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch index bfa7e19dd0..bfa7e19dd0 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0029-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0030-ldbl128-config.patch b/meta/recipes-devtools/gcc/gcc-9.5/0030-ldbl128-config.patch index f8e8c07f62..f8e8c07f62 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0030-ldbl128-config.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0030-ldbl128-config.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch b/meta/recipes-devtools/gcc/gcc-9.5/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch index 60a29fc94d..60a29fc94d 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0031-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch b/meta/recipes-devtools/gcc/gcc-9.5/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch index 6f048dab82..6f048dab82 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0032-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0033-sync-gcc-stddef.h-with-musl.patch b/meta/recipes-devtools/gcc/gcc-9.5/0033-sync-gcc-stddef.h-with-musl.patch index f080b0596f..f080b0596f 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0033-sync-gcc-stddef.h-with-musl.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0033-sync-gcc-stddef.h-with-musl.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0034-fix-segmentation-fault-in-precompiled-header-generat.patch b/meta/recipes-devtools/gcc/gcc-9.5/0034-fix-segmentation-fault-in-precompiled-header-generat.patch index 3b7ccb3e3d..3b7ccb3e3d 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0034-fix-segmentation-fault-in-precompiled-header-generat.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0034-fix-segmentation-fault-in-precompiled-header-generat.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0035-Fix-for-testsuite-failure.patch b/meta/recipes-devtools/gcc/gcc-9.5/0035-Fix-for-testsuite-failure.patch index 5e199fbcfd..5e199fbcfd 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0035-Fix-for-testsuite-failure.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0035-Fix-for-testsuite-failure.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0036-Re-introduce-spe-commandline-options.patch b/meta/recipes-devtools/gcc/gcc-9.5/0036-Re-introduce-spe-commandline-options.patch index 825e070aa3..825e070aa3 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0036-Re-introduce-spe-commandline-options.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0036-Re-introduce-spe-commandline-options.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch b/meta/recipes-devtools/gcc/gcc-9.5/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch index f268a4eb58..f268a4eb58 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch b/meta/recipes-devtools/gcc/gcc-9.5/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch index a79fc03d15..a79fc03d15 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.3/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch b/meta/recipes-devtools/gcc/gcc-9.5/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch index b69114d1e5..b69114d1e5 100644 --- a/meta/recipes-devtools/gcc/gcc-9.3/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch +++ b/meta/recipes-devtools/gcc/gcc-9.5/0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch | |||
diff --git a/meta/recipes-devtools/gcc/gcc-9.5/CVE-2023-4039.patch b/meta/recipes-devtools/gcc/gcc-9.5/CVE-2023-4039.patch new file mode 100644 index 0000000000..56d229066f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-9.5/CVE-2023-4039.patch | |||
@@ -0,0 +1,1506 @@ | |||
1 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
2 | Subject: [PATCH 00/19] aarch64: Fix -fstack-protector issue | ||
3 | Date: Tue, 12 Sep 2023 16:25:10 +0100 | ||
4 | |||
5 | This series of patches fixes deficiencies in GCC's -fstack-protector | ||
6 | implementation for AArch64 when using dynamically allocated stack space. | ||
7 | This is CVE-2023-4039. See: | ||
8 | |||
9 | https://developer.arm.com/Arm%20Security%20Center/GCC%20Stack%20Protector%20Vulnerability%20AArch64 | ||
10 | https://github.com/metaredteam/external-disclosures/security/advisories/GHSA-x7ch-h5rf-w2mf | ||
11 | |||
12 | for more details. | ||
13 | |||
14 | The fix is to put the saved registers above the locals area when | ||
15 | -fstack-protector is used. | ||
16 | |||
17 | The series also fixes a stack-clash problem that I found while working | ||
18 | on the CVE. In unpatched sources, the stack-clash problem would only | ||
19 | trigger for unrealistic numbers of arguments (8K 64-bit arguments, or an | ||
20 | equivalent). But it would be a more significant issue with the new | ||
21 | -fstack-protector frame layout. It's therefore important that both | ||
22 | problems are fixed together. | ||
23 | |||
24 | Some reorganisation of the code seemed necessary to fix the problems in a | ||
25 | cleanish way. The series is therefore quite long, but only a handful of | ||
26 | patches should have any effect on code generation. | ||
27 | |||
28 | See the individual patches for a detailed description. | ||
29 | |||
30 | Tested on aarch64-linux-gnu. Pushed to trunk and to all active branches. | ||
31 | I've also pushed backports to GCC 7+ to vendors/ARM/heads/CVE-2023-4039. | ||
32 | |||
33 | CVE: CVE-2023-4039 | ||
34 | Upstream-Status: Submitted | ||
35 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
36 | |||
37 | |||
38 | From 78ebdb7b12d5e258b9811bab715734454268fd0c Mon Sep 17 00:00:00 2001 | ||
39 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
40 | Date: Fri, 16 Jun 2023 17:00:51 +0100 | ||
41 | Subject: [PATCH 01/10] aarch64: Explicitly handle frames with no saved | ||
42 | registers | ||
43 | |||
44 | If a frame has no saved registers, it can be allocated in one go. | ||
45 | There is no need to treat the areas below and above the saved | ||
46 | registers as separate. | ||
47 | |||
48 | And if we allocate the frame in one go, it should be allocated | ||
49 | as the initial_adjust rather than the final_adjust. This allows the | ||
50 | frame size to grow to guard_size - guard_used_by_caller before a stack | ||
51 | probe is needed. (A frame with no register saves is necessarily a | ||
52 | leaf frame.) | ||
53 | |||
54 | This is a no-op as thing stand, since a leaf function will have | ||
55 | no outgoing arguments, and so all the frame will be above where | ||
56 | the saved registers normally go. | ||
57 | |||
58 | gcc/ | ||
59 | * config/aarch64/aarch64.c (aarch64_layout_frame): Explicitly | ||
60 | allocate the frame in one go if there are no saved registers. | ||
61 | --- | ||
62 | gcc/config/aarch64/aarch64.c | 8 +++++--- | ||
63 | 1 file changed, 5 insertions(+), 3 deletions(-) | ||
64 | |||
65 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
66 | index a35dceab9fc..e9dad682738 100644 | ||
67 | --- a/gcc/config/aarch64/aarch64.c | ||
68 | +++ b/gcc/config/aarch64/aarch64.c | ||
69 | @@ -4771,9 +4771,11 @@ aarch64_layout_frame (void) | ||
70 | max_push_offset = 256; | ||
71 | |||
72 | HOST_WIDE_INT const_size, const_fp_offset; | ||
73 | - if (cfun->machine->frame.frame_size.is_constant (&const_size) | ||
74 | - && const_size < max_push_offset | ||
75 | - && known_eq (crtl->outgoing_args_size, 0)) | ||
76 | + if (cfun->machine->frame.saved_regs_size == 0) | ||
77 | + cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size; | ||
78 | + else if (cfun->machine->frame.frame_size.is_constant (&const_size) | ||
79 | + && const_size < max_push_offset | ||
80 | + && known_eq (crtl->outgoing_args_size, 0)) | ||
81 | { | ||
82 | /* Simple, small frame with no outgoing arguments: | ||
83 | stp reg1, reg2, [sp, -frame_size]! | ||
84 | -- | ||
85 | 2.34.1 | ||
86 | |||
87 | |||
88 | From 347487fffa0266d43bf18f1f91878410881f596e Mon Sep 17 00:00:00 2001 | ||
89 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
90 | Date: Fri, 16 Jun 2023 16:55:12 +0100 | ||
91 | Subject: [PATCH 02/10] aarch64: Add bytes_below_hard_fp to frame info | ||
92 | |||
93 | The frame layout code currently hard-codes the assumption that | ||
94 | the number of bytes below the saved registers is equal to the | ||
95 | size of the outgoing arguments. This patch abstracts that | ||
96 | value into a new field of aarch64_frame. | ||
97 | |||
98 | gcc/ | ||
99 | * config/aarch64/aarch64.h (aarch64_frame::bytes_below_hard_fp): New | ||
100 | field. | ||
101 | * config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it, | ||
102 | and use it instead of crtl->outgoing_args_size. | ||
103 | (aarch64_get_separate_components): Use bytes_below_hard_fp instead | ||
104 | of outgoing_args_size. | ||
105 | (aarch64_process_components): Likewise. | ||
106 | --- | ||
107 | gcc/config/aarch64/aarch64.c | 50 +++++++++++++++++++----------------- | ||
108 | gcc/config/aarch64/aarch64.h | 6 ++++- | ||
109 | 2 files changed, 32 insertions(+), 24 deletions(-) | ||
110 | |||
111 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
112 | index e9dad682738..25cf10cc4b9 100644 | ||
113 | --- a/gcc/config/aarch64/aarch64.c | ||
114 | +++ b/gcc/config/aarch64/aarch64.c | ||
115 | @@ -4684,6 +4684,8 @@ aarch64_layout_frame (void) | ||
116 | last_fp_reg = regno; | ||
117 | } | ||
118 | |||
119 | + cfun->machine->frame.bytes_below_hard_fp = crtl->outgoing_args_size; | ||
120 | + | ||
121 | if (cfun->machine->frame.emit_frame_chain) | ||
122 | { | ||
123 | /* FP and LR are placed in the linkage record. */ | ||
124 | @@ -4751,11 +4753,11 @@ aarch64_layout_frame (void) | ||
125 | STACK_BOUNDARY / BITS_PER_UNIT); | ||
126 | |||
127 | /* Both these values are already aligned. */ | ||
128 | - gcc_assert (multiple_p (crtl->outgoing_args_size, | ||
129 | + gcc_assert (multiple_p (cfun->machine->frame.bytes_below_hard_fp, | ||
130 | STACK_BOUNDARY / BITS_PER_UNIT)); | ||
131 | cfun->machine->frame.frame_size | ||
132 | = (cfun->machine->frame.hard_fp_offset | ||
133 | - + crtl->outgoing_args_size); | ||
134 | + + cfun->machine->frame.bytes_below_hard_fp); | ||
135 | |||
136 | cfun->machine->frame.locals_offset = cfun->machine->frame.saved_varargs_size; | ||
137 | |||
138 | @@ -4775,23 +4777,23 @@ aarch64_layout_frame (void) | ||
139 | cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size; | ||
140 | else if (cfun->machine->frame.frame_size.is_constant (&const_size) | ||
141 | && const_size < max_push_offset | ||
142 | - && known_eq (crtl->outgoing_args_size, 0)) | ||
143 | + && known_eq (cfun->machine->frame.bytes_below_hard_fp, 0)) | ||
144 | { | ||
145 | - /* Simple, small frame with no outgoing arguments: | ||
146 | + /* Simple, small frame with no data below the saved registers. | ||
147 | stp reg1, reg2, [sp, -frame_size]! | ||
148 | stp reg3, reg4, [sp, 16] */ | ||
149 | cfun->machine->frame.callee_adjust = const_size; | ||
150 | } | ||
151 | - else if (known_lt (crtl->outgoing_args_size | ||
152 | + else if (known_lt (cfun->machine->frame.bytes_below_hard_fp | ||
153 | + cfun->machine->frame.saved_regs_size, 512) | ||
154 | && !(cfun->calls_alloca | ||
155 | && known_lt (cfun->machine->frame.hard_fp_offset, | ||
156 | max_push_offset))) | ||
157 | { | ||
158 | - /* Frame with small outgoing arguments: | ||
159 | + /* Frame with small area below the saved registers: | ||
160 | sub sp, sp, frame_size | ||
161 | - stp reg1, reg2, [sp, outgoing_args_size] | ||
162 | - stp reg3, reg4, [sp, outgoing_args_size + 16] */ | ||
163 | + stp reg1, reg2, [sp, bytes_below_hard_fp] | ||
164 | + stp reg3, reg4, [sp, bytes_below_hard_fp + 16] */ | ||
165 | cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size; | ||
166 | cfun->machine->frame.callee_offset | ||
167 | = cfun->machine->frame.frame_size - cfun->machine->frame.hard_fp_offset; | ||
168 | @@ -4799,22 +4801,23 @@ aarch64_layout_frame (void) | ||
169 | else if (cfun->machine->frame.hard_fp_offset.is_constant (&const_fp_offset) | ||
170 | && const_fp_offset < max_push_offset) | ||
171 | { | ||
172 | - /* Frame with large outgoing arguments but a small local area: | ||
173 | + /* Frame with large area below the saved registers, but with a | ||
174 | + small area above: | ||
175 | stp reg1, reg2, [sp, -hard_fp_offset]! | ||
176 | stp reg3, reg4, [sp, 16] | ||
177 | - sub sp, sp, outgoing_args_size */ | ||
178 | + sub sp, sp, bytes_below_hard_fp */ | ||
179 | cfun->machine->frame.callee_adjust = const_fp_offset; | ||
180 | cfun->machine->frame.final_adjust | ||
181 | = cfun->machine->frame.frame_size - cfun->machine->frame.callee_adjust; | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | - /* Frame with large local area and outgoing arguments using frame pointer: | ||
186 | + /* General case: | ||
187 | sub sp, sp, hard_fp_offset | ||
188 | stp x29, x30, [sp, 0] | ||
189 | add x29, sp, 0 | ||
190 | stp reg3, reg4, [sp, 16] | ||
191 | - sub sp, sp, outgoing_args_size */ | ||
192 | + sub sp, sp, bytes_below_hard_fp */ | ||
193 | cfun->machine->frame.initial_adjust = cfun->machine->frame.hard_fp_offset; | ||
194 | cfun->machine->frame.final_adjust | ||
195 | = cfun->machine->frame.frame_size - cfun->machine->frame.initial_adjust; | ||
196 | @@ -5243,9 +5246,11 @@ aarch64_get_separate_components (void) | ||
197 | if (aarch64_register_saved_on_entry (regno)) | ||
198 | { | ||
199 | poly_int64 offset = cfun->machine->frame.reg_offset[regno]; | ||
200 | + | ||
201 | + /* Get the offset relative to the register we'll use. */ | ||
202 | if (!frame_pointer_needed) | ||
203 | - offset += cfun->machine->frame.frame_size | ||
204 | - - cfun->machine->frame.hard_fp_offset; | ||
205 | + offset += cfun->machine->frame.bytes_below_hard_fp; | ||
206 | + | ||
207 | /* Check that we can access the stack slot of the register with one | ||
208 | direct load with no adjustments needed. */ | ||
209 | if (offset_12bit_unsigned_scaled_p (DImode, offset)) | ||
210 | @@ -5367,8 +5372,8 @@ aarch64_process_components (sbitmap components, bool prologue_p) | ||
211 | rtx reg = gen_rtx_REG (mode, regno); | ||
212 | poly_int64 offset = cfun->machine->frame.reg_offset[regno]; | ||
213 | if (!frame_pointer_needed) | ||
214 | - offset += cfun->machine->frame.frame_size | ||
215 | - - cfun->machine->frame.hard_fp_offset; | ||
216 | + offset += cfun->machine->frame.bytes_below_hard_fp; | ||
217 | + | ||
218 | rtx addr = plus_constant (Pmode, ptr_reg, offset); | ||
219 | rtx mem = gen_frame_mem (mode, addr); | ||
220 | |||
221 | @@ -5410,8 +5415,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) | ||
222 | /* REGNO2 can be saved/restored in a pair with REGNO. */ | ||
223 | rtx reg2 = gen_rtx_REG (mode, regno2); | ||
224 | if (!frame_pointer_needed) | ||
225 | - offset2 += cfun->machine->frame.frame_size | ||
226 | - - cfun->machine->frame.hard_fp_offset; | ||
227 | + offset2 += cfun->machine->frame.bytes_below_hard_fp; | ||
228 | rtx addr2 = plus_constant (Pmode, ptr_reg, offset2); | ||
229 | rtx mem2 = gen_frame_mem (mode, addr2); | ||
230 | rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2) | ||
231 | @@ -5478,10 +5482,10 @@ aarch64_stack_clash_protection_alloca_probe_range (void) | ||
232 | registers. If POLY_SIZE is not large enough to require a probe this function | ||
233 | will only adjust the stack. When allocating the stack space | ||
234 | FRAME_RELATED_P is then used to indicate if the allocation is frame related. | ||
235 | - FINAL_ADJUSTMENT_P indicates whether we are allocating the outgoing | ||
236 | - arguments. If we are then we ensure that any allocation larger than the ABI | ||
237 | - defined buffer needs a probe so that the invariant of having a 1KB buffer is | ||
238 | - maintained. | ||
239 | + FINAL_ADJUSTMENT_P indicates whether we are allocating the area below | ||
240 | + the saved registers. If we are then we ensure that any allocation | ||
241 | + larger than the ABI defined buffer needs a probe so that the | ||
242 | + invariant of having a 1KB buffer is maintained. | ||
243 | |||
244 | We emit barriers after each stack adjustment to prevent optimizations from | ||
245 | breaking the invariant that we never drop the stack more than a page. This | ||
246 | @@ -5671,7 +5675,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
247 | /* Handle any residuals. Residuals of at least MIN_PROBE_THRESHOLD have to | ||
248 | be probed. This maintains the requirement that each page is probed at | ||
249 | least once. For initial probing we probe only if the allocation is | ||
250 | - more than GUARD_SIZE - buffer, and for the outgoing arguments we probe | ||
251 | + more than GUARD_SIZE - buffer, and below the saved registers we probe | ||
252 | if the amount is larger than buffer. GUARD_SIZE - buffer + buffer == | ||
253 | GUARD_SIZE. This works that for any allocation that is large enough to | ||
254 | trigger a probe here, we'll have at least one, and if they're not large | ||
255 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
256 | index af0bc3f1881..95831637ba7 100644 | ||
257 | --- a/gcc/config/aarch64/aarch64.h | ||
258 | +++ b/gcc/config/aarch64/aarch64.h | ||
259 | @@ -712,9 +712,13 @@ struct GTY (()) aarch64_frame | ||
260 | HOST_WIDE_INT saved_varargs_size; | ||
261 | |||
262 | /* The size of the saved callee-save int/FP registers. */ | ||
263 | - | ||
264 | HOST_WIDE_INT saved_regs_size; | ||
265 | |||
266 | + /* The number of bytes between the bottom of the static frame (the bottom | ||
267 | + of the outgoing arguments) and the hard frame pointer. This value is | ||
268 | + always a multiple of STACK_BOUNDARY. */ | ||
269 | + poly_int64 bytes_below_hard_fp; | ||
270 | + | ||
271 | /* Offset from the base of the frame (incomming SP) to the | ||
272 | top of the locals area. This value is always a multiple of | ||
273 | STACK_BOUNDARY. */ | ||
274 | -- | ||
275 | 2.34.1 | ||
276 | |||
277 | |||
278 | From 4604c4cd0a6c4c26d6594ec9a0383b4d9197d9df Mon Sep 17 00:00:00 2001 | ||
279 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
280 | Date: Tue, 27 Jun 2023 11:25:40 +0100 | ||
281 | Subject: [PATCH 03/10] aarch64: Rename locals_offset to bytes_above_locals | ||
282 | MIME-Version: 1.0 | ||
283 | Content-Type: text/plain; charset=UTF-8 | ||
284 | Content-Transfer-Encoding: 8bit | ||
285 | |||
286 | locals_offset was described as: | ||
287 | |||
288 | /* Offset from the base of the frame (incomming SP) to the | ||
289 | top of the locals area. This value is always a multiple of | ||
290 | STACK_BOUNDARY. */ | ||
291 | |||
292 | This is implicitly an “upside down” view of the frame: the incoming | ||
293 | SP is at offset 0, and anything N bytes below the incoming SP is at | ||
294 | offset N (rather than -N). | ||
295 | |||
296 | However, reg_offset instead uses a “right way up” view; that is, | ||
297 | it views offsets in address terms. Something above X is at a | ||
298 | positive offset from X and something below X is at a negative | ||
299 | offset from X. | ||
300 | |||
301 | Also, even on FRAME_GROWS_DOWNWARD targets like AArch64, | ||
302 | target-independent code views offsets in address terms too: | ||
303 | locals are allocated at negative offsets to virtual_stack_vars. | ||
304 | |||
305 | It seems confusing to have *_offset fields of the same structure | ||
306 | using different polarities like this. This patch tries to avoid | ||
307 | that by renaming locals_offset to bytes_above_locals. | ||
308 | |||
309 | gcc/ | ||
310 | * config/aarch64/aarch64.h (aarch64_frame::locals_offset): Rename to... | ||
311 | (aarch64_frame::bytes_above_locals): ...this. | ||
312 | * config/aarch64/aarch64.c (aarch64_layout_frame) | ||
313 | (aarch64_initial_elimination_offset): Update accordingly. | ||
314 | --- | ||
315 | gcc/config/aarch64/aarch64.c | 9 +++++---- | ||
316 | gcc/config/aarch64/aarch64.h | 6 +++--- | ||
317 | 2 files changed, 8 insertions(+), 7 deletions(-) | ||
318 | |||
319 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
320 | index 25cf10cc4b9..dcaf491af42 100644 | ||
321 | --- a/gcc/config/aarch64/aarch64.c | ||
322 | +++ b/gcc/config/aarch64/aarch64.c | ||
323 | @@ -4759,7 +4759,8 @@ aarch64_layout_frame (void) | ||
324 | = (cfun->machine->frame.hard_fp_offset | ||
325 | + cfun->machine->frame.bytes_below_hard_fp); | ||
326 | |||
327 | - cfun->machine->frame.locals_offset = cfun->machine->frame.saved_varargs_size; | ||
328 | + cfun->machine->frame.bytes_above_locals | ||
329 | + = cfun->machine->frame.saved_varargs_size; | ||
330 | |||
331 | cfun->machine->frame.initial_adjust = 0; | ||
332 | cfun->machine->frame.final_adjust = 0; | ||
333 | @@ -8566,14 +8567,14 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to) | ||
334 | |||
335 | if (from == FRAME_POINTER_REGNUM) | ||
336 | return cfun->machine->frame.hard_fp_offset | ||
337 | - - cfun->machine->frame.locals_offset; | ||
338 | + - cfun->machine->frame.bytes_above_locals; | ||
339 | } | ||
340 | |||
341 | if (to == STACK_POINTER_REGNUM) | ||
342 | { | ||
343 | if (from == FRAME_POINTER_REGNUM) | ||
344 | - return cfun->machine->frame.frame_size | ||
345 | - - cfun->machine->frame.locals_offset; | ||
346 | + return cfun->machine->frame.frame_size | ||
347 | + - cfun->machine->frame.bytes_above_locals; | ||
348 | } | ||
349 | |||
350 | return cfun->machine->frame.frame_size; | ||
351 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
352 | index 95831637ba7..a079a88b4f4 100644 | ||
353 | --- a/gcc/config/aarch64/aarch64.h | ||
354 | +++ b/gcc/config/aarch64/aarch64.h | ||
355 | @@ -719,10 +719,10 @@ struct GTY (()) aarch64_frame | ||
356 | always a multiple of STACK_BOUNDARY. */ | ||
357 | poly_int64 bytes_below_hard_fp; | ||
358 | |||
359 | - /* Offset from the base of the frame (incomming SP) to the | ||
360 | - top of the locals area. This value is always a multiple of | ||
361 | + /* The number of bytes between the top of the locals area and the top | ||
362 | + of the frame (the incomming SP). This value is always a multiple of | ||
363 | STACK_BOUNDARY. */ | ||
364 | - poly_int64 locals_offset; | ||
365 | + poly_int64 bytes_above_locals; | ||
366 | |||
367 | /* Offset from the base of the frame (incomming SP) to the | ||
368 | hard_frame_pointer. This value is always a multiple of | ||
369 | -- | ||
370 | 2.34.1 | ||
371 | |||
372 | |||
373 | From 16016465ff28a75f5e0540cbaeb4eb102fdc3230 Mon Sep 17 00:00:00 2001 | ||
374 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
375 | Date: Tue, 27 Jun 2023 11:28:11 +0100 | ||
376 | Subject: [PATCH 04/10] aarch64: Rename hard_fp_offset to bytes_above_hard_fp | ||
377 | MIME-Version: 1.0 | ||
378 | Content-Type: text/plain; charset=UTF-8 | ||
379 | Content-Transfer-Encoding: 8bit | ||
380 | |||
381 | Similarly to the previous locals_offset patch, hard_fp_offset | ||
382 | was described as: | ||
383 | |||
384 | /* Offset from the base of the frame (incomming SP) to the | ||
385 | hard_frame_pointer. This value is always a multiple of | ||
386 | STACK_BOUNDARY. */ | ||
387 | poly_int64 hard_fp_offset; | ||
388 | |||
389 | which again took an “upside-down” view: higher offsets meant lower | ||
390 | addresses. This patch renames the field to bytes_above_hard_fp instead. | ||
391 | |||
392 | gcc/ | ||
393 | * config/aarch64/aarch64.h (aarch64_frame::hard_fp_offset): Rename | ||
394 | to... | ||
395 | (aarch64_frame::bytes_above_hard_fp): ...this. | ||
396 | * config/aarch64/aarch64.c (aarch64_layout_frame) | ||
397 | (aarch64_expand_prologue): Update accordingly. | ||
398 | (aarch64_initial_elimination_offset): Likewise. | ||
399 | --- | ||
400 | gcc/config/aarch64/aarch64.c | 21 +++++++++++---------- | ||
401 | gcc/config/aarch64/aarch64.h | 6 +++--- | ||
402 | 2 files changed, 14 insertions(+), 13 deletions(-) | ||
403 | |||
404 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
405 | index dcaf491af42..2681e0c2bb9 100644 | ||
406 | --- a/gcc/config/aarch64/aarch64.c | ||
407 | +++ b/gcc/config/aarch64/aarch64.c | ||
408 | @@ -4747,7 +4747,7 @@ aarch64_layout_frame (void) | ||
409 | HOST_WIDE_INT varargs_and_saved_regs_size | ||
410 | = offset + cfun->machine->frame.saved_varargs_size; | ||
411 | |||
412 | - cfun->machine->frame.hard_fp_offset | ||
413 | + cfun->machine->frame.bytes_above_hard_fp | ||
414 | = aligned_upper_bound (varargs_and_saved_regs_size | ||
415 | + get_frame_size (), | ||
416 | STACK_BOUNDARY / BITS_PER_UNIT); | ||
417 | @@ -4756,7 +4756,7 @@ aarch64_layout_frame (void) | ||
418 | gcc_assert (multiple_p (cfun->machine->frame.bytes_below_hard_fp, | ||
419 | STACK_BOUNDARY / BITS_PER_UNIT)); | ||
420 | cfun->machine->frame.frame_size | ||
421 | - = (cfun->machine->frame.hard_fp_offset | ||
422 | + = (cfun->machine->frame.bytes_above_hard_fp | ||
423 | + cfun->machine->frame.bytes_below_hard_fp); | ||
424 | |||
425 | cfun->machine->frame.bytes_above_locals | ||
426 | @@ -4788,7 +4788,7 @@ aarch64_layout_frame (void) | ||
427 | else if (known_lt (cfun->machine->frame.bytes_below_hard_fp | ||
428 | + cfun->machine->frame.saved_regs_size, 512) | ||
429 | && !(cfun->calls_alloca | ||
430 | - && known_lt (cfun->machine->frame.hard_fp_offset, | ||
431 | + && known_lt (cfun->machine->frame.bytes_above_hard_fp, | ||
432 | max_push_offset))) | ||
433 | { | ||
434 | /* Frame with small area below the saved registers: | ||
435 | @@ -4797,14 +4797,14 @@ aarch64_layout_frame (void) | ||
436 | stp reg3, reg4, [sp, bytes_below_hard_fp + 16] */ | ||
437 | cfun->machine->frame.initial_adjust = cfun->machine->frame.frame_size; | ||
438 | cfun->machine->frame.callee_offset | ||
439 | - = cfun->machine->frame.frame_size - cfun->machine->frame.hard_fp_offset; | ||
440 | + = cfun->machine->frame.frame_size - cfun->machine->frame.bytes_above_hard_fp; | ||
441 | } | ||
442 | - else if (cfun->machine->frame.hard_fp_offset.is_constant (&const_fp_offset) | ||
443 | + else if (cfun->machine->frame.bytes_above_hard_fp.is_constant (&const_fp_offset) | ||
444 | && const_fp_offset < max_push_offset) | ||
445 | { | ||
446 | /* Frame with large area below the saved registers, but with a | ||
447 | small area above: | ||
448 | - stp reg1, reg2, [sp, -hard_fp_offset]! | ||
449 | + stp reg1, reg2, [sp, -bytes_above_hard_fp]! | ||
450 | stp reg3, reg4, [sp, 16] | ||
451 | sub sp, sp, bytes_below_hard_fp */ | ||
452 | cfun->machine->frame.callee_adjust = const_fp_offset; | ||
453 | @@ -4814,12 +4814,13 @@ aarch64_layout_frame (void) | ||
454 | else | ||
455 | { | ||
456 | /* General case: | ||
457 | - sub sp, sp, hard_fp_offset | ||
458 | + sub sp, sp, bytes_above_hard_fp | ||
459 | stp x29, x30, [sp, 0] | ||
460 | add x29, sp, 0 | ||
461 | stp reg3, reg4, [sp, 16] | ||
462 | sub sp, sp, bytes_below_hard_fp */ | ||
463 | - cfun->machine->frame.initial_adjust = cfun->machine->frame.hard_fp_offset; | ||
464 | + cfun->machine->frame.initial_adjust | ||
465 | + = cfun->machine->frame.bytes_above_hard_fp; | ||
466 | cfun->machine->frame.final_adjust | ||
467 | = cfun->machine->frame.frame_size - cfun->machine->frame.initial_adjust; | ||
468 | } | ||
469 | @@ -8563,10 +8564,10 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to) | ||
470 | if (to == HARD_FRAME_POINTER_REGNUM) | ||
471 | { | ||
472 | if (from == ARG_POINTER_REGNUM) | ||
473 | - return cfun->machine->frame.hard_fp_offset; | ||
474 | + return cfun->machine->frame.bytes_above_hard_fp; | ||
475 | |||
476 | if (from == FRAME_POINTER_REGNUM) | ||
477 | - return cfun->machine->frame.hard_fp_offset | ||
478 | + return cfun->machine->frame.bytes_above_hard_fp | ||
479 | - cfun->machine->frame.bytes_above_locals; | ||
480 | } | ||
481 | |||
482 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
483 | index a079a88b4f4..eab6da84a02 100644 | ||
484 | --- a/gcc/config/aarch64/aarch64.h | ||
485 | +++ b/gcc/config/aarch64/aarch64.h | ||
486 | @@ -724,10 +724,10 @@ struct GTY (()) aarch64_frame | ||
487 | STACK_BOUNDARY. */ | ||
488 | poly_int64 bytes_above_locals; | ||
489 | |||
490 | - /* Offset from the base of the frame (incomming SP) to the | ||
491 | - hard_frame_pointer. This value is always a multiple of | ||
492 | + /* The number of bytes between the hard_frame_pointer and the top of | ||
493 | + the frame (the incomming SP). This value is always a multiple of | ||
494 | STACK_BOUNDARY. */ | ||
495 | - poly_int64 hard_fp_offset; | ||
496 | + poly_int64 bytes_above_hard_fp; | ||
497 | |||
498 | /* The size of the frame. This value is the offset from base of the | ||
499 | frame (incomming SP) to the stack_pointer. This value is always | ||
500 | -- | ||
501 | 2.34.1 | ||
502 | |||
503 | |||
504 | From eb2271eb6bb68ec3c9aa9ae4746ea1ee5f18874a Mon Sep 17 00:00:00 2001 | ||
505 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
506 | Date: Thu, 22 Jun 2023 22:26:30 +0100 | ||
507 | Subject: [PATCH 05/10] aarch64: Tweak frame_size comment | ||
508 | MIME-Version: 1.0 | ||
509 | Content-Type: text/plain; charset=UTF-8 | ||
510 | Content-Transfer-Encoding: 8bit | ||
511 | |||
512 | This patch fixes another case in which a value was described with | ||
513 | an “upside-down” view. | ||
514 | |||
515 | gcc/ | ||
516 | * config/aarch64/aarch64.h (aarch64_frame::frame_size): Tweak comment. | ||
517 | --- | ||
518 | gcc/config/aarch64/aarch64.h | 4 ++-- | ||
519 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
520 | |||
521 | diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h | ||
522 | index eab6da84a02..7c4b65ec55b 100644 | ||
523 | --- a/gcc/config/aarch64/aarch64.h | ||
524 | +++ b/gcc/config/aarch64/aarch64.h | ||
525 | @@ -729,8 +729,8 @@ struct GTY (()) aarch64_frame | ||
526 | STACK_BOUNDARY. */ | ||
527 | poly_int64 bytes_above_hard_fp; | ||
528 | |||
529 | - /* The size of the frame. This value is the offset from base of the | ||
530 | - frame (incomming SP) to the stack_pointer. This value is always | ||
531 | + /* The size of the frame, i.e. the number of bytes between the bottom | ||
532 | + of the outgoing arguments and the incoming SP. This value is always | ||
533 | a multiple of STACK_BOUNDARY. */ | ||
534 | poly_int64 frame_size; | ||
535 | |||
536 | -- | ||
537 | 2.34.1 | ||
538 | |||
539 | |||
540 | From cfed3b87e9351edff1568ade4ef666edc9887639 Mon Sep 17 00:00:00 2001 | ||
541 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
542 | Date: Tue, 15 Aug 2023 19:05:30 +0100 | ||
543 | Subject: [PATCH 06/10] Backport check-function-bodies support | ||
544 | |||
545 | --- | ||
546 | gcc/testsuite/lib/scanasm.exp | 191 ++++++++++++++++++++++++++++++++++ | ||
547 | 1 file changed, 191 insertions(+) | ||
548 | |||
549 | diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp | ||
550 | index 35ccbc86fc0..c9af27bf47a 100644 | ||
551 | --- a/gcc/testsuite/lib/scanasm.exp | ||
552 | +++ b/gcc/testsuite/lib/scanasm.exp | ||
553 | @@ -546,3 +546,194 @@ proc scan-lto-assembler { args } { | ||
554 | verbose "output_file: $output_file" | ||
555 | dg-scan "scan-lto-assembler" 1 $testcase $output_file $args | ||
556 | } | ||
557 | + | ||
558 | +# Read assembly file FILENAME and store a mapping from function names | ||
559 | +# to function bodies in array RESULT. FILENAME has already been uploaded | ||
560 | +# locally where necessary and is known to exist. | ||
561 | + | ||
562 | +proc parse_function_bodies { filename result } { | ||
563 | + upvar $result up_result | ||
564 | + | ||
565 | + # Regexp for the start of a function definition (name in \1). | ||
566 | + set label {^([a-zA-Z_]\S+):$} | ||
567 | + | ||
568 | + # Regexp for the end of a function definition. | ||
569 | + set terminator {^\s*\.size} | ||
570 | + | ||
571 | + # Regexp for lines that aren't interesting. | ||
572 | + set fluff {^\s*(?:\.|//|@|$)} | ||
573 | + | ||
574 | + set fd [open $filename r] | ||
575 | + set in_function 0 | ||
576 | + while { [gets $fd line] >= 0 } { | ||
577 | + if { [regexp $label $line dummy function_name] } { | ||
578 | + set in_function 1 | ||
579 | + set function_body "" | ||
580 | + } elseif { $in_function } { | ||
581 | + if { [regexp $terminator $line] } { | ||
582 | + set up_result($function_name) $function_body | ||
583 | + set in_function 0 | ||
584 | + } elseif { ![regexp $fluff $line] } { | ||
585 | + append function_body $line "\n" | ||
586 | + } | ||
587 | + } | ||
588 | + } | ||
589 | + close $fd | ||
590 | +} | ||
591 | + | ||
592 | +# FUNCTIONS is an array that maps function names to function bodies. | ||
593 | +# Return true if it contains a definition of function NAME and if | ||
594 | +# that definition matches BODY_REGEXP. | ||
595 | + | ||
596 | +proc check_function_body { functions name body_regexp } { | ||
597 | + upvar $functions up_functions | ||
598 | + | ||
599 | + if { ![info exists up_functions($name)] } { | ||
600 | + return 0 | ||
601 | + } | ||
602 | + set fn_res [regexp "^$body_regexp\$" $up_functions($name)] | ||
603 | + if { !$fn_res } { | ||
604 | + verbose -log "body: $body_regexp" | ||
605 | + verbose -log "against: $up_functions($name)" | ||
606 | + } | ||
607 | + return $fn_res | ||
608 | +} | ||
609 | + | ||
610 | +# Check the implementations of functions against expected output. Used as: | ||
611 | +# | ||
612 | +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } | ||
613 | +# | ||
614 | +# See sourcebuild.texi for details. | ||
615 | + | ||
616 | +proc check-function-bodies { args } { | ||
617 | + if { [llength $args] < 2 } { | ||
618 | + error "too few arguments to check-function-bodies" | ||
619 | + } | ||
620 | + if { [llength $args] > 4 } { | ||
621 | + error "too many arguments to check-function-bodies" | ||
622 | + } | ||
623 | + | ||
624 | + if { [llength $args] >= 3 } { | ||
625 | + set required_flags [lindex $args 2] | ||
626 | + | ||
627 | + upvar 2 dg-extra-tool-flags extra_tool_flags | ||
628 | + set flags $extra_tool_flags | ||
629 | + | ||
630 | + global torture_current_flags | ||
631 | + if { [info exists torture_current_flags] } { | ||
632 | + append flags " " $torture_current_flags | ||
633 | + } | ||
634 | + foreach required_flag $required_flags { | ||
635 | + switch -- $required_flag { | ||
636 | + target - | ||
637 | + xfail { | ||
638 | + error "misplaced $required_flag in check-function-bodies" | ||
639 | + } | ||
640 | + } | ||
641 | + } | ||
642 | + foreach required_flag $required_flags { | ||
643 | + if { ![regexp " $required_flag " $flags] } { | ||
644 | + return | ||
645 | + } | ||
646 | + } | ||
647 | + } | ||
648 | + | ||
649 | + set xfail_all 0 | ||
650 | + if { [llength $args] >= 4 } { | ||
651 | + switch [dg-process-target [lindex $args 3]] { | ||
652 | + "S" { } | ||
653 | + "N" { return } | ||
654 | + "F" { set xfail_all 1 } | ||
655 | + "P" { } | ||
656 | + } | ||
657 | + } | ||
658 | + | ||
659 | + set testcase [testname-for-summary] | ||
660 | + # The name might include a list of options; extract the file name. | ||
661 | + set filename [lindex $testcase 0] | ||
662 | + | ||
663 | + global srcdir | ||
664 | + set input_filename "$srcdir/$filename" | ||
665 | + set output_filename "[file rootname [file tail $filename]].s" | ||
666 | + | ||
667 | + set prefix [lindex $args 0] | ||
668 | + set prefix_len [string length $prefix] | ||
669 | + set terminator [lindex $args 1] | ||
670 | + if { [string equal $terminator ""] } { | ||
671 | + set terminator "*/" | ||
672 | + } | ||
673 | + set terminator_len [string length $terminator] | ||
674 | + | ||
675 | + set have_bodies 0 | ||
676 | + if { [is_remote host] } { | ||
677 | + remote_upload host "$filename" | ||
678 | + } | ||
679 | + if { [file exists $output_filename] } { | ||
680 | + parse_function_bodies $output_filename functions | ||
681 | + set have_bodies 1 | ||
682 | + } else { | ||
683 | + verbose -log "$testcase: output file does not exist" | ||
684 | + } | ||
685 | + | ||
686 | + set count 0 | ||
687 | + set function_regexp "" | ||
688 | + set label {^(\S+):$} | ||
689 | + | ||
690 | + set lineno 1 | ||
691 | + set fd [open $input_filename r] | ||
692 | + set in_function 0 | ||
693 | + while { [gets $fd line] >= 0 } { | ||
694 | + if { [string equal -length $prefix_len $line $prefix] } { | ||
695 | + set line [string trim [string range $line $prefix_len end]] | ||
696 | + if { !$in_function } { | ||
697 | + if { [regexp "^(.*?\\S)\\s+{(.*)}\$" $line dummy \ | ||
698 | + line selector] } { | ||
699 | + set selector [dg-process-target $selector] | ||
700 | + } else { | ||
701 | + set selector "P" | ||
702 | + } | ||
703 | + if { ![regexp $label $line dummy function_name] } { | ||
704 | + close $fd | ||
705 | + error "check-function-bodies: line $lineno does not have a function label" | ||
706 | + } | ||
707 | + set in_function 1 | ||
708 | + set function_regexp "" | ||
709 | + } elseif { [string equal $line "("] } { | ||
710 | + append function_regexp "(?:" | ||
711 | + } elseif { [string equal $line "|"] } { | ||
712 | + append function_regexp "|" | ||
713 | + } elseif { [string equal $line ")"] } { | ||
714 | + append function_regexp ")" | ||
715 | + } elseif { [string equal $line "..."] } { | ||
716 | + append function_regexp ".*" | ||
717 | + } else { | ||
718 | + append function_regexp "\t" $line "\n" | ||
719 | + } | ||
720 | + } elseif { [string equal -length $terminator_len $line $terminator] } { | ||
721 | + if { ![string equal $selector "N"] } { | ||
722 | + if { $xfail_all || [string equal $selector "F"] } { | ||
723 | + setup_xfail "*-*-*" | ||
724 | + } | ||
725 | + set testname "$testcase check-function-bodies $function_name" | ||
726 | + if { !$have_bodies } { | ||
727 | + unresolved $testname | ||
728 | + } elseif { [check_function_body functions $function_name \ | ||
729 | + $function_regexp] } { | ||
730 | + pass $testname | ||
731 | + } else { | ||
732 | + fail $testname | ||
733 | + } | ||
734 | + } | ||
735 | + set in_function 0 | ||
736 | + incr count | ||
737 | + } | ||
738 | + incr lineno | ||
739 | + } | ||
740 | + close $fd | ||
741 | + if { $in_function } { | ||
742 | + error "check-function-bodies: missing \"$terminator\"" | ||
743 | + } | ||
744 | + if { $count == 0 } { | ||
745 | + error "check-function-bodies: no matches found" | ||
746 | + } | ||
747 | +} | ||
748 | -- | ||
749 | 2.34.1 | ||
750 | |||
751 | |||
752 | From 4dd8925d95d3d6d89779b494b5f4cfadcf9fa96e Mon Sep 17 00:00:00 2001 | ||
753 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
754 | Date: Tue, 27 Jun 2023 15:11:44 +0100 | ||
755 | Subject: [PATCH 07/10] aarch64: Tweak stack clash boundary condition | ||
756 | |||
757 | The AArch64 ABI says that, when stack clash protection is used, | ||
758 | there can be a maximum of 1KiB of unprobed space at sp on entry | ||
759 | to a function. Therefore, we need to probe when allocating | ||
760 | >= guard_size - 1KiB of data (>= rather than >). This is what | ||
761 | GCC does. | ||
762 | |||
763 | If an allocation is exactly guard_size bytes, it is enough to allocate | ||
764 | those bytes and probe once at offset 1024. It isn't possible to use a | ||
765 | single probe at any other offset: higher would conmplicate later code, | ||
766 | by leaving more unprobed space than usual, while lower would risk | ||
767 | leaving an entire page unprobed. For simplicity, the code probes all | ||
768 | allocations at offset 1024. | ||
769 | |||
770 | Some register saves also act as probes. If we need to allocate | ||
771 | more space below the last such register save probe, we need to | ||
772 | probe the allocation if it is > 1KiB. Again, this allocation is | ||
773 | then sometimes (but not always) probed at offset 1024. This sort of | ||
774 | allocation is currently only used for outgoing arguments, which are | ||
775 | rarely this big. | ||
776 | |||
777 | However, the code also probed if this final outgoing-arguments | ||
778 | allocation was == 1KiB, rather than just > 1KiB. This isn't | ||
779 | necessary, since the register save then probes at offset 1024 | ||
780 | as required. Continuing to probe allocations of exactly 1KiB | ||
781 | would complicate later patches. | ||
782 | |||
783 | gcc/ | ||
784 | * config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space): | ||
785 | Don't probe final allocations that are exactly 1KiB in size (after | ||
786 | unprobed space above the final allocation has been deducted). | ||
787 | |||
788 | gcc/testsuite/ | ||
789 | * gcc.target/aarch64/stack-check-prologue-17.c: New test. | ||
790 | --- | ||
791 | gcc/config/aarch64/aarch64.c | 6 +- | ||
792 | .../aarch64/stack-check-prologue-17.c | 55 +++++++++++++++++++ | ||
793 | 2 files changed, 60 insertions(+), 1 deletion(-) | ||
794 | create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
795 | |||
796 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
797 | index 2681e0c2bb9..4c9e11cd7cf 100644 | ||
798 | --- a/gcc/config/aarch64/aarch64.c | ||
799 | +++ b/gcc/config/aarch64/aarch64.c | ||
800 | @@ -5506,6 +5506,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
801 | HOST_WIDE_INT guard_size | ||
802 | = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE); | ||
803 | HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; | ||
804 | + HOST_WIDE_INT byte_sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; | ||
805 | + gcc_assert (multiple_p (poly_size, byte_sp_alignment)); | ||
806 | /* When doing the final adjustment for the outgoing argument size we can't | ||
807 | assume that LR was saved at position 0. So subtract it's offset from the | ||
808 | ABI safe buffer so that we don't accidentally allow an adjustment that | ||
809 | @@ -5513,7 +5515,9 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
810 | probing. */ | ||
811 | HOST_WIDE_INT min_probe_threshold | ||
812 | = final_adjustment_p | ||
813 | - ? guard_used_by_caller - cfun->machine->frame.reg_offset[LR_REGNUM] | ||
814 | + ? (guard_used_by_caller | ||
815 | + + byte_sp_alignment | ||
816 | + - cfun->machine->frame.reg_offset[LR_REGNUM]) | ||
817 | : guard_size - guard_used_by_caller; | ||
818 | |||
819 | poly_int64 frame_size = cfun->machine->frame.frame_size; | ||
820 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
821 | new file mode 100644 | ||
822 | index 00000000000..0d8a25d73a2 | ||
823 | --- /dev/null | ||
824 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
825 | @@ -0,0 +1,55 @@ | ||
826 | +/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */ | ||
827 | +/* { dg-final { check-function-bodies "**" "" } } */ | ||
828 | + | ||
829 | +void f(int, ...); | ||
830 | +void g(); | ||
831 | + | ||
832 | +/* | ||
833 | +** test1: | ||
834 | +** ... | ||
835 | +** str x30, \[sp\] | ||
836 | +** sub sp, sp, #1024 | ||
837 | +** cbnz w0, .* | ||
838 | +** bl g | ||
839 | +** ... | ||
840 | +*/ | ||
841 | +int test1(int z) { | ||
842 | + __uint128_t x = 0; | ||
843 | + int y[0x400]; | ||
844 | + if (z) | ||
845 | + { | ||
846 | + f(0, 0, 0, 0, 0, 0, 0, &y, | ||
847 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
848 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
849 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
850 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); | ||
851 | + } | ||
852 | + g(); | ||
853 | + return 1; | ||
854 | +} | ||
855 | + | ||
856 | +/* | ||
857 | +** test2: | ||
858 | +** ... | ||
859 | +** str x30, \[sp\] | ||
860 | +** sub sp, sp, #1040 | ||
861 | +** str xzr, \[sp\] | ||
862 | +** cbnz w0, .* | ||
863 | +** bl g | ||
864 | +** ... | ||
865 | +*/ | ||
866 | +int test2(int z) { | ||
867 | + __uint128_t x = 0; | ||
868 | + int y[0x400]; | ||
869 | + if (z) | ||
870 | + { | ||
871 | + f(0, 0, 0, 0, 0, 0, 0, &y, | ||
872 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
873 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
874 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
875 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
876 | + x); | ||
877 | + } | ||
878 | + g(); | ||
879 | + return 1; | ||
880 | +} | ||
881 | -- | ||
882 | 2.34.1 | ||
883 | |||
884 | |||
885 | From 12517baf6c88447e3bda3a459ac4c29d61f84e6c Mon Sep 17 00:00:00 2001 | ||
886 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
887 | Date: Tue, 27 Jun 2023 15:12:55 +0100 | ||
888 | Subject: [PATCH 08/10] aarch64: Put LR save probe in first 16 bytes | ||
889 | |||
890 | -fstack-clash-protection uses the save of LR as a probe for the next | ||
891 | allocation. The next allocation could be: | ||
892 | |||
893 | * another part of the static frame, e.g. when allocating SVE save slots | ||
894 | or outgoing arguments | ||
895 | |||
896 | * an alloca in the same function | ||
897 | |||
898 | * an allocation made by a callee function | ||
899 | |||
900 | However, when -fomit-frame-pointer is used, the LR save slot is placed | ||
901 | above the other GPR save slots. It could therefore be up to 80 bytes | ||
902 | above the base of the GPR save area (which is also the hard fp address). | ||
903 | |||
904 | aarch64_allocate_and_probe_stack_space took this into account when | ||
905 | deciding how much subsequent space could be allocated without needing | ||
906 | a probe. However, it interacted badly with: | ||
907 | |||
908 | /* If doing a small final adjustment, we always probe at offset 0. | ||
909 | This is done to avoid issues when LR is not at position 0 or when | ||
910 | the final adjustment is smaller than the probing offset. */ | ||
911 | else if (final_adjustment_p && rounded_size == 0) | ||
912 | residual_probe_offset = 0; | ||
913 | |||
914 | which forces any allocation that is smaller than the guard page size | ||
915 | to be probed at offset 0 rather than the usual offset 1024. It was | ||
916 | therefore possible to construct cases in which we had: | ||
917 | |||
918 | * a probe using LR at SP + 80 bytes (or some other value >= 16) | ||
919 | * an allocation of the guard page size - 16 bytes | ||
920 | * a probe at SP + 0 | ||
921 | |||
922 | which allocates guard page size + 64 consecutive unprobed bytes. | ||
923 | |||
924 | This patch requires the LR probe to be in the first 16 bytes of the | ||
925 | save area when stack clash protection is active. Doing it | ||
926 | unconditionally would cause code-quality regressions. | ||
927 | |||
928 | gcc/ | ||
929 | * config/aarch64/aarch64.c (aarch64_layout_frame): Ensure that | ||
930 | the LR save slot is in the first 16 bytes of the register save area. | ||
931 | (aarch64_allocate_and_probe_stack_space): Remove workaround for | ||
932 | when LR was not in the first 16 bytes. | ||
933 | |||
934 | gcc/testsuite/ | ||
935 | * gcc.target/aarch64/stack-check-prologue-18.c: New test. | ||
936 | --- | ||
937 | gcc/config/aarch64/aarch64.c | 50 +++++---- | ||
938 | .../aarch64/stack-check-prologue-18.c | 100 ++++++++++++++++++ | ||
939 | 2 files changed, 127 insertions(+), 23 deletions(-) | ||
940 | create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
941 | |||
942 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
943 | index 4c9e11cd7cf..1e8467fdd03 100644 | ||
944 | --- a/gcc/config/aarch64/aarch64.c | ||
945 | +++ b/gcc/config/aarch64/aarch64.c | ||
946 | @@ -4686,15 +4686,31 @@ aarch64_layout_frame (void) | ||
947 | |||
948 | cfun->machine->frame.bytes_below_hard_fp = crtl->outgoing_args_size; | ||
949 | |||
950 | +#define ALLOCATE_GPR_SLOT(REGNO) \ | ||
951 | + do \ | ||
952 | + { \ | ||
953 | + cfun->machine->frame.reg_offset[REGNO] = offset; \ | ||
954 | + if (cfun->machine->frame.wb_candidate1 == INVALID_REGNUM) \ | ||
955 | + cfun->machine->frame.wb_candidate1 = (REGNO); \ | ||
956 | + else if (cfun->machine->frame.wb_candidate2 == INVALID_REGNUM) \ | ||
957 | + cfun->machine->frame.wb_candidate2 = (REGNO); \ | ||
958 | + offset += UNITS_PER_WORD; \ | ||
959 | + } \ | ||
960 | + while (0) | ||
961 | + | ||
962 | if (cfun->machine->frame.emit_frame_chain) | ||
963 | { | ||
964 | /* FP and LR are placed in the linkage record. */ | ||
965 | - cfun->machine->frame.reg_offset[R29_REGNUM] = 0; | ||
966 | - cfun->machine->frame.wb_candidate1 = R29_REGNUM; | ||
967 | - cfun->machine->frame.reg_offset[R30_REGNUM] = UNITS_PER_WORD; | ||
968 | - cfun->machine->frame.wb_candidate2 = R30_REGNUM; | ||
969 | - offset = 2 * UNITS_PER_WORD; | ||
970 | + ALLOCATE_GPR_SLOT (R29_REGNUM); | ||
971 | + ALLOCATE_GPR_SLOT (R30_REGNUM); | ||
972 | } | ||
973 | + else if (flag_stack_clash_protection | ||
974 | + && cfun->machine->frame.reg_offset[R30_REGNUM] == SLOT_REQUIRED) | ||
975 | + /* Put the LR save slot first, since it makes a good choice of probe | ||
976 | + for stack clash purposes. The idea is that the link register usually | ||
977 | + has to be saved before a call anyway, and so we lose little by | ||
978 | + stopping it from being individually shrink-wrapped. */ | ||
979 | + ALLOCATE_GPR_SLOT (R30_REGNUM); | ||
980 | |||
981 | /* With stack-clash, LR must be saved in non-leaf functions. */ | ||
982 | gcc_assert (crtl->is_leaf | ||
983 | @@ -4704,14 +4720,9 @@ aarch64_layout_frame (void) | ||
984 | /* Now assign stack slots for them. */ | ||
985 | for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) | ||
986 | if (cfun->machine->frame.reg_offset[regno] == SLOT_REQUIRED) | ||
987 | - { | ||
988 | - cfun->machine->frame.reg_offset[regno] = offset; | ||
989 | - if (cfun->machine->frame.wb_candidate1 == INVALID_REGNUM) | ||
990 | - cfun->machine->frame.wb_candidate1 = regno; | ||
991 | - else if (cfun->machine->frame.wb_candidate2 == INVALID_REGNUM) | ||
992 | - cfun->machine->frame.wb_candidate2 = regno; | ||
993 | - offset += UNITS_PER_WORD; | ||
994 | - } | ||
995 | + ALLOCATE_GPR_SLOT (regno); | ||
996 | + | ||
997 | +#undef ALLOCATE_GPR_SLOT | ||
998 | |||
999 | HOST_WIDE_INT max_int_offset = offset; | ||
1000 | offset = ROUND_UP (offset, STACK_BOUNDARY / BITS_PER_UNIT); | ||
1001 | @@ -5508,16 +5519,9 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
1002 | HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; | ||
1003 | HOST_WIDE_INT byte_sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; | ||
1004 | gcc_assert (multiple_p (poly_size, byte_sp_alignment)); | ||
1005 | - /* When doing the final adjustment for the outgoing argument size we can't | ||
1006 | - assume that LR was saved at position 0. So subtract it's offset from the | ||
1007 | - ABI safe buffer so that we don't accidentally allow an adjustment that | ||
1008 | - would result in an allocation larger than the ABI buffer without | ||
1009 | - probing. */ | ||
1010 | HOST_WIDE_INT min_probe_threshold | ||
1011 | = final_adjustment_p | ||
1012 | - ? (guard_used_by_caller | ||
1013 | - + byte_sp_alignment | ||
1014 | - - cfun->machine->frame.reg_offset[LR_REGNUM]) | ||
1015 | + ? guard_used_by_caller + byte_sp_alignment | ||
1016 | : guard_size - guard_used_by_caller; | ||
1017 | |||
1018 | poly_int64 frame_size = cfun->machine->frame.frame_size; | ||
1019 | @@ -5697,8 +5701,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
1020 | if (final_adjustment_p && rounded_size != 0) | ||
1021 | min_probe_threshold = 0; | ||
1022 | /* If doing a small final adjustment, we always probe at offset 0. | ||
1023 | - This is done to avoid issues when LR is not at position 0 or when | ||
1024 | - the final adjustment is smaller than the probing offset. */ | ||
1025 | + This is done to avoid issues when the final adjustment is smaller | ||
1026 | + than the probing offset. */ | ||
1027 | else if (final_adjustment_p && rounded_size == 0) | ||
1028 | residual_probe_offset = 0; | ||
1029 | |||
1030 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
1031 | new file mode 100644 | ||
1032 | index 00000000000..82447d20fff | ||
1033 | --- /dev/null | ||
1034 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
1035 | @@ -0,0 +1,100 @@ | ||
1036 | +/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */ | ||
1037 | +/* { dg-final { check-function-bodies "**" "" } } */ | ||
1038 | + | ||
1039 | +void f(int, ...); | ||
1040 | +void g(); | ||
1041 | + | ||
1042 | +/* | ||
1043 | +** test1: | ||
1044 | +** ... | ||
1045 | +** str x30, \[sp\] | ||
1046 | +** sub sp, sp, #4064 | ||
1047 | +** str xzr, \[sp\] | ||
1048 | +** cbnz w0, .* | ||
1049 | +** bl g | ||
1050 | +** ... | ||
1051 | +** str x26, \[sp, #?4128\] | ||
1052 | +** ... | ||
1053 | +*/ | ||
1054 | +int test1(int z) { | ||
1055 | + __uint128_t x = 0; | ||
1056 | + int y[0x400]; | ||
1057 | + if (z) | ||
1058 | + { | ||
1059 | + asm volatile ("" ::: | ||
1060 | + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); | ||
1061 | + f(0, 0, 0, 0, 0, 0, 0, &y, | ||
1062 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1063 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1064 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1065 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1066 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1067 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1068 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1069 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1070 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1071 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1072 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1073 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1074 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1075 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1076 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1077 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x); | ||
1078 | + } | ||
1079 | + g(); | ||
1080 | + return 1; | ||
1081 | +} | ||
1082 | + | ||
1083 | +/* | ||
1084 | +** test2: | ||
1085 | +** ... | ||
1086 | +** str x30, \[sp\] | ||
1087 | +** sub sp, sp, #1040 | ||
1088 | +** str xzr, \[sp\] | ||
1089 | +** cbnz w0, .* | ||
1090 | +** bl g | ||
1091 | +** ... | ||
1092 | +*/ | ||
1093 | +int test2(int z) { | ||
1094 | + __uint128_t x = 0; | ||
1095 | + int y[0x400]; | ||
1096 | + if (z) | ||
1097 | + { | ||
1098 | + asm volatile ("" ::: | ||
1099 | + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); | ||
1100 | + f(0, 0, 0, 0, 0, 0, 0, &y, | ||
1101 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1102 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1103 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1104 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1105 | + x); | ||
1106 | + } | ||
1107 | + g(); | ||
1108 | + return 1; | ||
1109 | +} | ||
1110 | + | ||
1111 | +/* | ||
1112 | +** test3: | ||
1113 | +** ... | ||
1114 | +** str x30, \[sp\] | ||
1115 | +** sub sp, sp, #1024 | ||
1116 | +** cbnz w0, .* | ||
1117 | +** bl g | ||
1118 | +** ... | ||
1119 | +*/ | ||
1120 | +int test3(int z) { | ||
1121 | + __uint128_t x = 0; | ||
1122 | + int y[0x400]; | ||
1123 | + if (z) | ||
1124 | + { | ||
1125 | + asm volatile ("" ::: | ||
1126 | + "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); | ||
1127 | + f(0, 0, 0, 0, 0, 0, 0, &y, | ||
1128 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1129 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1130 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, | ||
1131 | + x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); | ||
1132 | + } | ||
1133 | + g(); | ||
1134 | + return 1; | ||
1135 | +} | ||
1136 | -- | ||
1137 | 2.34.1 | ||
1138 | |||
1139 | |||
1140 | From f2684e63652bb251d22c79e40081c646df1f36b6 Mon Sep 17 00:00:00 2001 | ||
1141 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
1142 | Date: Tue, 8 Aug 2023 01:57:26 +0100 | ||
1143 | Subject: [PATCH 09/10] aarch64: Simplify probe of final frame allocation | ||
1144 | |||
1145 | Previous patches ensured that the final frame allocation only needs | ||
1146 | a probe when the size is strictly greater than 1KiB. It's therefore | ||
1147 | safe to use the normal 1024 probe offset in all cases. | ||
1148 | |||
1149 | The main motivation for doing this is to simplify the code and | ||
1150 | remove the number of special cases. | ||
1151 | |||
1152 | gcc/ | ||
1153 | * config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space): | ||
1154 | Always probe the residual allocation at offset 1024, asserting | ||
1155 | that that is in range. | ||
1156 | |||
1157 | gcc/testsuite/ | ||
1158 | * gcc.target/aarch64/stack-check-prologue-17.c: Expect the probe | ||
1159 | to be at offset 1024 rather than offset 0. | ||
1160 | * gcc.target/aarch64/stack-check-prologue-18.c: Likewise. | ||
1161 | --- | ||
1162 | gcc/config/aarch64/aarch64.c | 12 ++++-------- | ||
1163 | .../gcc.target/aarch64/stack-check-prologue-17.c | 2 +- | ||
1164 | .../gcc.target/aarch64/stack-check-prologue-18.c | 7 +++++-- | ||
1165 | 3 files changed, 10 insertions(+), 11 deletions(-) | ||
1166 | |||
1167 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
1168 | index 1e8467fdd03..705f719a2ea 100644 | ||
1169 | --- a/gcc/config/aarch64/aarch64.c | ||
1170 | +++ b/gcc/config/aarch64/aarch64.c | ||
1171 | @@ -5695,16 +5695,12 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
1172 | are still safe. */ | ||
1173 | if (residual) | ||
1174 | { | ||
1175 | - HOST_WIDE_INT residual_probe_offset = guard_used_by_caller; | ||
1176 | + gcc_assert (guard_used_by_caller + byte_sp_alignment <= size); | ||
1177 | + | ||
1178 | /* If we're doing final adjustments, and we've done any full page | ||
1179 | allocations then any residual needs to be probed. */ | ||
1180 | if (final_adjustment_p && rounded_size != 0) | ||
1181 | min_probe_threshold = 0; | ||
1182 | - /* If doing a small final adjustment, we always probe at offset 0. | ||
1183 | - This is done to avoid issues when the final adjustment is smaller | ||
1184 | - than the probing offset. */ | ||
1185 | - else if (final_adjustment_p && rounded_size == 0) | ||
1186 | - residual_probe_offset = 0; | ||
1187 | |||
1188 | aarch64_sub_sp (temp1, temp2, residual, frame_related_p); | ||
1189 | if (residual >= min_probe_threshold) | ||
1190 | @@ -5715,8 +5711,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, | ||
1191 | HOST_WIDE_INT_PRINT_DEC " bytes, probing will be required." | ||
1192 | "\n", residual); | ||
1193 | |||
1194 | - emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, | ||
1195 | - residual_probe_offset)); | ||
1196 | + emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, | ||
1197 | + guard_used_by_caller)); | ||
1198 | emit_insn (gen_blockage ()); | ||
1199 | } | ||
1200 | } | ||
1201 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
1202 | index 0d8a25d73a2..f0ec1389771 100644 | ||
1203 | --- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
1204 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | ||
1205 | @@ -33,7 +33,7 @@ int test1(int z) { | ||
1206 | ** ... | ||
1207 | ** str x30, \[sp\] | ||
1208 | ** sub sp, sp, #1040 | ||
1209 | -** str xzr, \[sp\] | ||
1210 | +** str xzr, \[sp, #?1024\] | ||
1211 | ** cbnz w0, .* | ||
1212 | ** bl g | ||
1213 | ** ... | ||
1214 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
1215 | index 82447d20fff..71d33ba34e9 100644 | ||
1216 | --- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
1217 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | ||
1218 | @@ -8,8 +8,9 @@ void g(); | ||
1219 | ** test1: | ||
1220 | ** ... | ||
1221 | ** str x30, \[sp\] | ||
1222 | +** ... | ||
1223 | ** sub sp, sp, #4064 | ||
1224 | -** str xzr, \[sp\] | ||
1225 | +** str xzr, \[sp, #?1024\] | ||
1226 | ** cbnz w0, .* | ||
1227 | ** bl g | ||
1228 | ** ... | ||
1229 | @@ -49,8 +50,9 @@ int test1(int z) { | ||
1230 | ** test2: | ||
1231 | ** ... | ||
1232 | ** str x30, \[sp\] | ||
1233 | +** ... | ||
1234 | ** sub sp, sp, #1040 | ||
1235 | -** str xzr, \[sp\] | ||
1236 | +** str xzr, \[sp, #?1024\] | ||
1237 | ** cbnz w0, .* | ||
1238 | ** bl g | ||
1239 | ** ... | ||
1240 | @@ -77,6 +79,7 @@ int test2(int z) { | ||
1241 | ** test3: | ||
1242 | ** ... | ||
1243 | ** str x30, \[sp\] | ||
1244 | +** ... | ||
1245 | ** sub sp, sp, #1024 | ||
1246 | ** cbnz w0, .* | ||
1247 | ** bl g | ||
1248 | -- | ||
1249 | 2.34.1 | ||
1250 | |||
1251 | |||
1252 | From bf3eeaa0182a92987570d9c787bd45079eebf528 Mon Sep 17 00:00:00 2001 | ||
1253 | From: Richard Sandiford <richard.sandiford@arm.com> | ||
1254 | Date: Thu, 15 Jun 2023 19:16:52 +0100 | ||
1255 | Subject: [PATCH 10/10] aarch64: Make stack smash canary protect saved | ||
1256 | registers | ||
1257 | |||
1258 | AArch64 normally puts the saved registers near the bottom of the frame, | ||
1259 | immediately above any dynamic allocations. But this means that a | ||
1260 | stack-smash attack on those dynamic allocations could overwrite the | ||
1261 | saved registers without needing to reach as far as the stack smash | ||
1262 | canary. | ||
1263 | |||
1264 | The same thing could also happen for variable-sized arguments that are | ||
1265 | passed by value, since those are allocated before a call and popped on | ||
1266 | return. | ||
1267 | |||
1268 | This patch avoids that by putting the locals (and thus the canary) below | ||
1269 | the saved registers when stack smash protection is active. | ||
1270 | |||
1271 | The patch fixes CVE-2023-4039. | ||
1272 | |||
1273 | gcc/ | ||
1274 | * config/aarch64/aarch64.c (aarch64_save_regs_above_locals_p): | ||
1275 | New function. | ||
1276 | (aarch64_layout_frame): Use it to decide whether locals should | ||
1277 | go above or below the saved registers. | ||
1278 | (aarch64_expand_prologue): Update stack layout comment. | ||
1279 | Emit a stack tie after the final adjustment. | ||
1280 | |||
1281 | gcc/testsuite/ | ||
1282 | * gcc.target/aarch64/stack-protector-8.c: New test. | ||
1283 | * gcc.target/aarch64/stack-protector-9.c: Likewise. | ||
1284 | --- | ||
1285 | gcc/config/aarch64/aarch64.c | 46 +++++++++++++-- | ||
1286 | .../gcc.target/aarch64/stack-protector-8.c | 58 +++++++++++++++++++ | ||
1287 | .../gcc.target/aarch64/stack-protector-9.c | 33 +++++++++++ | ||
1288 | 3 files changed, 133 insertions(+), 4 deletions(-) | ||
1289 | create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-8.c | ||
1290 | create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-9.c | ||
1291 | |||
1292 | diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c | ||
1293 | index 705f719a2ea..3d094214fac 100644 | ||
1294 | --- a/gcc/config/aarch64/aarch64.c | ||
1295 | +++ b/gcc/config/aarch64/aarch64.c | ||
1296 | @@ -4622,6 +4622,20 @@ aarch64_needs_frame_chain (void) | ||
1297 | return aarch64_use_frame_pointer; | ||
1298 | } | ||
1299 | |||
1300 | +/* Return true if the current function should save registers above | ||
1301 | + the locals area, rather than below it. */ | ||
1302 | + | ||
1303 | +static bool | ||
1304 | +aarch64_save_regs_above_locals_p () | ||
1305 | +{ | ||
1306 | + /* When using stack smash protection, make sure that the canary slot | ||
1307 | + comes between the locals and the saved registers. Otherwise, | ||
1308 | + it would be possible for a carefully sized smash attack to change | ||
1309 | + the saved registers (particularly LR and FP) without reaching the | ||
1310 | + canary. */ | ||
1311 | + return crtl->stack_protect_guard; | ||
1312 | +} | ||
1313 | + | ||
1314 | /* Mark the registers that need to be saved by the callee and calculate | ||
1315 | the size of the callee-saved registers area and frame record (both FP | ||
1316 | and LR may be omitted). */ | ||
1317 | @@ -4686,6 +4700,16 @@ aarch64_layout_frame (void) | ||
1318 | |||
1319 | cfun->machine->frame.bytes_below_hard_fp = crtl->outgoing_args_size; | ||
1320 | |||
1321 | + bool regs_at_top_p = aarch64_save_regs_above_locals_p (); | ||
1322 | + | ||
1323 | + if (regs_at_top_p) | ||
1324 | + { | ||
1325 | + cfun->machine->frame.bytes_below_hard_fp += get_frame_size (); | ||
1326 | + cfun->machine->frame.bytes_below_hard_fp | ||
1327 | + = aligned_upper_bound (cfun->machine->frame.bytes_below_hard_fp, | ||
1328 | + STACK_BOUNDARY / BITS_PER_UNIT); | ||
1329 | + } | ||
1330 | + | ||
1331 | #define ALLOCATE_GPR_SLOT(REGNO) \ | ||
1332 | do \ | ||
1333 | { \ | ||
1334 | @@ -4758,9 +4782,11 @@ aarch64_layout_frame (void) | ||
1335 | HOST_WIDE_INT varargs_and_saved_regs_size | ||
1336 | = offset + cfun->machine->frame.saved_varargs_size; | ||
1337 | |||
1338 | + cfun->machine->frame.bytes_above_hard_fp = varargs_and_saved_regs_size; | ||
1339 | + if (!regs_at_top_p) | ||
1340 | + cfun->machine->frame.bytes_above_hard_fp += get_frame_size (); | ||
1341 | cfun->machine->frame.bytes_above_hard_fp | ||
1342 | - = aligned_upper_bound (varargs_and_saved_regs_size | ||
1343 | - + get_frame_size (), | ||
1344 | + = aligned_upper_bound (cfun->machine->frame.bytes_above_hard_fp, | ||
1345 | STACK_BOUNDARY / BITS_PER_UNIT); | ||
1346 | |||
1347 | /* Both these values are already aligned. */ | ||
1348 | @@ -4772,6 +4798,9 @@ aarch64_layout_frame (void) | ||
1349 | |||
1350 | cfun->machine->frame.bytes_above_locals | ||
1351 | = cfun->machine->frame.saved_varargs_size; | ||
1352 | + if (regs_at_top_p) | ||
1353 | + cfun->machine->frame.bytes_above_locals | ||
1354 | + += cfun->machine->frame.saved_regs_size; | ||
1355 | |||
1356 | cfun->machine->frame.initial_adjust = 0; | ||
1357 | cfun->machine->frame.final_adjust = 0; | ||
1358 | @@ -5764,10 +5793,10 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg, | ||
1359 | | for register varargs | | ||
1360 | | | | ||
1361 | +-------------------------------+ | ||
1362 | - | local variables | <-- frame_pointer_rtx | ||
1363 | + | local variables (1) | <-- frame_pointer_rtx | ||
1364 | | | | ||
1365 | +-------------------------------+ | ||
1366 | - | padding | \ | ||
1367 | + | padding (1) | \ | ||
1368 | +-------------------------------+ | | ||
1369 | | callee-saved registers | | frame.saved_regs_size | ||
1370 | +-------------------------------+ | | ||
1371 | @@ -5775,6 +5804,10 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg, | ||
1372 | +-------------------------------+ | | ||
1373 | | FP' | / <- hard_frame_pointer_rtx (aligned) | ||
1374 | +-------------------------------+ | ||
1375 | + | local variables (2) | | ||
1376 | + +-------------------------------+ | ||
1377 | + | padding (2) | | ||
1378 | + +-------------------------------+ | ||
1379 | | dynamic allocation | | ||
1380 | +-------------------------------+ | ||
1381 | | padding | | ||
1382 | @@ -5784,6 +5817,9 @@ aarch64_add_cfa_expression (rtx_insn *insn, unsigned int reg, | ||
1383 | +-------------------------------+ | ||
1384 | | | <-- stack_pointer_rtx (aligned) | ||
1385 | |||
1386 | + The regions marked (1) and (2) are mutually exclusive. (2) is used | ||
1387 | + when aarch64_save_regs_above_locals_p is true. | ||
1388 | + | ||
1389 | Dynamic stack allocations via alloca() decrease stack_pointer_rtx | ||
1390 | but leave frame_pointer_rtx and hard_frame_pointer_rtx | ||
1391 | unchanged. | ||
1392 | @@ -5937,6 +5973,8 @@ aarch64_expand_prologue (void) | ||
1393 | that is assumed by the called. */ | ||
1394 | aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust, | ||
1395 | !frame_pointer_needed, true); | ||
1396 | + if (emit_frame_chain && maybe_ne (final_adjust, 0)) | ||
1397 | + emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); | ||
1398 | } | ||
1399 | |||
1400 | /* Return TRUE if we can use a simple_return insn. | ||
1401 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c | ||
1402 | new file mode 100644 | ||
1403 | index 00000000000..c5e7deef6c1 | ||
1404 | --- /dev/null | ||
1405 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c | ||
1406 | @@ -0,0 +1,58 @@ | ||
1407 | +/* { dg-options " -O -fstack-protector-strong -mstack-protector-guard=sysreg -mstack-protector-guard-reg=tpidr2_el0 -mstack-protector-guard-offset=16" } */ | ||
1408 | +/* { dg-final { check-function-bodies "**" "" } } */ | ||
1409 | + | ||
1410 | +void g(void *); | ||
1411 | + | ||
1412 | +/* | ||
1413 | +** test1: | ||
1414 | +** sub sp, sp, #288 | ||
1415 | +** stp x29, x30, \[sp, #?272\] | ||
1416 | +** add x29, sp, #?272 | ||
1417 | +** mrs (x[0-9]+), tpidr2_el0 | ||
1418 | +** ldr (x[0-9]+), \[\1, #?16\] | ||
1419 | +** str \2, \[sp, #?264\] | ||
1420 | +** mov \2, *0 | ||
1421 | +** add x0, sp, #?8 | ||
1422 | +** bl g | ||
1423 | +** ... | ||
1424 | +** mrs .* | ||
1425 | +** ... | ||
1426 | +** bne .* | ||
1427 | +** ... | ||
1428 | +** ldp x29, x30, \[sp, #?272\] | ||
1429 | +** add sp, sp, #?288 | ||
1430 | +** ret | ||
1431 | +** bl __stack_chk_fail | ||
1432 | +*/ | ||
1433 | +int test1() { | ||
1434 | + int y[0x40]; | ||
1435 | + g(y); | ||
1436 | + return 1; | ||
1437 | +} | ||
1438 | + | ||
1439 | +/* | ||
1440 | +** test2: | ||
1441 | +** stp x29, x30, \[sp, #?-16\]! | ||
1442 | +** mov x29, sp | ||
1443 | +** sub sp, sp, #1040 | ||
1444 | +** mrs (x[0-9]+), tpidr2_el0 | ||
1445 | +** ldr (x[0-9]+), \[\1, #?16\] | ||
1446 | +** str \2, \[sp, #?1032\] | ||
1447 | +** mov \2, *0 | ||
1448 | +** add x0, sp, #?8 | ||
1449 | +** bl g | ||
1450 | +** ... | ||
1451 | +** mrs .* | ||
1452 | +** ... | ||
1453 | +** bne .* | ||
1454 | +** ... | ||
1455 | +** add sp, sp, #?1040 | ||
1456 | +** ldp x29, x30, \[sp\], #?16 | ||
1457 | +** ret | ||
1458 | +** bl __stack_chk_fail | ||
1459 | +*/ | ||
1460 | +int test2() { | ||
1461 | + int y[0x100]; | ||
1462 | + g(y); | ||
1463 | + return 1; | ||
1464 | +} | ||
1465 | diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c | ||
1466 | new file mode 100644 | ||
1467 | index 00000000000..58f322aa480 | ||
1468 | --- /dev/null | ||
1469 | +++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c | ||
1470 | @@ -0,0 +1,33 @@ | ||
1471 | +/* { dg-options "-O2 -mcpu=neoverse-v1 -fstack-protector-all" } */ | ||
1472 | +/* { dg-final { check-function-bodies "**" "" } } */ | ||
1473 | + | ||
1474 | +/* | ||
1475 | +** main: | ||
1476 | +** ... | ||
1477 | +** stp x29, x30, \[sp, #?-[0-9]+\]! | ||
1478 | +** ... | ||
1479 | +** sub sp, sp, #[0-9]+ | ||
1480 | +** ... | ||
1481 | +** str x[0-9]+, \[x29, #?-8\] | ||
1482 | +** ... | ||
1483 | +*/ | ||
1484 | +int f(const char *); | ||
1485 | +void g(void *); | ||
1486 | +int main(int argc, char* argv[]) | ||
1487 | +{ | ||
1488 | + int a; | ||
1489 | + int b; | ||
1490 | + char c[2+f(argv[1])]; | ||
1491 | + int d[0x100]; | ||
1492 | + char y; | ||
1493 | + | ||
1494 | + y=42; a=4; b=10; | ||
1495 | + c[0] = 'h'; c[1] = '\0'; | ||
1496 | + | ||
1497 | + c[f(argv[2])] = '\0'; | ||
1498 | + | ||
1499 | + __builtin_printf("%d %d\n%s\n", a, b, c); | ||
1500 | + g(d); | ||
1501 | + | ||
1502 | + return 0; | ||
1503 | +} | ||
1504 | -- | ||
1505 | 2.34.1 | ||
1506 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-common.inc b/meta/recipes-devtools/gcc/gcc-common.inc index 3dcfdf835f..69a3536965 100644 --- a/meta/recipes-devtools/gcc/gcc-common.inc +++ b/meta/recipes-devtools/gcc/gcc-common.inc | |||
@@ -1,5 +1,6 @@ | |||
1 | SUMMARY = "GNU cc and gcc C compilers" | 1 | SUMMARY = "GNU cc and gcc C compilers" |
2 | HOMEPAGE = "http://www.gnu.org/software/gcc/" | 2 | HOMEPAGE = "http://www.gnu.org/software/gcc/" |
3 | DESCRIPTION = "The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, Go, and D, as well as libraries for these languages (libstdc++,...). GCC was originally written as the compiler for the GNU operating system." | ||
3 | SECTION = "devel" | 4 | SECTION = "devel" |
4 | LICENSE = "GPL" | 5 | LICENSE = "GPL" |
5 | 6 | ||
@@ -99,7 +100,7 @@ BINV = "${PV}" | |||
99 | #S = "${WORKDIR}/gcc-${PV}" | 100 | #S = "${WORKDIR}/gcc-${PV}" |
100 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}" | 101 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}" |
101 | 102 | ||
102 | B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}" | 103 | B ?= "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}" |
103 | 104 | ||
104 | target_includedir ?= "${includedir}" | 105 | target_includedir ?= "${includedir}" |
105 | target_libdir ?= "${libdir}" | 106 | target_libdir ?= "${libdir}" |
diff --git a/meta/recipes-devtools/gcc/gcc-cross-canadian_9.3.bb b/meta/recipes-devtools/gcc/gcc-cross-canadian_9.5.bb index bf53c5cd78..bf53c5cd78 100644 --- a/meta/recipes-devtools/gcc/gcc-cross-canadian_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-cross-canadian_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-cross_9.3.bb b/meta/recipes-devtools/gcc/gcc-cross_9.5.bb index b43cca0c52..b43cca0c52 100644 --- a/meta/recipes-devtools/gcc/gcc-cross_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-cross_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-crosssdk_9.3.bb b/meta/recipes-devtools/gcc/gcc-crosssdk_9.5.bb index 40a6c4feff..40a6c4feff 100644 --- a/meta/recipes-devtools/gcc/gcc-crosssdk_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-crosssdk_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-runtime_9.3.bb b/meta/recipes-devtools/gcc/gcc-runtime_9.5.bb index dd430b57eb..dd430b57eb 100644 --- a/meta/recipes-devtools/gcc/gcc-runtime_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-runtime_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-sanitizers_9.3.bb b/meta/recipes-devtools/gcc/gcc-sanitizers_9.5.bb index f3c7058114..f3c7058114 100644 --- a/meta/recipes-devtools/gcc/gcc-sanitizers_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-sanitizers_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-shared-source.inc b/meta/recipes-devtools/gcc/gcc-shared-source.inc index aac4b49313..4baf7874d2 100644 --- a/meta/recipes-devtools/gcc/gcc-shared-source.inc +++ b/meta/recipes-devtools/gcc/gcc-shared-source.inc | |||
@@ -9,3 +9,6 @@ SRC_URI = "" | |||
9 | 9 | ||
10 | do_configure[depends] += "gcc-source-${PV}:do_preconfigure" | 10 | do_configure[depends] += "gcc-source-${PV}:do_preconfigure" |
11 | do_populate_lic[depends] += "gcc-source-${PV}:do_unpack" | 11 | do_populate_lic[depends] += "gcc-source-${PV}:do_unpack" |
12 | |||
13 | # patch is available via gcc-source recipe | ||
14 | CVE_CHECK_WHITELIST += "CVE-2023-4039" | ||
diff --git a/meta/recipes-devtools/gcc/gcc-source.inc b/meta/recipes-devtools/gcc/gcc-source.inc index 03bab97815..224b7778ef 100644 --- a/meta/recipes-devtools/gcc/gcc-source.inc +++ b/meta/recipes-devtools/gcc/gcc-source.inc | |||
@@ -18,6 +18,7 @@ INHIBIT_DEFAULT_DEPS = "1" | |||
18 | DEPENDS = "" | 18 | DEPENDS = "" |
19 | PACKAGES = "" | 19 | PACKAGES = "" |
20 | 20 | ||
21 | B = "${WORKDIR}/build" | ||
21 | 22 | ||
22 | # This needs to be Python to avoid lots of shell variables becoming dependencies. | 23 | # This needs to be Python to avoid lots of shell variables becoming dependencies. |
23 | python do_preconfigure () { | 24 | python do_preconfigure () { |
diff --git a/meta/recipes-devtools/gcc/gcc-source_9.3.bb b/meta/recipes-devtools/gcc/gcc-source_9.5.bb index b890fa33ea..b890fa33ea 100644 --- a/meta/recipes-devtools/gcc/gcc-source_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc-source_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc_9.3.bb b/meta/recipes-devtools/gcc/gcc_9.5.bb index 7d93590588..7d93590588 100644 --- a/meta/recipes-devtools/gcc/gcc_9.3.bb +++ b/meta/recipes-devtools/gcc/gcc_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgcc-initial_9.3.bb b/meta/recipes-devtools/gcc/libgcc-initial_9.5.bb index 0c698c26ec..0c698c26ec 100644 --- a/meta/recipes-devtools/gcc/libgcc-initial_9.3.bb +++ b/meta/recipes-devtools/gcc/libgcc-initial_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgcc_9.3.bb b/meta/recipes-devtools/gcc/libgcc_9.5.bb index ea210a1130..ea210a1130 100644 --- a/meta/recipes-devtools/gcc/libgcc_9.3.bb +++ b/meta/recipes-devtools/gcc/libgcc_9.5.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgfortran_9.3.bb b/meta/recipes-devtools/gcc/libgfortran_9.5.bb index 71dd8b4bdc..71dd8b4bdc 100644 --- a/meta/recipes-devtools/gcc/libgfortran_9.3.bb +++ b/meta/recipes-devtools/gcc/libgfortran_9.5.bb | |||