Nathan,
I see two ways to fix this(that cover a majority of the cases):
* Increase alignment in .ld files that specify symbol (_ebss in stm32
variants) used to locate the idle stack
* Adjust asm() in start function that clears LR and calls __start to
forcibly align SP down(at least for stm variants)
I think updating the .ld files is cleaner, but that makes the PR review
a bit unweildy due to the sheer number of affected .ld files (100+ in
just the stm32 variants). Question is which approach I should take in
creating the PR?
Looking further at the .ld files (stm32 variants in this case), there
are multiple copies of the same content(outside of comments). At some
point it may be worth merging together a bunch of these duplicate linker
files into a "family" - but that's a different issue.
On 3/15/26 23:38, Nathan Hartman wrote:
Ah, thank you for the correction! It seems we'd better research each
platform and choose the correct alignment, since 8 bytes isn't enough
for all of them.
I tried to do some quick searches before my earlier reply but I was
using mobile and it wasn't obvious where to find the information.
At least I'm glad that my reply prompted a better response!
Maybe an issue should be filed in the issue tracker to verify
alignment requirements are met for all supported platforms, not just
Arm? It's possible these could have been missed in other places.
Thanks,
Nathan
On Sun, Mar 15, 2026 at 7:55 PM Lwazi Dube <[email protected]> wrote:
8-bytes is not enough for v8. I would use at least 16.
For armv8:
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#6452stack-constraints-at-a-public-interface
6.4.5.2 Stack constraints at a public interface
The stack must also conform to the following constraint at a public
interface:
SP mod 16 = 0. The stack must be quad-word aligned.
For 32 bit ARM (including ARMv5):
https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst#6212stack-constraints-at-a-public-interface
6.2.1.2 Stack constraints at a public interface
The stack must also conform to the following constraint at a public
interface:
SP mod 8 = 0. The stack must be double-word aligned.
On Sun, 15 Mar 2026 at 16:16, Nathan Hartman
<[email protected]>
wrote:
> On Fri, Mar 13, 2026 at 2:03 PM Peter Barada
<[email protected]>
> wrote:
>
> > I've run across a crash on a few different STM32 Nucleo boards
(h743zi2,
> > f767zi, and f446re) caused by the Idlestack not being8-byte
aligned due
> > to syslog messages at startup (with timestamps enabled) that
passes a
> > uintmax_t parameter to vsprinf_internal().
> >
> > I originally found this on nucleo-h743zi2:jumbo while trying
to fix the
> > "Missing logic" warning in stm32_irq.c:152 I've been able to
apply my
> > same changes to nucleo-f446re and nucleo-f767zi and exhibit
the issue.
> > Even w/o my changes, forcing the .bss section to not be 8-byte
aligned
> > in size causes the same issue.
> >
> > The underlying issue occurs due to calling stm32_dumpnvic from the
> > idletask with SYSLOG_TIMESTAMP enabled, but only when the
Idlestak is
> > not aligned to an 8-byte bvoundary. The issue is due to
invoking "x =
> > va_arg(ap, unsigned long long);" in vsprintf_internal
> > (lib_libvsprintf.c:1061) which aligns ap before accessing the
long long:
> >
> > Breakpoint 5, vsprintf_internal (stream=stream@entry=0x20005390,
> > arglist=0x0,
> > numargs=0, fmt=0x8018bf2 ".%06ld] [%6s] %s: ",
> > fmt@entry=0x8005817 <lib_sprintf_internal+22> "...",
> > ap=..., ap@entry=..., numargs=0, arglist=0x0)
> > at stream/lib_libvsprintf.c:1061
> > 1061 x = va_arg(ap, unsigned long long);
> > p ap
> > $18 = {__ap =*0x2000536c*}
> > (gdb) x/5i $pc
> > => 0x800563a <vsprintf_internal+782>: add.w r9, r9, #7
> > 0x800563e <vsprintf_internal+786>:*bic.w r9, r9, #7 #
align ap*
> > 0x8005642 <vsprintf_internal+790>: mov r7, r9
> > 0x8005644 <vsprintf_internal+792>: ldr.w r1, [r9, #4]
> > 0x8005648 <vsprintf_internal+796>: ldr.w r0, [r7], #8
> > (gdb) p/x $r9
> > $19 = 0x2000536c
> > (gdb) s
> > 1108 flags &= ~(FL_PLUS | FL_SPACE);
> > (gdb) p ap
> > $20 = {__ap =*0x20005378*}
> > (gdb) p/x $r7
> > $21 = 0x20005378
> > (gdb)
> >
> > This works fine if the stack is aligned on an 8-byte boundary
(which all
> > other task/user stacks currently are due to
MM_DEFAULT_ALIGNMENT being
> > 8). But if the idletask stack is not aligned, ap ends up
incremented by
> > 12 causing access to any following vararg in vsprintf_internal
to be
> > offset by 4 bytes resulting in potential exceptions.
> >
> > A fix is to increase the alignment in the .bss section to 8 in the
> > linker description file (since the idlestack immediately
follows .bss
> > starting at _ebss). I've tested this fix on nucleo-743zi2
(based on
> > stm32h7), nucleo-h767zi (based on stm32f7), and nucleo-f446re
(based on
> > stm32), all with success.
> >
> > I can provide a PR, but my question is whether this alignment
should be
> > applied to all ARM?
> >
> > --
> > Peter Barada
> > [email protected]
> >
>
> Hi Peter,
>
> Good catch!!
>
> A PR would be very much appreciated.
>
> As for whether the alignment fix should be applied to all ARM, I
don't know
> the answer off the top of my head, but I think it would be safe
to do so.
>
> NuttX supports multiple ARM platforms, including:
>
> armv6-m
> armv7-a
> armv7-m
> armv7-r
> armv8-m
> armv8-r
> arm64
>
> The STM32H7 and STM32F7 both have a armv7-m core; without
checking, I don't
> know which cores the other STM32 parts have.
>
> Since you caught this issue on armc7-m, I think it's safe to assume
> that armv7-a
> through arm64 probably require the stack aligned to 8 bytes.
>
> I don't know about armv6-m but I think it can be updated to 8-byte
> alignment as well, for consistency across the ARM platforms.
>
> In other words, Someone (tm) could go ahead and do the research to
> determine what the alignment requirements are for each of the
cores listed
> above, or the alignment could just be updated to 8-byte whether
it's needed
> or not.
>
> Thoughts?
>
> Nathan
>
--
Peter Barada
[email protected]