From ff210e1c2d535255443757ab64f4042681bf6615 Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Tue, 12 Apr 2022 22:25:19 +0800 Subject: [PATCH] arch/stack_color: correct the end address of stack color The different optimization of compilers will cause ambiguity in obtaining sp through up_getsp() in arm_stack_color(), if compile with clang and enable the optimization flag (-Ofast), up_getsp() call will be earlier than push {r0-r9,lr}, the end address of color stack will overlap with saved registers. Compile line: clang --target=arm-none-eabi -c "-Ofast" -fno-builtin -march=armv8.1-m.main+mve.fp+fp.dp \ -mtune=cortex-m55 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -D__NuttX__ -common/arm_checkstack.c -o arm_checkstack.o Assembler code: llvm-objdump -aS arm_checkstack.o ------------------------------------ |00000000 : |; start = INT32_ALIGN_UP((uintptr_t)stackbase); | 0: c2 1c adds r2, r0, #3 | 2: 22 f0 03 02 bic r2, r2, #3 |; end = nbytes ? INT32_ALIGN_DOWN((uintptr_t)stackbase + nbytes) : | 6: 19 b1 cbz r1, 0x10 @ imm = #6 | 8: 08 44 add r0, r1 | a: 20 f0 03 00 bic r0, r0, #3 | e: 00 e0 b 0x12 @ imm = #0 |; __asm__ | 10: 68 46 mov r0, sp <--- fetch the sp before push {r7 lr} | 12: 80 b5 push {r7, lr} <--- sp changed |; nwords = (end - start) >> 2; | 14: 80 1a subs r0, r0, r2 | 16: 80 08 lsrs r0, r0, #2 |; } | 18: 08 bf it eq | 1a: 80 bd popeq {r7, pc} | 1c: 4b f6 ef 63 movw r3, #48879 | 20: cd f6 ad 63 movt r3, #57005 | 24: a0 ee 10 3b vdup.32 q0, r3 |; while (nwords-- > 0) | 28: 20 f0 01 e0 dlstp.32 lr, r0 |; *ptr++ = STACK_COLOR; <--- overwrite | 2c: a2 ec 04 1f vstrw.32 q0, [r2], #16 | 30: 1f f0 05 c0 letp lr, 0x2c @ imm = #-8 |; } | 34: 80 bd pop {r7, pc} ------------------------------------ Signed-off-by: chao.an --- arch/arm/src/common/arm_checkstack.c | 3 ++- arch/ceva/src/common/up_createstack.c | 13 +++++++++---- arch/or1k/src/common/up_createstack.c | 13 +++++++++---- arch/risc-v/src/common/riscv_createstack.c | 3 ++- arch/sim/src/sim/up_createstack.c | 13 +++++++++---- arch/sparc/src/common/up_checkstack.c | 3 ++- arch/xtensa/src/common/xtensa_createstack.c | 3 ++- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c index 87384c56e742b..08dd03a0b4879 100644 --- a/arch/arm/src/common/arm_checkstack.c +++ b/arch/arm/src/common/arm_checkstack.c @@ -168,12 +168,13 @@ void arm_stack_color(FAR void *stackbase, size_t nbytes) uintptr_t end; size_t nwords; FAR uint32_t *ptr; + uintptr_t sp; /* Take extra care that we do not write outside the stack boundaries */ start = INT32_ALIGN_UP((uintptr_t)stackbase); end = nbytes ? INT32_ALIGN_DOWN((uintptr_t)stackbase + nbytes) : - up_getsp(); /* 0: colorize the running stack */ + (uintptr_t)&sp; /* 0: colorize the running stack */ /* Get the adjusted size based on the top and bottom of the stack */ diff --git a/arch/ceva/src/common/up_createstack.c b/arch/ceva/src/common/up_createstack.c index 1eab7ad0d9c29..d0ba7d28ac006 100644 --- a/arch/ceva/src/common/up_createstack.c +++ b/arch/ceva/src/common/up_createstack.c @@ -232,10 +232,15 @@ void up_stack_color(FAR void *stackbase, size_t nbytes) { /* Take extra care that we do not write outsize the stack boundaries */ - uint32_t *stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); - uintptr_t stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : - up_getsp(); /* 0: colorize the running stack */ - size_t nwords = (stkend - (uintptr_t)stackbase) >> 2; + uint32_t *stkptr; + uintptr_t stkend; + size_t nwords; + uintptr_t sp; + + stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); + stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : + (uintptr_t)&sp; /* 0: colorize the running stack */ + nwords = (stkend - (uintptr_t)stackbase) >> 2; /* Set the entire stack to the coloration value */ diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c index b65531b760c9b..731c5b64b00fb 100644 --- a/arch/or1k/src/common/up_createstack.c +++ b/arch/or1k/src/common/up_createstack.c @@ -205,10 +205,15 @@ void up_stack_color(FAR void *stackbase, size_t nbytes) { /* Take extra care that we do not write outsize the stack boundaries */ - uint32_t *stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); - uintptr_t stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : - up_getsp(); /* 0: colorize the running stack */ - size_t nwords = (stkend - (uintptr_t)stackbase) >> 2; + uint32_t *stkptr; + uintptr_t stkend; + size_t nwords; + uintptr_t sp; + + stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); + stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : + (uintptr_t)&sp; /* 0: colorize the running stack */ + nwords = (stkend - (uintptr_t)stackbase) >> 2; /* Set the entire stack to the coloration value */ diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c index 29dd8b96a6897..d8a27bcb4295f 100644 --- a/arch/risc-v/src/common/riscv_createstack.c +++ b/arch/risc-v/src/common/riscv_createstack.c @@ -217,12 +217,13 @@ void riscv_stack_color(void *stackbase, size_t nbytes) uintptr_t end; size_t nwords; uint32_t *ptr; + uintptr_t sp; /* Take extra care that we do not write outside the stack boundaries */ start = STACK_ALIGN_UP((uintptr_t)stackbase); end = nbytes ? STACK_ALIGN_DOWN((uintptr_t)stackbase + nbytes) : - up_getsp(); /* 0: colorize the running stack */ + (uintptr_t)&sp; /* 0: colorize the running stack */ /* Get the adjusted size based on the top and bottom of the stack */ diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c index 6e540afd37696..71381f3b29850 100644 --- a/arch/sim/src/sim/up_createstack.c +++ b/arch/sim/src/sim/up_createstack.c @@ -161,10 +161,15 @@ void nostackprotect_function up_stack_color(FAR void *stackbase, { /* Take extra care that we do not write outsize the stack boundaries */ - uint32_t *stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); - uintptr_t stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : - up_getsp(); /* 0: colorize the running stack */ - size_t nwords = (stkend - (uintptr_t)stackbase) >> 2; + uint32_t *stkptr; + uintptr_t stkend; + size_t nwords; + uintptr_t sp; + + stkptr = (uint32_t *)(((uintptr_t)stackbase + 3) & ~3); + stkend = nbytes ? (((uintptr_t)stackbase + nbytes) & ~3) : + (uintptr_t)&sp; /* 0: colorize the running stack */ + nwords = (stkend - (uintptr_t)stackbase) >> 2; /* Set the entire stack to the coloration value */ diff --git a/arch/sparc/src/common/up_checkstack.c b/arch/sparc/src/common/up_checkstack.c index b2302683e4bf1..b1d9cca52046a 100644 --- a/arch/sparc/src/common/up_checkstack.c +++ b/arch/sparc/src/common/up_checkstack.c @@ -169,12 +169,13 @@ void up_stack_color(FAR void *stackbase, size_t nbytes) uintptr_t end; size_t nwords; FAR uint32_t *ptr; + uintptr_t sp; /* Take extra care that we do not write outside the stack boundaries */ start = INT32_ALIGN_UP((uintptr_t)stackbase); end = nbytes ? INT32_ALIGN_DOWN((uintptr_t)stackbase + nbytes) : - up_getsp(); /* 0: colorize the running stack */ + (uintptr_t)&sp; /* 0: colorize the running stack */ /* Get the adjusted size based on the top and bottom of the stack */ diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c index 4dc601d227f58..aeea6c2c8aabb 100644 --- a/arch/xtensa/src/common/xtensa_createstack.c +++ b/arch/xtensa/src/common/xtensa_createstack.c @@ -223,12 +223,13 @@ void xtensa_stack_color(void *stackbase, size_t nbytes) uintptr_t end; size_t nwords; uint32_t *ptr; + uintptr_t sp; /* Take extra care that we do not write outside the stack boundaries */ start = STACK_ALIGN_UP((uintptr_t)stackbase); end = nbytes ? STACK_ALIGN_DOWN((uintptr_t)stackbase + nbytes) : - up_getsp(); /* 0: colorize the running stack */ + (uintptr_t)&sp; /* 0: colorize the running stack */ /* Get the adjusted size based on the top and bottom of the stack */