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