cortexm: fix stack size calculation with interrupts

Interrupts store 32 bytes on the current stack, which may be a goroutine
stack. After that the interrupt switches to the main stack pointer so
nothing more is pushed to the current stack. However, these 32 bytes
were not included in the stack size calculation.

This commit adds those 32 bytes. The code is rather verbose, but that is
intentional to make sure it is readable. This is tricky code that's hard
to get right, so I'd rather keep it well documented.
Этот коммит содержится в:
Ayke van Laethem 2020-08-30 13:26:10 +02:00 коммит произвёл Ron Evans
родитель 098fb5f39c
коммит da7db81087

Просмотреть файл

@ -447,11 +447,28 @@ func modifyStackSizes(executable string, stackSizeLoads []string, stackSizes map
return fmt.Errorf("could not find symbol %s in ELF file", name)
}
if fn.stackSizeType == stacksize.Bounded {
// Note: adding 4 for the stack canary. Even though the size may be
stackSize := uint32(fn.stackSize)
// Adding 4 for the stack canary. Even though the size may be
// automatically determined, stack overflow checking is still
// important as the stack size cannot be determined for all
// goroutines.
binary.LittleEndian.PutUint32(data[i*4:], uint32(fn.stackSize)+4)
stackSize += 4
// Add stack size used by interrupts.
switch elfFile.Machine {
case elf.EM_ARM:
// On Cortex-M (assumed here), this stack size is 8 words or 32
// bytes. This is only to store the registers that the interrupt
// may modify, the interrupt will switch to the interrupt stack
// (MSP).
// Some background:
// https://interrupt.memfault.com/blog/cortex-m-rtos-context-switching
stackSize += 32
}
// Finally write the stack size to the binary.
binary.LittleEndian.PutUint32(data[i*4:], stackSize)
}
}