You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/10/17 08:23:09 UTC
[incubator-nuttx] branch releases/10.0 updated: ARM stack fix: Same
boundary calculation in do_stackcheck and stack_color.
This is an automated email from the ASF dual-hosted git repository.
btashton pushed a commit to branch releases/10.0
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/releases/10.0 by this push:
new a82be21 ARM stack fix: Same boundary calculation in do_stackcheck and stack_color.
a82be21 is described below
commit a82be215b9eaef7b68b732957d9d896e98576fd1
Author: Johannes Schock <jo...@nivus.com>
AuthorDate: Sat Sep 26 19:33:22 2020 +0200
ARM stack fix: Same boundary calculation in do_stackcheck and stack_color.
Use additional space from 8 byte aligning for stack in up_create_stack().
Moved arm_stack_color to arm_checkstack.c.
---
arch/arm/src/common/arm_checkstack.c | 85 +++++++++++++++++++++++++++--------
arch/arm/src/common/arm_createstack.c | 43 ++++++------------
arch/arm/src/common/arm_usestack.c | 14 +++++-
3 files changed, 91 insertions(+), 51 deletions(-)
diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c
index 8f624a6..c3e51ba 100644
--- a/arch/arm/src/common/arm_checkstack.c
+++ b/arch/arm/src/common/arm_checkstack.c
@@ -56,16 +56,30 @@
#ifdef CONFIG_STACK_COLORATION
/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* 32bit alignment macros */
+
+#define INT32_ALIGN_MASK (3)
+#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
+#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
+
+/****************************************************************************
* Private Function Prototypes
****************************************************************************/
-static size_t do_stackcheck(uintptr_t alloc, size_t size);
+static size_t do_stackcheck(FAR void *stackbase, size_t nbytes);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
/****************************************************************************
* Name: do_stackcheck
*
* Description:
- * Determine (approximately) how much stack has been used be searching the
+ * Determine (approximately) how much stack has been used by searching the
* stack memory for a high water mark. That is, the deepest level of the
* stack that clobbered some recognizable marker in the stack memory.
*
@@ -78,26 +92,26 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size);
*
****************************************************************************/
-static size_t do_stackcheck(uintptr_t alloc, size_t size)
+static size_t do_stackcheck(FAR void *stackbase, size_t nbytes)
{
- FAR uintptr_t start;
- FAR uintptr_t end;
+ uintptr_t start;
+ uintptr_t end;
FAR uint32_t *ptr;
size_t mark;
- if (size == 0)
+ if (nbytes == 0)
{
return 0;
}
- /* Get aligned addresses of the top and bottom of the stack */
+ /* Take extra care that we do not check outside the stack boundaries */
- start = alloc & ~3;
- end = (alloc + size + 3) & ~3;
+ start = INT32_ALIGN_UP((uintptr_t)stackbase);
+ end = INT32_ALIGN_DOWN((uintptr_t)stackbase + nbytes);
/* Get the adjusted size based on the top and bottom of the stack */
- size = end - start;
+ nbytes = end - start;
/* The ARM uses a push-down stack: the stack grows toward lower addresses
* in memory. We need to start at the lowest address in the stack memory
@@ -105,7 +119,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
* that does not have the magic value is the high water mark.
*/
- for (ptr = (FAR uint32_t *)start, mark = (size >> 2);
+ for (ptr = (FAR uint32_t *)start, mark = (nbytes >> 2);
*ptr == STACK_COLOR && mark > 0;
ptr++, mark--);
@@ -126,7 +140,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
int j;
ptr = (FAR uint32_t *)start;
- for (i = 0; i < size; i += 4 * 64)
+ for (i = 0; i < nbytes; i += 4 * 64)
{
for (j = 0; j < 64; j++)
{
@@ -158,6 +172,39 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
****************************************************************************/
/****************************************************************************
+ * Name: arm_stack_color
+ *
+ * Description:
+ * Write a well know value into the stack
+ *
+ ****************************************************************************/
+
+void arm_stack_color(FAR void *stackbase, size_t nbytes)
+{
+ uintptr_t start;
+ uintptr_t end;
+ size_t nwords;
+ FAR uint32_t *ptr;
+
+ /* Take extra care that we do not write outside the stack boundaries */
+
+ start = INT32_ALIGN_UP((uintptr_t)stackbase);
+ end = INT32_ALIGN_DOWN((uintptr_t)stackbase + nbytes);
+
+ /* Get the adjusted size based on the top and bottom of the stack */
+
+ nwords = (end - start) >> 2;
+ ptr = (FAR uint32_t *)start;
+
+ /* Set the entire stack to the coloration value */
+
+ while (nwords-- > 0)
+ {
+ *ptr++ = STACK_COLOR;
+ }
+}
+
+/****************************************************************************
* Name: up_check_stack and friends
*
* Description:
@@ -175,8 +222,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
size_t up_check_tcbstack(FAR struct tcb_s *tcb)
{
- return do_stackcheck((uintptr_t)tcb->adj_stack_ptr - tcb->adj_stack_size,
- tcb->adj_stack_size);
+ return do_stackcheck((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
+ tcb->adj_stack_size), tcb->adj_stack_size);
}
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
@@ -198,17 +245,17 @@ ssize_t up_check_stack_remain(void)
size_t up_check_intstack(void)
{
#ifdef CONFIG_SMP
- return do_stackcheck(arm_intstack_base(),
- (CONFIG_ARCH_INTERRUPTSTACK & ~3));
+ return do_stackcheck((FAR void *)arm_intstack_base(),
+ INT32_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK));
#else
- return do_stackcheck((uintptr_t)&g_intstackalloc,
- (CONFIG_ARCH_INTERRUPTSTACK & ~3));
+ return do_stackcheck((FAR void *)&g_intstackalloc,
+ INT32_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK));
#endif
}
size_t up_check_intstack_remain(void)
{
- return (CONFIG_ARCH_INTERRUPTSTACK & ~3) - up_check_intstack();
+ return INT32_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK) - up_check_intstack();
}
#endif
diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c
index 97534cb..dda4b1f 100644
--- a/arch/arm/src/common/arm_createstack.c
+++ b/arch/arm/src/common/arm_createstack.c
@@ -58,6 +58,12 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+/* 32bit alignment macros */
+
+#define INT32_ALIGN_MASK (3)
+#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
+#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -103,10 +109,12 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
size_t alloc_size;
+ size_t tls_size;
- /* Add the size of the TLS information structure and align */
+ /* Add the size of the TLS information structure and align. */
- alloc_size = STACK_ALIGN_UP(stack_size + sizeof(struct tls_info_s));
+ tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
+ alloc_size = STACK_ALIGN_UP(stack_size + tls_size);
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
@@ -117,10 +125,11 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (alloc_size > TLS_MAXSTACK)
{
alloc_size = TLS_MAXSTACK;
- stack_size = alloc_size - sizeof(struct tls_info_s);
}
#endif
+ stack_size = alloc_size - tls_size;
+
/* Is there already a stack allocated of a different size? */
if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
@@ -209,7 +218,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Initialize the TLS data structure */
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+ memset(tcb->stack_alloc_ptr, 0, tls_size);
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
@@ -227,29 +236,3 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
return ERROR;
}
-
-/****************************************************************************
- * Name: arm_stack_color
- *
- * Description:
- * Write a well know value into the stack
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STACK_COLORATION
-void arm_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 = (((uintptr_t)stackbase + nbytes) & ~3);
- size_t nwords = (stkend - (uintptr_t)stackbase) >> 2;
-
- /* Set the entire stack to the coloration value */
-
- while (nwords-- > 0)
- {
- *stkptr++ = STACK_COLOR;
- }
-}
-#endif
diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c
index e0e03b4..45e28d7 100644
--- a/arch/arm/src/common/arm_usestack.c
+++ b/arch/arm/src/common/arm_usestack.c
@@ -53,6 +53,12 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+/* 32bit alignment macros */
+
+#define INT32_ALIGN_MASK (3)
+#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
+#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -87,12 +93,16 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
+ size_t tls_size;
+
#ifdef CONFIG_TLS_ALIGNED
/* Make certain that the user provided stack is properly aligned */
DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
#endif
+ tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
+
/* Is there already a stack allocated? */
if (tcb->stack_alloc_ptr)
@@ -125,7 +135,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
/* Offset by tls_size */
- stack = (FAR void *)((uintptr_t)stack + sizeof(struct tls_info_s));
+ stack = (FAR void *)((uintptr_t)stack + tls_size);
/* Is there enough room for at least TLS ? */
@@ -138,7 +148,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
/* Initialize the TLS data structure */
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+ memset(tcb->stack_alloc_ptr, 0, tls_size);
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a