Stack scrubbing involves cooperation between a strub
context,
i.e., a function whose stack frame is to be zeroed-out, and its callers.
The caller initializes a stack watermark, the strub
context
updates the watermark according to its stack use, and the caller zeroes
it out once it regains control, whether by the callee’s returning or by
an exception.
Each of these steps is performed by a different builtin function call.
Calls to these builtins are introduced automatically, in response to
strub
attributes and command-line options; they are not expected
to be explicitly called by source code.
The functions that implement the builtins are available in libgcc but, depending on optimization levels, they are expanded internally, adjusted to account for inlining, and sometimes combined/deferred (e.g. passing the caller-supplied watermark on to callees, refraining from erasing stack areas that the caller will) to enable tail calls and to optimize for code size.
void
__builtin___strub_enter (void **wmptr)
¶This function initializes a stack watermark variable with the
current top of the stack. A call to this builtin function is introduced
before entering a strub
context. It remains as a function call
if optimization is not enabled.
void
__builtin___strub_update (void **wmptr)
¶This function updates a stack watermark variable with the current
top of the stack, if it tops the previous watermark. A call to this
builtin function is inserted within strub
contexts, whenever
additional stack space may have been used. It remains as a function
call at optimization levels lower than 2.
void
__builtin___strub_leave (void **wmptr)
¶This function overwrites the memory area between the current top of the
stack, and the watermarked address. A call to this builtin
function is inserted after leaving a strub
context. It remains
as a function call at optimization levels lower than 3, and it is guarded by
a condition at level 2.