Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PR target/111340
gcc/ChangeLog:
* config/i386/i386.c (output_pic_addr_const): Handle CONST_WIDE_INT.
Call output_addr_const for CASE_CONST_SCALAR_INT.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr111340.c: New test.
(cherry picked from commit 048927ed8561ca994ad853fe85ccf8c2ca07a8fe)
|
|
AArch64 normally puts the saved registers near the bottom of the frame,
immediately above any dynamic allocations. But this means that a
stack-smash attack on those dynamic allocations could overwrite the
saved registers without needing to reach as far as the stack smash
canary.
The same thing could also happen for variable-sized arguments that are
passed by value, since those are allocated before a call and popped on
return.
This patch avoids that by putting the locals (and thus the canary) below
the saved registers when stack smash protection is active.
The patch fixes CVE-2023-4039.
gcc/
* config/aarch64/aarch64.c (aarch64_save_regs_above_locals_p):
New function.
(aarch64_layout_frame): Use it to decide whether locals should
go above or below the saved registers.
(aarch64_expand_prologue): Update stack layout comment.
Emit a stack tie after the final adjustment.
gcc/testsuite/
* gcc.target/aarch64/stack-protector-8.c: New test.
* gcc.target/aarch64/stack-protector-9.c: Likewise.
|
|
After previous patches, it's no longer necessary to store
saved_regs_size and below_hard_fp_saved_regs_size in the frame info.
All measurements instead use the top or bottom of the frame as
reference points.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::saved_regs_size)
(aarch64_frame::below_hard_fp_saved_regs_size): Delete.
* config/aarch64/aarch64.c (aarch64_layout_frame): Update accordingly.
|
|
The stack frame is currently divided into three areas:
A: the area above the hard frame pointer
B: the SVE saves below the hard frame pointer
C: the outgoing arguments
If the stack frame is allocated in one chunk, the allocation needs a
probe if the frame size is >= guard_size - 1KiB. In addition, if the
function is not a leaf function, it must probe an address no more than
1KiB above the outgoing SP. We ensured the second condition by
(1) using single-chunk allocations for non-leaf functions only if
the link register save slot is within 512 bytes of the bottom
of the frame; and
(2) using the link register save as a probe (meaning, for instance,
that it can't be individually shrink wrapped)
If instead the stack is allocated in multiple chunks, then:
* an allocation involving only the outgoing arguments (C above) requires
a probe if the allocation size is > 1KiB
* any other allocation requires a probe if the allocation size
is >= guard_size - 1KiB
* second and subsequent allocations require the previous allocation
to probe at the bottom of the allocated area, regardless of the size
of that previous allocation
The final point means that, unlike for single allocations,
it can be necessary to have both a non-SVE register probe and
an SVE register probe. For example:
* allocate A, probe using a non-SVE register save
* allocate B, probe using an SVE register save
* allocate C
The non-SVE register used in this case was again the link register.
It was previously used even if the link register save slot was some
bytes above the bottom of the non-SVE register saves, but an earlier
patch avoided that by putting the link register save slot first.
As a belt-and-braces fix, this patch explicitly records which
probe registers we're using and allows the non-SVE probe to be
whichever register comes first (as for SVE).
The patch also avoids unnecessary probes in sve/pcs/stack_clash_3.c.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::sve_save_and_probe)
(aarch64_frame::hard_fp_save_and_probe): New fields.
* config/aarch64/aarch64.c (aarch64_layout_frame): Initialize them.
Rather than asserting that a leaf function saves LR, instead assert
that a leaf function saves something.
(aarch64_get_separate_components): Prevent the chosen probe
registers from being individually shrink-wrapped.
(aarch64_allocate_and_probe_stack_space): Remove workaround for
probe registers that aren't at the bottom of the previous allocation.
gcc/testsuite/
* gcc.target/aarch64/sve/pcs/stack_clash_3.c: Avoid redundant probes.
|
|
Previous patches ensured that the final frame allocation only needs
a probe when the size is strictly greater than 1KiB. It's therefore
safe to use the normal 1024 probe offset in all cases.
The main motivation for doing this is to simplify the code and
remove the number of special cases.
gcc/
* config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space):
Always probe the residual allocation at offset 1024, asserting
that that is in range.
gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-17.c: Expect the probe
to be at offset 1024 rather than offset 0.
* gcc.target/aarch64/stack-check-prologue-18.c: Likewise.
|
|
-fstack-clash-protection uses the save of LR as a probe for the next
allocation. The next allocation could be:
* another part of the static frame, e.g. when allocating SVE save slots
or outgoing arguments
* an alloca in the same function
* an allocation made by a callee function
However, when -fomit-frame-pointer is used, the LR save slot is placed
above the other GPR save slots. It could therefore be up to 80 bytes
above the base of the GPR save area (which is also the hard fp address).
aarch64_allocate_and_probe_stack_space took this into account when
deciding how much subsequent space could be allocated without needing
a probe. However, it interacted badly with:
/* If doing a small final adjustment, we always probe at offset 0.
This is done to avoid issues when LR is not at position 0 or when
the final adjustment is smaller than the probing offset. */
else if (final_adjustment_p && rounded_size == 0)
residual_probe_offset = 0;
which forces any allocation that is smaller than the guard page size
to be probed at offset 0 rather than the usual offset 1024. It was
therefore possible to construct cases in which we had:
* a probe using LR at SP + 80 bytes (or some other value >= 16)
* an allocation of the guard page size - 16 bytes
* a probe at SP + 0
which allocates guard page size + 64 consecutive unprobed bytes.
This patch requires the LR probe to be in the first 16 bytes of the
save area when stack clash protection is active. Doing it
unconditionally would cause code-quality regressions, but a later
patch deals with that.
The new comment doesn't say that the probe register is required
to be LR, since a later patch removes that restriction.
gcc/
* config/aarch64/aarch64.c (aarch64_layout_frame): Ensure that
the LR save slot is in the first 16 bytes of the register save area.
(aarch64_allocate_and_probe_stack_space): Remove workaround for
when LR was not in the first 16 bytes.
gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-18.c: New test.
|
|
The AArch64 ABI says that, when stack clash protection is used,
there can be a maximum of 1KiB of unprobed space at sp on entry
to a function. Therefore, we need to probe when allocating
>= guard_size - 1KiB of data (>= rather than >). This is what
GCC does.
If an allocation is exactly guard_size bytes, it is enough to allocate
those bytes and probe once at offset 1024. It isn't possible to use a
single probe at any other offset: higher would conmplicate later code,
by leaving more unprobed space than usual, while lower would risk
leaving an entire page unprobed. For simplicity, the code probes all
allocations at offset 1024.
Some register saves also act as probes. If we need to allocate
more space below the last such register save probe, we need to
probe the allocation if it is > 1KiB. Again, this allocation is
then sometimes (but not always) probed at offset 1024. This sort of
allocation is currently only used for outgoing arguments, which are
rarely this big.
However, the code also probed if this final outgoing-arguments
allocation was == 1KiB, rather than just > 1KiB. This isn't
necessary, since the register save then probes at offset 1024
as required. Continuing to probe allocations of exactly 1KiB
would complicate later patches.
gcc/
* config/aarch64/aarch64.c (aarch64_allocate_and_probe_stack_space):
Don't probe final allocations that are exactly 1KiB in size (after
unprobed space above the final allocation has been deducted).
gcc/testsuite/
* gcc.target/aarch64/stack-check-prologue-17.c: New test.
|
|
This patch just changes a calculation of initial_adjust
to one that makes it slightly more obvious that the total
adjustment is frame.frame_size.
gcc/
* config/aarch64/aarch64.c (aarch64_layout_frame): Tweak
calculation of initial_adjust for frames in which all saves
are SVE saves.
|
|
After previous patches, it no longer really makes sense to allocate
the top of the frame in terms of varargs_and_saved_regs_size and
saved_regs_and_above.
gcc/
* config/aarch64/aarch64.c (aarch64_layout_frame): Simplify
the allocation of the top of the frame.
|
|
reg_offset was measured from the bottom of the saved register area.
This made perfect sense with the original layout, since the bottom
of the saved register area was also the hard frame pointer address.
It became slightly less obvious with SVE, since we save SVE
registers below the hard frame pointer, but it still made sense.
However, if we want to allow different frame layouts, it's more
convenient and obvious to measure reg_offset from the bottom of
the frame. After previous patches, it's also a slight simplification
in its own right.
gcc/
* config/aarch64/aarch64.h (aarch64_frame): Add comment above
reg_offset.
* config/aarch64/aarch64.c (aarch64_layout_frame): Walk offsets
from the bottom of the frame, rather than the bottom of the saved
register area. Measure reg_offset from the bottom of the frame
rather than the bottom of the saved register area.
(aarch64_save_callee_saves): Update accordingly.
(aarch64_restore_callee_saves): Likewise.
(aarch64_get_separate_components): Likewise.
(aarch64_process_components): Likewise.
|
|
This patch fixes another case in which a value was described with
an “upside-down” view.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::frame_size): Tweak comment.
|
|
Similarly to the previous locals_offset patch, hard_fp_offset
was described as:
/* Offset from the base of the frame (incomming SP) to the
hard_frame_pointer. This value is always a multiple of
STACK_BOUNDARY. */
poly_int64 hard_fp_offset;
which again took an “upside-down” view: higher offsets meant lower
addresses. This patch renames the field to bytes_above_hard_fp instead.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::hard_fp_offset): Rename
to...
(aarch64_frame::bytes_above_hard_fp): ...this.
* config/aarch64/aarch64.c (aarch64_layout_frame)
(aarch64_expand_prologue): Update accordingly.
(aarch64_initial_elimination_offset): Likewise.
|
|
locals_offset was described as:
/* Offset from the base of the frame (incomming SP) to the
top of the locals area. This value is always a multiple of
STACK_BOUNDARY. */
This is implicitly an “upside down” view of the frame: the incoming
SP is at offset 0, and anything N bytes below the incoming SP is at
offset N (rather than -N).
However, reg_offset instead uses a “right way up” view; that is,
it views offsets in address terms. Something above X is at a
positive offset from X and something below X is at a negative
offset from X.
Also, even on FRAME_GROWS_DOWNWARD targets like AArch64,
target-independent code views offsets in address terms too:
locals are allocated at negative offsets to virtual_stack_vars.
It seems confusing to have *_offset fields of the same structure
using different polarities like this. This patch tries to avoid
that by renaming locals_offset to bytes_above_locals.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::locals_offset): Rename to...
(aarch64_frame::bytes_above_locals): ...this.
* config/aarch64/aarch64.c (aarch64_layout_frame)
(aarch64_initial_elimination_offset): Update accordingly.
|
|
After previous patches, it is no longer necessary to calculate
a chain_offset in cases where there is no chain record.
gcc/
* config/aarch64/aarch64.c (aarch64_expand_prologue): Move the
calculation of chain_offset into the emit_frame_chain block.
|
|
aarch64_save_callee_saves and aarch64_restore_callee_saves took
a parameter called start_offset that gives the offset of the
bottom of the saved register area from the current stack pointer.
However, it's more convenient for later patches if we use the
bottom of the entire frame as the reference point, rather than
the bottom of the saved registers.
Doing that removes the need for the callee_offset field.
Other than that, this is not a win on its own. It only really
makes sense in combination with the follow-on patches.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::callee_offset): Delete.
* config/aarch64/aarch64.c (aarch64_layout_frame): Remove
callee_offset handling.
(aarch64_save_callee_saves): Replace the start_offset parameter
with a bytes_below_sp parameter.
(aarch64_restore_callee_saves): Likewise.
(aarch64_expand_prologue): Update accordingly.
(aarch64_expand_epilogue): Likewise.
|
|
Following on from the previous bytes_below_saved_regs patch, this one
records the number of bytes that are below the hard frame pointer.
This eventually replaces below_hard_fp_saved_regs_size.
If a frame pointer is not needed, the epilogue adds final_adjust
to the stack pointer before restoring registers:
aarch64_add_sp (tmp1_rtx, tmp0_rtx, final_adjust, true);
Therefore, if the epilogue needs to restore the stack pointer from
the hard frame pointer, the directly corresponding offset is:
-bytes_below_hard_fp + final_adjust
i.e. go from the hard frame pointer to the bottom of the frame,
then add the same amount as if we were using the stack pointer
from the outset.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::bytes_below_hard_fp): New
field.
* config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it.
(aarch64_expand_epilogue): Use it instead of
below_hard_fp_saved_regs_size.
|
|
The frame layout code currently hard-codes the assumption that
the number of bytes below the saved registers is equal to the
size of the outgoing arguments. This patch abstracts that
value into a new field of aarch64_frame.
gcc/
* config/aarch64/aarch64.h (aarch64_frame::bytes_below_saved_regs): New
field.
* config/aarch64/aarch64.c (aarch64_layout_frame): Initialize it,
and use it instead of crtl->outgoing_args_size.
(aarch64_get_separate_components): Use bytes_below_saved_regs instead
of outgoing_args_size.
(aarch64_process_components): Likewise.
|
|
If a frame has no saved registers, it can be allocated in one go.
There is no need to treat the areas below and above the saved
registers as separate.
And if we allocate the frame in one go, it should be allocated
as the initial_adjust rather than the final_adjust. This allows the
frame size to grow to guard_size - guard_used_by_caller before a stack
probe is needed. (A frame with no register saves is necessarily a
leaf frame.)
This is a no-op as thing stand, since a leaf function will have
no outgoing arguments, and so all the frame will be above where
the saved registers normally go.
gcc/
* config/aarch64/aarch64.c (aarch64_layout_frame): Explicitly
allocate the frame in one go if there are no saved registers.
|
|
When we emit the frame chain, i.e. when we reach Here in this statement
of aarch64_expand_prologue:
if (emit_frame_chain)
{
// Here
...
}
the stack is in one of two states:
- We've allocated up to the frame chain, but no more.
- We've allocated the whole frame, and the frame chain is within easy
reach of the new SP.
The offset of the frame chain from the current SP is available
in aarch64_frame as callee_offset. It is also available as the
chain_offset local variable, where the latter is calculated from other
data. (However, chain_offset is not always equal to callee_offset when
!emit_frame_chain, so chain_offset isn't redundant.)
In c600df9a4060da3c6121ff4d0b93f179eafd69d1 I switched to using
chain_offset for the initialisation of the hard frame pointer:
aarch64_add_offset (Pmode, hard_frame_pointer_rtx,
- stack_pointer_rtx, callee_offset,
+ stack_pointer_rtx, chain_offset,
tmp1_rtx, tmp0_rtx, frame_pointer_needed);
But the later REG_CFA_ADJUST_CFA handling still used callee_offset.
I think the difference is harmless, but it's more logical for the
CFA note to be in sync, and it's more convenient for later patches
if it uses chain_offset.
gcc/
* config/aarch64/aarch64.c (aarch64_expand_prologue): Use
chain_offset rather than callee_offset.
|
|
aarch64_layout_frame uses a shorthand for referring to
cfun->machine->frame:
aarch64_frame &frame = cfun->machine->frame;
This patch does the same for some other heavy users of the structure.
No functional change intended.
gcc/
* config/aarch64/aarch64.c (aarch64_save_callee_saves): Use
a local shorthand for cfun->machine->frame.
(aarch64_restore_callee_saves, aarch64_get_separate_components):
(aarch64_process_components): Likewise.
(aarch64_allocate_and_probe_stack_space): Likewise.
(aarch64_expand_prologue, aarch64_expand_epilogue): Likewise.
(aarch64_layout_frame): Use existing shorthand for one more case.
|
|
gcc/
PR target/96762
* config/rs6000/rs6000-string.c (expand_block_move): Call vector
load/store with length only on 64-bit Power10.
gcc/testsuite/
PR target/96762
* gcc.target/powerpc/pr96762.c: New.
(cherry picked from commit 946b8967b905257ac9f140225db744c9a6ab91be)
|
|
|
|
For backward compatibility we still want to allow patterns like
this->A<T>::foo, but the template keyword in a qualified name is
specifically to specify that a dependent name is a template, so don't look
in the enclosing scope at all.
Also fix handling of dependent bases: if member lookup in the current
instantiation fails and we have dependent bases, the lookup is dependent.
We were already handling that for the case where lookup in the enclosing
scope also fails, but we also want it to affect that lookup itself.
PR c++/106310
gcc/cp/ChangeLog:
* parser.c (cp_parser_template_name): Skip non-member
lookup after the template keyword.
(cp_parser_lookup_name): Pass down template_keyword_p.
gcc/testsuite/ChangeLog:
* g++.dg/template/template-keyword4.C: New test.
|
|
Here it turns out I also needed to adjust cfun when stepping out of the
member function to instantiate the DMI. But instead of adding that tweak,
let's unify with instantiate_body and just push_to_top_level instead of
trying to do the minimum subset of it. There was no measurable change in
compile time on stdc++.h.
This should also resolve 109506 without yet another tweak.
PR c++/106890
PR c++/109666
gcc/cp/ChangeLog:
* name-lookup.c (maybe_push_to_top_level)
(maybe_pop_from_top_level): Split out...
* pt.c (instantiate_body): ...from here.
* init.c (maybe_instantiate_nsdmi_init): Use them.
* name-lookup.h: Declare them..
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/nsdmi-array2.C: New test.
* g++.dg/cpp0x/nsdmi-template25.C: New test.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|