Commit c35af30f by Eric Botcazou Committed by Eric Botcazou

re PR target/10127 (-fstack-check let's program crash)

	PR target/10127
	PR ada/20548
	* expr.h (anti_adjust_stack_and_probe): Declare.
	* explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK
	parameter and rewrite head comment.
	(allocate_dynamic_stack_space): Adjust call to above function.
	* function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP.

	* tree.h (dwarf2out_args_size): Delete.
	* dwarf2out.c (dwarf2out_args_size): Make static and move around.
	(dwarf2out_args_size_adjust): Delete prototype and move around.
	(dwarf2out_frame_debug_expr): Do not record arg size adjustments for
	ACCUMULATE_OUTGOING_ARGS targets.

From-SVN: r154079
parent 35230a78
2009-11-10 Eric Botcazou <ebotcazou@adacore.com>
PR target/10127
PR ada/20548
* expr.h (anti_adjust_stack_and_probe): Declare.
* explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK
parameter and rewrite head comment.
(allocate_dynamic_stack_space): Adjust call to above function.
* function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP.
* tree.h (dwarf2out_args_size): Delete.
* dwarf2out.c (dwarf2out_args_size): Make static and move around.
(dwarf2out_args_size_adjust): Delete prototype and move around.
(dwarf2out_frame_debug_expr): Do not record arg size adjustments for
ACCUMULATE_OUTGOING_ARGS targets.
2009-11-10 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc.c (print_operand) <')'>: Test for a non-null
DECL_SIZE of DECL_RESULT before evaluating it.
......@@ -470,8 +470,6 @@ static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
static void output_cfi_directive (dw_cfi_ref);
static void output_call_frame_info (int);
static void dwarf2out_note_section_used (void);
static void dwarf2out_stack_adjust (rtx, bool);
static void dwarf2out_args_size_adjust (HOST_WIDE_INT, const char *);
static void flush_queued_reg_saves (void);
static bool clobbers_queued_reg_save (const_rtx);
static void dwarf2out_frame_debug_expr (rtx, const char *);
......@@ -1157,25 +1155,6 @@ dwarf2out_window_save (const char *label)
add_fde_cfi (label, cfi);
}
/* Add a CFI to update the running total of the size of arguments
pushed onto the stack. */
void
dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
{
dw_cfi_ref cfi;
if (size == old_args_size)
return;
old_args_size = size;
cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
add_fde_cfi (label, cfi);
}
/* Entry point for saving a register to the stack. REG is the GCC register
number. LABEL and OFFSET are passed to reg_save. */
......@@ -1526,6 +1505,48 @@ compute_barrier_args_size (void)
VEC_free (rtx, heap, next);
}
/* Add a CFI to update the running total of the size of arguments
pushed onto the stack. */
static void
dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
{
dw_cfi_ref cfi;
if (size == old_args_size)
return;
old_args_size = size;
cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
add_fde_cfi (label, cfi);
}
/* Adjust args_size based on stack adjustment OFFSET. */
static void
dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label)
{
if (cfa.reg == STACK_POINTER_REGNUM)
cfa.offset += offset;
if (cfa_store.reg == STACK_POINTER_REGNUM)
cfa_store.offset += offset;
#ifndef STACK_GROWS_DOWNWARD
offset = -offset;
#endif
args_size += offset;
if (args_size < 0)
args_size = 0;
def_cfa_1 (label, &cfa);
if (flag_asynchronous_unwind_tables)
dwarf2out_args_size (label, args_size);
}
/* Check INSN to see if it looks like a push or a stack adjustment, and
make a note of it if it does. EH uses this information to find out how
......@@ -1619,30 +1640,6 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
dwarf2out_args_size_adjust (offset, label);
}
/* Adjust args_size based on stack adjustment OFFSET. */
static void
dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label)
{
if (cfa.reg == STACK_POINTER_REGNUM)
cfa.offset += offset;
if (cfa_store.reg == STACK_POINTER_REGNUM)
cfa_store.offset += offset;
#ifndef STACK_GROWS_DOWNWARD
offset = -offset;
#endif
args_size += offset;
if (args_size < 0)
args_size = 0;
def_cfa_1 (label, &cfa);
if (flag_asynchronous_unwind_tables)
dwarf2out_args_size (label, args_size);
}
#endif
/* We delay emitting a register save until either (a) we reach the end
......@@ -2209,7 +2206,8 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
&& (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
&& (RTX_FRAME_RELATED_P (elem) || par_index == 0))
dwarf2out_frame_debug_expr (elem, label);
else if (GET_CODE (elem) == SET
else if (!ACCUMULATE_OUTGOING_ARGS
&& GET_CODE (elem) == SET
&& par_index != 0
&& !RTX_FRAME_RELATED_P (elem))
{
......
......@@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see
static rtx break_out_memory_refs (rtx);
static void emit_stack_probe (rtx);
static void anti_adjust_stack_and_probe (rtx);
/* Truncate and perhaps sign-extend C as appropriate for MODE. */
......@@ -1308,7 +1307,7 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
}
if (flag_stack_check && STACK_CHECK_MOVING_SP)
anti_adjust_stack_and_probe (size);
anti_adjust_stack_and_probe (size, false);
else
anti_adjust_stack (size);
......@@ -1545,13 +1544,17 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
}
}
/* Adjust the stack by SIZE bytes while probing it. Note that we skip the
probe for the first interval + a small dope of 4 words and instead probe
that many bytes past the specified size to maintain a protection area. */
/* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes)
while probing it. This pushes when SIZE is positive. SIZE need not
be constant. If ADJUST_BACK is true, adjust back the stack pointer
by plus SIZE at the end. */
static void
anti_adjust_stack_and_probe (rtx size)
void
anti_adjust_stack_and_probe (rtx size, bool adjust_back)
{
/* We skip the probe for the first interval + a small dope of 4 words and
probe that many bytes past the specified size to maintain a protection
area at the botton of the stack. */
const int dope = 4 * UNITS_PER_WORD;
/* First ensure SIZE is Pmode. */
......@@ -1660,8 +1663,11 @@ anti_adjust_stack_and_probe (rtx size)
}
}
/* Adjust back to account for the additional first interval. */
adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
/* Adjust back and account for the additional first interval. */
if (adjust_back)
adjust_stack (plus_constant (size, PROBE_INTERVAL + dope));
else
adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
}
/* Return an rtx representing the register or memory location
......
......@@ -767,6 +767,9 @@ extern void adjust_stack (rtx);
/* Add some bytes to the stack. An rtx says how many. */
extern void anti_adjust_stack (rtx);
/* Add some bytes to the stack while probing it. An rtx says how many. */
extern void anti_adjust_stack_and_probe (rtx, bool);
/* This enum is used for the following two functions. */
enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
......
......@@ -4642,9 +4642,12 @@ expand_function_end (void)
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (CALL_P (insn))
{
rtx max_frame_size = GEN_INT (STACK_CHECK_MAX_FRAME_SIZE);
start_sequence ();
probe_stack_range (STACK_OLD_CHECK_PROTECT,
GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
if (STACK_CHECK_MOVING_SP)
anti_adjust_stack_and_probe (max_frame_size, true);
else
probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
seq = get_insns ();
end_sequence ();
emit_insn_before (seq, stack_check_probe_note);
......
......@@ -5161,11 +5161,6 @@ extern void dwarf2out_def_cfa (const char *, unsigned, HOST_WIDE_INT);
extern void dwarf2out_window_save (const char *);
/* Add a CFI to update the running total of the size of arguments pushed
onto the stack. */
extern void dwarf2out_args_size (const char *, HOST_WIDE_INT);
/* Entry point for saving a register to the stack. */
extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment