Hi all,

I have detected the armv{6,7,8}-m/arm_vectors.c assigns the initial
stack pointer value (using the first entry at the exception vectors
table) just to _ebss + CONFIG_IDLETHREAD_STACKSIZE, without further
checking. This can yield to an unusable binary if .data or .bss
sections grow too much.

To test, use the attached patch 0001 and ./tools/configure.sh
lm3s6965-ek:qemu-flat

(Note with stacks just below SRAM limit the NSH prompt will still not
be visible because booting will fail during heap allocation, but still
the "ABCDF" booting markers will be shown; when the stack starting
point is past the SRAM end, booting fails immediately and those
markers are not shown).

There are multiple ways to fix (= detect this at build time) this
problem. The best IMHO is to make the stack space appear at the memory
map and be allocated. This will cause a region overflow error during
linking when the initial stack overflows SRAM (as intended). For a
demo of this fix (for lm3s6965-ek:qemu-flat only) see attached patch
0002.

Unfortunately, this requires linker script changes for most platforms.
Without the changes, the initial stack would be correctly allocated
(ld would just map ".stack" section to any writable memory region) but
several other parts of the code assume the heap to be just after the
idle thread stack, which cannot be guaranteed without the
aforementioned linker script changes.

So I want to ask here for opinion before progressing further, as a
change this deep would affect a lot of platforms which I do not have
the means to test.

WDYT?

Carlos
From 0dc292a1fa17c9776784e1d4c648bf225ee79710 Mon Sep 17 00:00:00 2001
From: Carlos Sanchez <carlossanchez@geotab.com>
Date: Wed, 2 Nov 2022 11:59:49 +0100
Subject: [PATCH 1/2] Changes to force fill bss section causing sp past the
 SRAM end.

---
 arch/arm/src/armv7-m/arm_vectors.c            | 12 ++++++++++++
 boards/arm/tiva/lm3s6965-ek/scripts/ld.script |  1 +
 2 files changed, 13 insertions(+)

diff --git a/arch/arm/src/armv7-m/arm_vectors.c b/arch/arm/src/armv7-m/arm_vectors.c
index 36bdfb8075..ca86f2a58a 100644
--- a/arch/arm/src/armv7-m/arm_vectors.c
+++ b/arch/arm/src/armv7-m/arm_vectors.c
@@ -90,3 +90,15 @@ unsigned _vectors[] locate_data(".vectors") =
 
   [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
 };
+
+/* Stack initialized to 0x20010000 */
+/* static volatile char fill[49160]; */
+
+/* Stack initialized to 0x20010008, still works because
+   Dump of assembler code for function __start:
+   => 0x0000011c <+0>:	push	{r3, lr}
+   which are never pop'ed. */
+/* static volatile char fill[49168]; */
+
+/* Stack initialized to 0x20010010 */
+static volatile char fill[49176];
diff --git a/boards/arm/tiva/lm3s6965-ek/scripts/ld.script b/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
index 15cc25511f..f16f4588d7 100644
--- a/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
+++ b/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
@@ -83,6 +83,7 @@ SECTIONS
         *(.bss .bss.*)
         *(.gnu.linkonce.b.*)
         *(COMMON)
+	KEEP(*(.bss.fill))
         . = ALIGN(4);
         _ebss = ABSOLUTE(.);
     } > sram
-- 
2.25.1

From 958993fb56fb22cd1d4af94645cb570adb3579e5 Mon Sep 17 00:00:00 2001
From: Carlos Sanchez <carlossanchez@geotab.com>
Date: Wed, 2 Nov 2022 13:27:59 +0100
Subject: [PATCH 2/2] Allocate stack in the memory map.

---
 arch/arm/src/armv7-m/arm_vectors.c            | 8 +++++++-
 boards/arm/tiva/lm3s6965-ek/scripts/ld.script | 4 ++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/src/armv7-m/arm_vectors.c b/arch/arm/src/armv7-m/arm_vectors.c
index ca86f2a58a..86d7fd6496 100644
--- a/arch/arm/src/armv7-m/arm_vectors.c
+++ b/arch/arm/src/armv7-m/arm_vectors.c
@@ -45,12 +45,18 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define IDLE_STACK      ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE)
+#define IDLE_STACK      ((unsigned) idle_stack + sizeof(idle_stack))
 
 #ifndef ARMV7M_PERIPHERAL_INTERRUPTS
 #  error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported
 #endif
 
+/****************************************************************************
+ * Private data
+ ****************************************************************************/
+
+static char idle_stack[CONFIG_IDLETHREAD_STACKSIZE] locate_data(".stack");
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
diff --git a/boards/arm/tiva/lm3s6965-ek/scripts/ld.script b/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
index f16f4588d7..1f13773591 100644
--- a/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
+++ b/boards/arm/tiva/lm3s6965-ek/scripts/ld.script
@@ -88,6 +88,10 @@ SECTIONS
         _ebss = ABSOLUTE(.);
     } > sram
 
+    .stack (NOLOAD) : ALIGN(4) {
+        *(.stack)
+    } > sram
+
      /* Stabs debugging sections. */
 
     .stab 0 : { *(.stab) }
-- 
2.25.1

Reply via email to