[Freemint-list] mintlib startup code & accessories
Thorsten Otto
admin at tho-otto.de
Sun Mar 19 15:58:31 MSK 2017
Hi,
i just encountered a strange problem with the mintlib's behaviour of the
startup code setting up the stack for the program (in crtinit.c). The
convention is to use the _stksize variable, so applications have control of it
without having to link every program to a specialized startup code. The way
that variable is interpreted is actually very similar to that was suggested by
Atari long time ago in their gemstart.s of the Alcyon package.
To simplify it: for accessories, it is suggested to use _stksize=0, which
would use a minimum compiled-in stacksize in (usually 4 or 8k), or a positive
value to use that amount of stack. The startup code then does a
Mshrink(0x100+textsize+datasize+bsssize+_stksize)
Now here the problem is: the stack size, because determined at runtime, is not
part of the bsssize as stated in the program header. However, when AES starts,
it does so by:
while (accessory found)
{
Pexec(3, acc); /* load, dont go */
Mshrink(acc, 0x100+textsize+datasize+bsssize);
/* note:NOT including ANY stack */
...
then puts accessory on run list
}
Notice that at this point, no user code is executed. They are only put on the
runlist, and executed later when aes has finished initialization. As a
consequence, if there is more than 1 acc, the 2nd acc may be loaded (and
usually is loaded) just behind the memory area of the 1st acc. Now, when the
first acc starts executing, its startup code will do the Mshrink() that
includes the stacksize. That Mshrink() will fail, because the area for the
stack is already occupied by the 2nd acc. The return code is not checked
however, and the stackpointer for the first acc is still set to the end of
that area, now pointing into some memory of the 2nd acc. Result: the memory of
the 2nd acc is clobbered (or the 1st acc is killed if running with MP).
Any idea how to solve this?
BTW accs compiled by PureC don't have this problem: when you specify a
stacksize in the link command, the linker will notice that and add that value
to the bss segment size. However the startup code is simpler, and therefore
only works for positive stacksize values.
BTW2: that behaviour of Mshrinking() the accessories memory before it is
executed seems to be common to TOS, EmuTOS and XaAES.
More information about the Freemint-list
mailing list