RE: stackinit unit test failures on m68k

From: David Laight
Date: Thu Feb 29 2024 - 17:34:22 EST


...
> It is basically doing this:
>
> static void *fill_start, *target_start;
> static size_t fill_size, target_size;
>
> static noinline int leaf_char_array_none(unsigned long sp, bool fill,
> unsigned char *arg)
> {
> char buf[32];
> unsigned char var[16];
>
> target_start = &var;
> target_size = sizeof(var);
> /*
> * Keep this buffer around to make sure we've got a
> * stack frame of SOME kind...
> */
> memset(buf, (char)(sp & 0xff), sizeof(buf));
> /* Fill variable with 0xFF. */
> if (fill) {
> fill_start = &var;
> fill_size = sizeof(var);
> memset(fill_start,
> (char)((sp & 0xff) | forced_mask),
> fill_size);
> }
>
> /* Silence "never initialized" warnings. */
> do_nothing_char_array(var);
>
> /* Exfiltrate "var". */
> memcpy(check_buf, target_start, target_size);
>
> return (int)buf[0] | (int)buf[sizeof(buf) - 1];
> }
>
> and it's called as:
>
>
> ignored = leaf_char_array_none((unsigned long)&ignored, 1, zero);
> ...
> ignored = leaf_char_array_none((unsigned long)&ignored, 0, zero);
>
> The first call remembers where "var" is in the stack frame via the
> fill_start assignment, and the second call records where "var" is via
> the target_start assignment.
>
> The complaint is that it _changes_ between the two calls. ... Oh, I
> think I see what's happened. Between the two calls, the stack grows (and
> is for some reason not reclaimed) due to the KUNIT checks between the two
> leaf calls. Yes, moving that fixes it.

Is the noinline enough to stop gcc generating two copies of the
function for the different values of 'fill'?

You might need to call through a volatile global function pointer
variable?

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)