The ABI speaks of two types of functions.
https://docs.microsoft.com/en-us/cpp/build/function-types
They are called "nested" or "frame" or "non-leaf" functions, and leaf functions.
A common misconception is that a leaf function is one that makes no calls.
This is a natural misunderstanding, because people think of call trees, and leaves of it.
While a function that makes calls is indeed not a leaf, that is not the only characteristic that makes a function not a leaf.
A frame function is a function that changes non-volatile registers or has an exception handler (or both).
These are the base most and only two reasons a function is a frame function. Everything else follows.
Two common examples of changing non-volatile registers are changing RSP to allocate stack space, or calling another function, which also changes RSP.
But these are not additional conditions, merely common examples of changing non-volatile registers. RSP is just another non-volatile (https://docs.microsoft.com/en-us/cpp/build/register-usage). A function is expected to return with the same RSP as it started with.
Another reason to change non-volatiles is to use them for local variables.
If you change a non-volatile, then you must first save it, and describe how you saved it. Alternatively, instead of saving it, you can describe how you changed it -- that is, you can state how much you subtracted from RSP, so that restore is not loading the old value, but just adding.
And then, the description of how you saved non-volatiles goes into xdata, which is found via pdata.
As well, if you have an exception handler, that is also described in the xdata.
So, by virtue of the base reasons of changing non-volatiles or having an exception handler, a frame function has pdata/xdata.
- Jay
No comments:
Post a Comment