[En-Nut-Discussion] CM3 Stack alignment

bon at elektron.ikp.physik.tu-darmstadt.de bon at elektron.ikp.physik.tu-darmstadt.de
Mon Sep 23 18:50:25 CEST 2013

>>>>> "Harald" == Harald Kipp <harald.kipp at egnite.de> writes:

    Harald> Hi Uwe, a comment line would have been great and help other
    Harald> platform maintainers to follow. I do have questions.

    Harald> On 23.09.2013 14:18, bon at elektron.ikp.physik.tu-darmstadt.de
    Harald> wrote:
    >> for va_arg() to work with double and uint64_t on cortex and arm, the
    >> stack needs to be aligned on a 8-byte boundary.

    Harald> You mean the start of stack memory or the current stack pointer
    Harald> value?

It is somehow explained by the weblink I gave and the mailinglist discussion
about the gcc compiler, mostly Bob's findings.

In short: The start of stack memory must be 8 byte aligned. 

    Harald> While I can imagine, that the latter may be required, I have no
    Harald> idea how the va_arg() is influenced by the location of the
    Harald> stack's top.

Arm calling convention says to put 8-byte entities to R0/R1 or R2/R3. So if
R0 is already occupied by a function argument, a second 64-byte
argument is put to R2/R3 while skipping R1. Further function arguments are
pushed on the stack, with 8-byte values on a 8-byte boundary, eventually
skipping a 4-byte stack value. The va_arg magic fetches 8-byte values from
this 8-byte boundary, eventually skipping an unused 4-byte stack.

    Harald> Your patch in nut/arch/cm3/os/context.c does two things:

    Harald> 1. Rounding up the stack size to an 8 byte boundary.

    Harald>  alloc_size = stackSize + sizeof(NUTTHREADINFO); alloc_size +=
    Harald> 7; alloc_size &= ~7;

    Harald> Can you explain, why we need to adjust the stack's size?

This is for security reason, so the effective stack size is not smaller than
the calling code requested. 

    Harald> 2. Aligning the stack top to the next lower 8 byte boundary.

    Harald>  td = (NUTTHREADINFO *) (((uint32_t)(threadMem + stackSize)) &
    Harald> ~7);

    Harald> This will move the initial stack pointer down to the next 8 byte
    Harald> boundary. But what happens in

    Harald> void foo(void) { int bar;

    Harald>   /* Is my SP still 8-byte aligned here? */ ...more code...  }

At least "bar" is only put in R0, so not effecting the stack at all. Bad
And it is up to  the compiler to keep the stack happy. But the compiler
doesn't know about our assembler commands setting the stack, so these
commands must care for stack alignment.

Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------

More information about the En-Nut-Discussion mailing list