https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110027

--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Hongtao Liu from comment #19)
> (In reply to Jakub Jelinek from comment #17)
> > Both of the posted patches are incorrect, this needs to be fixed in
> > asan_emit_stack_protection, account for the different offsets[0] which
> > happens when a stack pointer guard is created.
> > I'll deal with it tomorrow.
> 
> It seems to me that the only offend place is where I've modifed, are there
> other places where align_frame_offset (ASAN_RED_ZONE_SIZE) is also added?
> 
> Also, your patch adds a gcc_assert for offset[0], which seems to me there
> was an assumption that offset[0] should be a multiple of alignb, thus making
> my patch more reasonable?

Your first patch aligned offsets[0] to maximum of alignb and
ASAN_RED_ZONE_SIZE.
But as I wrote in the reply to that mail, alignb there is the alignment of just
a single variable which is the first one to appear in the sorted list and is
placed in the highest spot in the stack frame.
That is not necessarily the largest alignment, the sorting ensures that it is a
variable with the largest size in the frame (and only if several of them have
equal size, largest alignment from the same sized ones).
Your second patch used maximum of BIGGEST_ALIGNMENT / BITS_PER_UNIT and
ASAN_RED_ZONE_SIZE.  That doesn't change anything at all when using
-mno-avx512f - offsets[0] is still just 32-byte aligned in that case relative
to top of frame, just changes the -mavx512f case to be 64-byte aligned
offsets[0] (aka offsets[0] is then either 0 or -64 instead of either 0 or -32).
 That will not help if any variable in the frame needs 128-byte, 256-byte,
512-byte ... 4096-byte alignment.
If you want to fix the bug in the spot you've touched, you'd need to walk all
the
stack_vars[stack_vars_sorted[si2]] for si2 [si + 1, n - 1] and for those where
the
loop would do anything (i.e.
stack_vars[i2].representative == i2
&& TREE_CODE (decl2) == SSA_NAME
   ? SA.partition_to_pseudo[var_to_partition (SA.map, decl2)] == NULL_RTX
   : DECL_RTL (decl2) == pc_rtx
and the pred applies (but that means also walking the earlier ones! because
with -fstack-protector* the vars can be processed in several calls) and
alignb2 * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT
and compute maximum of those alignments.
That maximum is already computed,
data->asan_alignb = MAX (data->asan_alignb, alignb);
computes that, but you get the final result only after you do all the
expand_stack_vars
calls.  You'd need to compute it before.

Though, that change would be still in the wrong place.
The thing is, it would be a waste of the precious stack space when it isn't
needed at all (e.g. when asan will not at compile time do the use after return
checking, or if it won't do it at runtime, or even if it will do at runtime it
will waste the space on the stack).
My patch enlarges if needed just the __asan_stack_malloc_N allocated chunk, not
the stack frame size.

Reply via email to