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]

Reply via email to