Perhaps Simon Marlow, or others, may be able to help? It would be good to capture the answers somewhere, perhaps in the GHC Commentary? https://gitlab.haskell.org/ghc/ghc/wikis/commentary Simon | -----Original Message----- | From: ghc-devs <ghc-devs-bounces@haskell.org> On Behalf Of Stefan Schulze | Frielinghaus | Sent: 22 June 2019 10:23 | To: ghc-devs@haskell.org | Subject: StgRun and reserved C stack space | | Hi all, | | I'm trying to understand how StgRun/StgReturn are supposed to be | implemented. | My current understanding is that StgRun is called from C land in order to | save all callee-saved registers, allocate some stack space, and then | finally jump to an STG function. StgReturn is the counterpart of StgRun | and is called from STG land in order to restore all callee-saved | registers, free the previously allocated stack space, and finally return | to C land. | | Assuming that my intuition is correct I still have some concerns regarding | the stack space which is allocated by StgRun. StgRun allocates | RESERVED_C_STACK_BYTES many bytes on the C stack. However, I cannot see | how an STG function is supposed to access this reserved area since no | pointer is derived or whatsoever. Does an STG function make use of the C | stack pointer and assume that the reserved area is at the very bottom of | the stack? | | Lets make an example. Assume the C ABI demands that every function | allocates a Register Save Area (RSA for short) at the bottom of a stack | frame which may be used by a subsequent C function. That means a caller | allocates some stack space for its callee. This area must be below the | local variable and parameter area which means it is at the very bottom of | a stack frame. A C stack frame then looks as follows: | | . . | . . | | previous frame | | +---------------------+ | | local variables | | +---------------------+ | | parameter area | | +---------------------+ | | register save area | | +---------------------+ <---+ SP | | Thus StgRun must also allocate a register save area which is used by | subsequent C functions. An example stack while calling StgRun could look | as follows: | | . . | . . | | | | +---------------------+ | RSA1 | register save area | | | used by StgRun | | +---------------------+ xxx | | | xx | | | xx | | | xx | | | xx | | | xxxxxx RESERVED_C_STACK_BYTES | | | xx | | | xx | | | xx | | | xx | +---------------------+ xxx | RSA2 | register save area | | | for further C calls | | +---------------------+ <---+ SP | | RSA1 is allocated by the caller of StgRun and is used by StgRun in order | to save all callee-saved registers. StgRun itself then allocates | RESERVED_C_STACK_BYTES many bytes and RSA2. RSA2 will be used by | subsequent C functions which are called from STG land. | | Thus coming back to my initial question how is an STG function supposed to | know where the reserved area starts? One way would be to use SP + | len(RSA2) but this would mean an STG function is aware of the register in | which the C stack pointer is hold and the length of a register save area. | I didn't find anything which suggests this while skimming over the code. | | Many thanks and kind regards, | Stefan | _______________________________________________ | ghc-devs mailing list | ghc-devs@haskell.org | https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.hask | ell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc- | devs&data=02%7C01%7Csimonpj%40microsoft.com%7C9b1c5c94f5a14f3d11c308d6 | f6f34a3d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636967922119470764&a | mp;sdata=cYAlP9xb%2F%2FeoYy%2Bq4M66IomjxX90HtwgPpSf2mvYX5U%3D&reserved | =0