On May 21, 2025, Richard Sandiford <[email protected]> wrote:
> I think this one shows a deeper issue, though. -fsanitize=shadow-call-stack
> is currently hardcoded to use x18:
Oh, indeed!
> and I assume this usage will be incompatible with the TCB usage.
> So I think instead we should emit a sorry() if -fsanitize=shadow-call-stack
> is used on VxWorks.
Agreed. Here's a revised version that implements sorry(), introduces
TARGET_OS_USES_R18 to guard that and the fixed-register setting, and
skips the tests that exercise -fsanitize-shadow-call-stack.
Tested with gcc-14 on aarch64-vxworks7r2. Ok to install?
[aarch64] [vxworks] mark x18 as fixed, adjust tests
VxWorks uses x18 as the TCB, so STATIC_CHAIN_REGNUM has long been set
(in gcc/config/aarch64/aarch64-vxworks.h) to use x9 instead.
This patch marks x18 as fixed if the newly-introduced
TARGET_OS_USES_R18 is defined, so that it is not chosen by the
register allocator, rejects -fsanitize-shadow-call-stack due to the
register conflict, and adjusts tests that depend on x18 or on the
static chain register.
for gcc/ChangeLog
* config/aarch64/aarch64-vxworks.h (TARGET_OS_USES_R18): Define.
Update comments.
* config/aarch64/aarch64.c (aarch64_conditional_register_usage):
Mark x18 as fixed on VxWorks.
(aarch64_override_options_internal): Issue sorry message on
-fsanitize=shadow-call-stack if TARGET_OS_USES_R18.
for gcc/testsuite/ChangeLog
* gcc.dg/cwsc1.c (CHAIN, aarch64): x9 instead x18 for __vxworks.
* gcc.target/aarch64/reg-alloc-4.c: Drop x18-assigned asm
operand on vxworks.
* gcc.target/aarch64/shadow_call_stack_1.c: Don't expect
-ffixed-x18 error on vxworks, but rather the sorry message.
* gcc.target/aarch64/shadow_call_stack_2.c: Skip on vxworks.
* gcc.target/aarch64/shadow_call_stack_3.c: Likewise.
* gcc.target/aarch64/shadow_call_stack_4.c: Likewise.
* gcc.target/aarch64/shadow_call_stack_5.c: Likewise.
* gcc.target/aarch64/shadow_call_stack_6.c: Likewise.
* gcc.target/aarch64/shadow_call_stack_7.c: Likewise.
* gcc.target/aarch64/shadow_call_stack_8.c: Likewise.
* gcc.target/aarch64/stack-check-prologue-19.c: Likewise.
* gcc.target/aarch64/stack-check-prologue-20.c: Likewise.
---
gcc/config/aarch64/aarch64-vxworks.h | 7 +++----
gcc/config/aarch64/aarch64.cc | 21 +++++++++++++++++---
gcc/testsuite/gcc.dg/cwsc1.c | 6 +++++-
gcc/testsuite/gcc.target/aarch64/reg-alloc-4.c | 2 ++
.../gcc.target/aarch64/shadow_call_stack_1.c | 4 +++-
.../gcc.target/aarch64/shadow_call_stack_2.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_3.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_4.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_5.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_6.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_7.c | 1 +
.../gcc.target/aarch64/shadow_call_stack_8.c | 1 +
.../gcc.target/aarch64/stack-check-prologue-19.c | 1 +
.../gcc.target/aarch64/stack-check-prologue-20.c | 1 +
14 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-vxworks.h
b/gcc/config/aarch64/aarch64-vxworks.h
index 41adada9b1de3..7b4da934b6083 100644
--- a/gcc/config/aarch64/aarch64-vxworks.h
+++ b/gcc/config/aarch64/aarch64-vxworks.h
@@ -66,9 +66,8 @@ along with GCC; see the file COPYING3. If not see
#define VXWORKS_PERSONALITY "llvm"
/* VxWorks uses R18 as a TCB pointer. We must pick something else as
- the static chain and R18 needs to be claimed "fixed". Until we
- arrange to override the common parts of the port family to
- acknowledge the latter, configure --with-specs="-ffixed-r18". */
+ the static chain and R18 needs to be claimed "fixed" (TARGET_OS_USES_R18
+ does that in aarch64_conditional_register_usage). */
#undef STATIC_CHAIN_REGNUM
#define STATIC_CHAIN_REGNUM 9
-
+#define TARGET_OS_USES_R18
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 1da615c8955a4..ec9da0ed60c6f 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18819,9 +18819,16 @@ aarch64_override_options_internal (struct gcc_options
*opts)
aarch64_stack_protector_guard_offset = offs;
}
- if ((flag_sanitize & SANITIZE_SHADOW_CALL_STACK)
- && !fixed_regs[R18_REGNUM])
- error ("%<-fsanitize=shadow-call-stack%> requires %<-ffixed-x18%>");
+ if ((flag_sanitize & SANITIZE_SHADOW_CALL_STACK))
+ {
+ if (!fixed_regs[R18_REGNUM])
+ error ("%<-fsanitize=shadow-call-stack%> requires %<-ffixed-x18%>");
+#ifdef TARGET_OS_USES_R18
+ else
+ sorry ("%<-fsanitize=shadow-call-stack%> conflicts with the use of"
+ " register x18 by the target operating system");
+#endif
+ }
aarch64_feature_flags isa_flags = aarch64_get_isa_flags (opts);
if ((isa_flags & (AARCH64_FL_SM_ON | AARCH64_FL_ZA_ON))
@@ -22039,6 +22046,14 @@ aarch64_conditional_register_usage (void)
fixed_regs[SPECULATION_SCRATCH_REGNUM] = 1;
call_used_regs[SPECULATION_SCRATCH_REGNUM] = 1;
}
+
+#ifdef TARGET_OS_USES_R18
+ /* R18 is the STATIC_CHAIN_REGNUM on most aarch64 ports, but VxWorks
+ uses it as the TCB, so aarch64-vxworks.h overrides
+ STATIC_CHAIN_REGNUM, and here we mark R18 as fixed. */
+ fixed_regs[R18_REGNUM] = 1;
+ call_used_regs[R18_REGNUM] = 1;
+#endif
}
/* Implement TARGET_MEMBER_TYPE_FORCES_BLK. */
diff --git a/gcc/testsuite/gcc.dg/cwsc1.c b/gcc/testsuite/gcc.dg/cwsc1.c
index e793e26116af4..cccf4139c35b5 100644
--- a/gcc/testsuite/gcc.dg/cwsc1.c
+++ b/gcc/testsuite/gcc.dg/cwsc1.c
@@ -6,7 +6,11 @@
#elif defined(__i386__)
# define CHAIN "%ecx"
#elif defined(__aarch64__)
-# define CHAIN "x18"
+# if defined __vxworks
+# define CHAIN "x9"
+# else
+# define CHAIN "x18"
+# endif
#elif defined(__alpha__)
# define CHAIN "$1"
#elif defined(__arm__)
diff --git a/gcc/testsuite/gcc.target/aarch64/reg-alloc-4.c
b/gcc/testsuite/gcc.target/aarch64/reg-alloc-4.c
index ceb6f50de2dc3..0576dc27eb072 100644
--- a/gcc/testsuite/gcc.target/aarch64/reg-alloc-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/reg-alloc-4.c
@@ -61,7 +61,9 @@ foo (volatile struct L *head, int inc)
"r" (inner->next), /* x15 */
"r" (inner->next), /* x16 */
"r" (inner->next), /* x17 */
+#ifndef __vxworks /* x18 is a fixed register on VxWorks, used for the TCB. */
"r" (inner->next), /* x18 */
+#endif
"r" (inner->next) : /* x30 */
"x19", "x20", "x21", "x22", "x23",
"x24", "x25", "x26", "x27", "x28");
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_1.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_1.c
index ab68d6e848252..fb19bd4ecb4f6 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_1.c
@@ -3,4 +3,6 @@
int i;
-/* { dg-error "'-fsanitize=shadow-call-stack' requires '-ffixed-x18'" ""
{target "aarch64*-*-*" } 0 } */
+/* aarch64-*-vxworks has x18 as a fixed register. */
+/* { dg-error "'-fsanitize=shadow-call-stack' requires '-ffixed-x18'" "" {
target { aarch64*-*-* && { ! aarch64-*-vxworks* } } } 0 } */
+/* { dg-message "sorry, unimplemented: '-fsanitize=shadow-call-stack'
conflicts with the use of register x18" "" { target { aarch64-*-vxworks* } } 0
} */
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_2.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_2.c
index b5139a245597b..2c381cd796298 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=shadow-call-stack -ffixed-x18 -fexceptions" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
int i;
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_3.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_3.c
index b88e490f3ae71..95d41e722a002 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_3.c
@@ -3,6 +3,7 @@
/* scs_pop: ldr x30, [x18, #-8]! */
/* { dg-do compile } */
/* { dg-options "-O2 -fsanitize=shadow-call-stack -ffixed-x18 -fno-exceptions"
} */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_4.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_4.c
index f63169340e125..1e84ab630f98a 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_4.c
@@ -3,6 +3,7 @@
/* scs_pop: ldr x30, [x18, #-8]! */
/* { dg-do compile } */
/* { dg-options "-O2 -fno-omit-frame-pointer -fsanitize=shadow-call-stack
-ffixed-x18 -fno-exceptions" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
int foo (int);
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_5.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_5.c
index d7f82984ff533..e76de4796f933 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_5.c
@@ -8,6 +8,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fno-omit-frame-pointer -fsanitize=shadow-call-stack
-fno-exceptions -ffixed-x18 --save-temps -fno-stack-protector" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
#include "test_frame_common.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_6.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_6.c
index 8d088aecc202e..35093757f7c60 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_6.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_6.c
@@ -8,6 +8,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fomit-frame-pointer -fsanitize=shadow-call-stack
-fno-exceptions -ffixed-x18 --save-temps -fno-stack-protector" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
#include "test_frame_common.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_7.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_7.c
index a2f376e0091c2..9ddd71a203a7b 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_7.c
@@ -8,6 +8,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fomit-frame-pointer -fsanitize=shadow-call-stack
-fno-exceptions -ffixed-x18 --save-temps -fno-stack-protector" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
#include "test_frame_common.h"
diff --git a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_8.c
b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_8.c
index 5162cbb391757..be8d8166ddab8 100644
--- a/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_8.c
+++ b/gcc/testsuite/gcc.target/aarch64/shadow_call_stack_8.c
@@ -10,6 +10,7 @@
/* { dg-do compile } */
/* { dg-options "-O0 -fomit-frame-pointer -fsanitize=shadow-call-stack
-fno-exceptions -ffixed-x18 --save-temps -fno-stack-protector" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
int func1 (void)
{
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
index 38eab4d36ab2d..49dc51142e6e8 100644
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c
@@ -1,4 +1,5 @@
/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param
stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18
-fno-stack-protector" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
/* { dg-final { check-function-bodies "**" "" } } */
void f(int, ...);
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
index 690aae8dfd5b5..35b8ccc99e44e 100644
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c
@@ -1,3 +1,4 @@
/* { dg-options "-O2 -fstack-protector-all -fstack-clash-protection
-fomit-frame-pointer --param stack-clash-protection-guard-size=12
-fsanitize=shadow-call-stack -ffixed-x18" } */
+/* { dg-skip-if "conflicts with x18" { aarch64-*-vxworks* } } */
#include "stack-check-prologue-19.c"
--
Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!