+++ /dev/null
-diff -urN gcc-3.3.1/gcc/Makefile.in gcc-3.3.1-pp/gcc/Makefile.in
---- gcc-3.3.1/gcc/Makefile.in 2003-08-03 15:48:36.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/Makefile.in 2003-09-12 13:40:28.000000000 +0000
-@@ -387,7 +387,7 @@
- # Options to use when compiling libgcc2.a.
- #
- LIBGCC2_DEBUG_CFLAGS = -g
--LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED @inhibit_libc@
-+LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED @inhibit_libc@ -fno-stack-protector
-
- # Additional options to use when compiling libgcc2.a.
- # Some targets override this to -isystem include
-@@ -764,7 +764,7 @@
- sibcall.o simplify-rtx.o ssa.o ssa-ccp.o ssa-dce.o stmt.o \
- stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
- tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
-- et-forest.o $(GGC) $(out_object_file) $(EXTRA_OBJS)
-+ et-forest.o protector.o $(GGC) $(out_object_file) $(EXTRA_OBJS)
-
- BACKEND = main.o libbackend.a
-
-@@ -798,7 +798,7 @@
-
- LIB2FUNCS_2 = _floatdixf _fixunsxfsi _fixtfdi _fixunstfdi _floatditf \
- _clear_cache _trampoline __main _exit _absvsi2 _absvdi2 _addvsi3 \
-- _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors
-+ _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors _stack_smash_handler
-
- # Defined in libgcc2.c, included only in the static library.
- LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp
-@@ -1410,7 +1410,7 @@
- ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
- langhooks.h insn-flags.h options.h cfglayout.h real.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-- -DTARGET_NAME=\"$(target_alias)\" \
-+ -DSTACK_PROTECTOR -DTARGET_NAME=\"$(target_alias)\" \
- -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
- main.o : main.c $(CONFIG_H) $(SYSTEM_H) toplev.h
-
-@@ -1665,6 +1665,7 @@
- output.h except.h $(TM_P_H) real.h
- params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
- hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) $(HOOKS_H)
-+protector.o: protector.c $(CONFIG_H)
-
- $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) $(GGC_H) \
- $(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
-diff -urN gcc-3.3.1/gcc/calls.c gcc-3.3.1-pp/gcc/calls.c
---- gcc-3.3.1/gcc/calls.c 2003-07-18 02:58:25.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/calls.c 2003-09-12 13:40:28.000000000 +0000
-@@ -2327,7 +2327,7 @@
- /* For variable-sized objects, we must be called with a target
- specified. If we were to allocate space on the stack here,
- we would have no way of knowing when to free it. */
-- rtx d = assign_temp (TREE_TYPE (exp), 1, 1, 1);
-+ rtx d = assign_temp (TREE_TYPE (exp), 5, 1, 1);
-
- mark_temp_addr_taken (d);
- structure_value_addr = XEXP (d, 0);
-diff -urN gcc-3.3.1/gcc/combine.c gcc-3.3.1-pp/gcc/combine.c
---- gcc-3.3.1/gcc/combine.c 2003-03-24 11:37:32.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/combine.c 2003-09-12 13:40:28.000000000 +0000
-@@ -3859,7 +3859,17 @@
- rtx inner_op0 = XEXP (XEXP (x, 0), 1);
- rtx inner_op1 = XEXP (x, 1);
- rtx inner;
--
-+
-+#ifndef FRAME_GROWS_DOWNWARD
-+ if (flag_propolice_protection
-+ && code == PLUS
-+ && other == frame_pointer_rtx
-+ && GET_CODE (inner_op0) == CONST_INT
-+ && GET_CODE (inner_op1) == CONST_INT
-+ && INTVAL (inner_op0) > 0
-+ && INTVAL (inner_op0) + INTVAL (inner_op1) <= 0)
-+ return x;
-+#endif
- /* Make sure we pass the constant operand if any as the second
- one if this is a commutative operation. */
- if (CONSTANT_P (inner_op0) && GET_RTX_CLASS (code) == 'c')
-@@ -4272,6 +4282,11 @@
- they are now checked elsewhere. */
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
-+#ifndef FRAME_GROWS_DOWNWARD
-+ if (! (flag_propolice_protection
-+ && XEXP (XEXP (x, 0), 0) == frame_pointer_rtx
-+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
-+#endif
- return gen_binary (PLUS, mode,
- gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
- XEXP (x, 1)),
-@@ -4400,7 +4415,10 @@
-
- /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
- integers. */
-- if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
-+ if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode)
-+ && (! (flag_propolice_protection
-+ && XEXP (XEXP (x, 1), 0) == frame_pointer_rtx
-+ && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)))
- return gen_binary (MINUS, mode,
- gen_binary (MINUS, mode, XEXP (x, 0),
- XEXP (XEXP (x, 1), 0)),
-diff -urN gcc-3.3.1/gcc/config/t-linux gcc-3.3.1-pp/gcc/config/t-linux
---- gcc-3.3.1/gcc/config/t-linux 2003-06-04 16:56:11.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/config/t-linux 2003-09-12 13:40:28.000000000 +0000
-@@ -4,7 +4,7 @@
- # Compile crtbeginS.o and crtendS.o with pic.
- CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
- # Compile libgcc2.a with pic.
--TARGET_LIBGCC2_CFLAGS = -fPIC
-+TARGET_LIBGCC2_CFLAGS = -fPIC -DHAVE_SYSLOG
-
- # Override t-slibgcc-elf-ver to export some libgcc symbols with
- # the symbol versions that glibc used.
-diff -urN gcc-3.3.1/gcc/cse.c gcc-3.3.1-pp/gcc/cse.c
---- gcc-3.3.1/gcc/cse.c 2003-04-29 19:16:40.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/cse.c 2003-09-12 13:40:28.000000000 +0000
-@@ -4288,7 +4288,14 @@
-
- if (new_const == 0)
- break;
--
-+#ifndef FRAME_GROWS_DOWNWARD
-+ if (flag_propolice_protection
-+ && GET_CODE (y) == PLUS
-+ && XEXP (y, 0) == frame_pointer_rtx
-+ && INTVAL (inner_const) > 0
-+ && INTVAL (new_const) <= 0)
-+ break;
-+#endif
- /* If we are associating shift operations, don't let this
- produce a shift of the size of the object or larger.
- This could occur when we follow a sign-extend by a right
-@@ -4823,6 +4830,13 @@
- if (SET_DEST (x) == pc_rtx
- && GET_CODE (SET_SRC (x)) == LABEL_REF)
- ;
-+ /* cut the reg propagation of stack-protected argument */
-+ else if (x->volatil) {
-+ rtx x1 = SET_DEST (x);
-+ if (GET_CODE (x1) == SUBREG && GET_CODE (SUBREG_REG (x1)) == REG)
-+ x1 = SUBREG_REG (x1);
-+ make_new_qty (REGNO (x1), GET_MODE (x1));
-+ }
-
- /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
- The hard function value register is used only once, to copy to
-diff -urN gcc-3.3.1/gcc/explow.c gcc-3.3.1-pp/gcc/explow.c
---- gcc-3.3.1/gcc/explow.c 2003-04-07 22:58:12.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/explow.c 2003-09-12 13:40:28.000000000 +0000
-@@ -86,7 +86,8 @@
- rtx tem;
- int all_constant = 0;
-
-- if (c == 0)
-+ if (c == 0
-+ && !(flag_propolice_protection && x == virtual_stack_vars_rtx))
- return x;
-
- restart:
-@@ -187,7 +188,8 @@
- break;
- }
-
-- if (c != 0)
-+ if (c != 0
-+ || (flag_propolice_protection && x == virtual_stack_vars_rtx))
- x = gen_rtx_PLUS (mode, x, GEN_INT (c));
-
- if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
-@@ -531,6 +533,21 @@
- in certain cases. This is not necessary since the code
- below can handle all possible cases, but machine-dependent
- transformations can make better code. */
-+ if (flag_propolice_protection)
-+ {
-+#define FRAMEADDR_P(X) (GET_CODE (X) == PLUS \
-+ && XEXP (X, 0) == virtual_stack_vars_rtx \
-+ && GET_CODE (XEXP (X, 1)) == CONST_INT)
-+ rtx y;
-+ if (FRAMEADDR_P (x)) goto win;
-+ for (y=x; y!=0 && GET_CODE (y)==PLUS; y = XEXP (y, 0))
-+ {
-+ if (FRAMEADDR_P (XEXP (y, 0)))
-+ XEXP (y, 0) = force_reg (GET_MODE (XEXP (y, 0)), XEXP (y, 0));
-+ if (FRAMEADDR_P (XEXP (y, 1)))
-+ XEXP (y, 1) = force_reg (GET_MODE (XEXP (y, 1)), XEXP (y, 1));
-+ }
-+ }
- LEGITIMIZE_ADDRESS (x, oldx, mode, win);
-
- /* PLUS and MULT can appear in special ways
-diff -urN gcc-3.3.1/gcc/expr.c gcc-3.3.1-pp/gcc/expr.c
---- gcc-3.3.1/gcc/expr.c 2003-07-24 19:11:20.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/expr.c 2003-09-12 13:40:28.000000000 +0000
-@@ -45,6 +45,7 @@
- #include "langhooks.h"
- #include "intl.h"
- #include "tm_p.h"
-+#include "protector.h"
-
- /* Decide whether a function's arguments should be processed
- from first to last or from last to first.
-@@ -1518,7 +1519,7 @@
-
- if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
- {
-- data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
-+ data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len-GET_MODE_SIZE (mode)));
- data.autinc_from = 1;
- data.explicit_inc_from = -1;
- }
-@@ -1532,7 +1533,7 @@
- data.from_addr = copy_addr_to_reg (from_addr);
- if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
- {
-- data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
-+ data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len-GET_MODE_SIZE (mode)));
- data.autinc_to = 1;
- data.explicit_inc_to = -1;
- }
-@@ -1649,11 +1650,13 @@
- from1 = adjust_address (data->from, mode, data->offset);
-
- if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
-- emit_insn (gen_add2_insn (data->to_addr,
-- GEN_INT (-(HOST_WIDE_INT)size)));
-+ if (data->explicit_inc_to < -1)
-+ emit_insn (gen_add2_insn (data->to_addr,
-+ GEN_INT (-(HOST_WIDE_INT)size)));
- if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
-- emit_insn (gen_add2_insn (data->from_addr,
-- GEN_INT (-(HOST_WIDE_INT)size)));
-+ if (data->explicit_inc_from < -1)
-+ emit_insn (gen_add2_insn (data->from_addr,
-+ GEN_INT (-(HOST_WIDE_INT)size)));
-
- if (data->to)
- emit_insn ((*genfun) (to1, from1));
-@@ -2826,7 +2829,7 @@
-
- if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
- {
-- data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len));
-+ data->to_addr = copy_addr_to_reg (plus_constant (to_addr, data->len-GET_MODE_SIZE (mode)));
- data->autinc_to = 1;
- data->explicit_inc_to = -1;
- }
-@@ -2897,8 +2900,9 @@
- to1 = adjust_address (data->to, mode, data->offset);
-
- if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
-- emit_insn (gen_add2_insn (data->to_addr,
-- GEN_INT (-(HOST_WIDE_INT) size)));
-+ if (data->explicit_inc_to < -1)
-+ emit_insn (gen_add2_insn (data->to_addr,
-+ GEN_INT (-(HOST_WIDE_INT) size)));
-
- cst = (*data->constfun) (data->constfundata, data->offset, mode);
- emit_insn ((*genfun) (to1, cst));
-@@ -5894,7 +5898,9 @@
- && GET_CODE (XEXP (value, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
- && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
-- && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
-+ && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER
-+ && (!flag_propolice_protection
-+ || XEXP (XEXP (value, 0), 0) != virtual_stack_vars_rtx))
- {
- rtx temp = expand_simple_binop (GET_MODE (value), code,
- XEXP (XEXP (value, 0), 0), op2,
-@@ -8070,7 +8076,8 @@
- /* If adding to a sum including a constant,
- associate it to put the constant outside. */
- if (GET_CODE (op1) == PLUS
-- && CONSTANT_P (XEXP (op1, 1)))
-+ && CONSTANT_P (XEXP (op1, 1))
-+ && !(flag_propolice_protection && (contains_fp (op0) || contains_fp (op1))))
- {
- rtx constant_term = const0_rtx;
-
-diff -urN gcc-3.3.1/gcc/flags.h gcc-3.3.1-pp/gcc/flags.h
---- gcc-3.3.1/gcc/flags.h 2003-06-20 21:18:41.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/flags.h 2003-09-12 13:40:28.000000000 +0000
-@@ -690,4 +690,12 @@
- #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
- (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
-
-+/* Nonzero means use propolice as a stack protection method */
-+
-+extern int flag_propolice_protection;
-+
-+/* Warn when not issuing stack smashing protection for some reason */
-+
-+extern int warn_stack_protector;
-+
- #endif /* ! GCC_FLAGS_H */
-diff -urN gcc-3.3.1/gcc/function.c gcc-3.3.1-pp/gcc/function.c
---- gcc-3.3.1/gcc/function.c 2003-04-10 22:26:04.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/function.c 2003-09-12 13:40:28.000000000 +0000
-@@ -59,6 +59,7 @@
- #include "tm_p.h"
- #include "integrate.h"
- #include "langhooks.h"
-+#include "protector.h"
-
- #ifndef TRAMPOLINE_ALIGNMENT
- #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
-@@ -142,6 +143,10 @@
- /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
- in this function. */
- static GTY(()) varray_type sibcall_epilogue;
-+
-+/* Current boundary mark for character arrays. */
-+int temp_boundary_mark = 0;
-+
- \f
- /* In order to evaluate some expressions, such as function calls returning
- structures in memory, we need to temporarily allocate stack locations.
-@@ -195,6 +200,8 @@
- /* The size of the slot, including extra space for alignment. This
- info is for combine_temp_slots. */
- HOST_WIDE_INT full_size;
-+ /* Boundary mark of a character array and the others. This info is for propolice */
-+ int boundary_mark;
- };
- \f
- /* This structure is used to record MEMs or pseudos used to replace VAR, any
-@@ -629,6 +636,7 @@
- whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3
- if we are to allocate something at an inner level to be treated as
- a variable in the block (e.g., a SAVE_EXPR).
-+ KEEP is 5 if we allocate a place to return structure.
-
- TYPE is the type that will be used for the stack slot. */
-
-@@ -642,6 +650,8 @@
- unsigned int align;
- struct temp_slot *p, *best_p = 0;
- rtx slot;
-+ int char_array = (flag_propolice_protection
-+ && keep == 1 && search_string_def (type));
-
- /* If SIZE is -1 it means that somebody tried to allocate a temporary
- of a variable size. */
-@@ -667,7 +677,8 @@
- && ! p->in_use
- && objects_must_conflict_p (p->type, type)
- && (best_p == 0 || best_p->size > p->size
-- || (best_p->size == p->size && best_p->align > p->align)))
-+ || (best_p->size == p->size && best_p->align > p->align))
-+ && (! char_array || p->boundary_mark != 0))
- {
- if (p->align == align && p->size == size)
- {
-@@ -702,6 +713,7 @@
- p->address = 0;
- p->rtl_expr = 0;
- p->type = best_p->type;
-+ p->boundary_mark = best_p->boundary_mark;
- p->next = temp_slots;
- temp_slots = p;
-
-@@ -762,6 +774,7 @@
- p->full_size = frame_offset - frame_offset_old;
- #endif
- p->address = 0;
-+ p->boundary_mark = char_array?++temp_boundary_mark:0;
- p->next = temp_slots;
- temp_slots = p;
- }
-@@ -932,14 +945,16 @@
- int delete_q = 0;
- if (! q->in_use && GET_MODE (q->slot) == BLKmode)
- {
-- if (p->base_offset + p->full_size == q->base_offset)
-+ if (p->base_offset + p->full_size == q->base_offset &&
-+ p->boundary_mark == q->boundary_mark)
- {
- /* Q comes after P; combine Q into P. */
- p->size += q->size;
- p->full_size += q->full_size;
- delete_q = 1;
- }
-- else if (q->base_offset + q->full_size == p->base_offset)
-+ else if (q->base_offset + q->full_size == p->base_offset &&
-+ p->boundary_mark == q->boundary_mark)
- {
- /* P comes after Q; combine P into Q. */
- q->size += p->size;
-@@ -1497,7 +1512,9 @@
- new = func->x_parm_reg_stack_loc[regno];
-
- if (new == 0)
-- new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
-+ new = function ?
-+ assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func):
-+ assign_stack_local_for_pseudo_reg (decl_mode, GET_MODE_SIZE (decl_mode), 0);
-
- PUT_CODE (reg, MEM);
- PUT_MODE (reg, decl_mode);
-@@ -3961,7 +3978,8 @@
- constant with that register. */
- temp = gen_reg_rtx (Pmode);
- XEXP (x, 0) = new;
-- if (validate_change (object, &XEXP (x, 1), temp, 0))
-+ if (validate_change (object, &XEXP (x, 1), temp, 0)
-+ && ! flag_propolice_protection)
- emit_insn_before (gen_move_insn (temp, new_offset), object);
- else
- {
-diff -urN gcc-3.3.1/gcc/gcse.c gcc-3.3.1-pp/gcc/gcse.c
---- gcc-3.3.1/gcc/gcse.c 2003-07-14 09:21:22.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/gcse.c 2003-09-12 13:40:28.000000000 +0000
-@@ -4211,7 +4211,7 @@
- /* Find an assignment that sets reg_used and is available
- at the start of the block. */
- set = find_avail_set (regno, insn);
-- if (! set)
-+ if (! set || set->expr->volatil)
- continue;
-
- pat = set->expr;
-diff -urN gcc-3.3.1/gcc/integrate.c gcc-3.3.1-pp/gcc/integrate.c
---- gcc-3.3.1/gcc/integrate.c 2003-07-15 01:05:43.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/integrate.c 2003-09-12 13:40:28.000000000 +0000
-@@ -401,6 +401,10 @@
- /* These args would always appear unused, if not for this. */
- TREE_USED (copy) = 1;
-
-+ /* The inlined variable is marked as INLINE not to sweep by propolice */
-+ if (flag_propolice_protection && TREE_CODE (copy) == VAR_DECL)
-+ DECL_INLINE (copy) = 1;
-+
- /* Set the context for the new declaration. */
- if (!DECL_CONTEXT (decl))
- /* Globals stay global. */
-@@ -1965,6 +1969,10 @@
-
- seq = get_insns ();
- end_sequence ();
-+#ifdef FRAME_GROWS_DOWNWARD
-+ if (flag_propolice_protection && GET_CODE (seq) == SET)
-+ RTX_INTEGRATED_P (SET_SRC (seq)) = 1;
-+#endif
- emit_insn_after (seq, map->insns_at_start);
- return temp;
- }
-diff -urN gcc-3.3.1/gcc/libgcc-std.ver gcc-3.3.1-pp/gcc/libgcc-std.ver
---- gcc-3.3.1/gcc/libgcc-std.ver 2003-07-13 21:25:09.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/libgcc-std.ver 2003-09-12 13:40:28.000000000 +0000
-@@ -174,6 +174,10 @@
- _Unwind_SjLj_RaiseException
- _Unwind_SjLj_ForcedUnwind
- _Unwind_SjLj_Resume
-+
-+ # stack smash handler symbols
-+ __guard
-+ __stack_smash_handler
- }
-
- %inherit GCC_3.3 GCC_3.0
-diff -urN gcc-3.3.1/gcc/libgcc2.c gcc-3.3.1-pp/gcc/libgcc2.c
---- gcc-3.3.1/gcc/libgcc2.c 2002-10-23 10:47:24.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/libgcc2.c 2003-09-12 13:40:28.000000000 +0000
-@@ -1993,3 +1993,102 @@
- #endif /* NEED_ATEXIT */
-
- #endif /* L_exit */
-+\f
-+#ifdef L_stack_smash_handler
-+#include <stdio.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+
-+#ifdef _POSIX_SOURCE
-+#include <signal.h>
-+#endif
-+
-+#if defined(HAVE_SYSLOG)
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+
-+#include <sys/syslog.h>
-+#ifndef _PATH_LOG
-+#define _PATH_LOG "/dev/log"
-+#endif
-+#endif
-+
-+long __guard[8] = {0,0,0,0,0,0,0,0};
-+static void __guard_setup (void) __attribute__ ((constructor)) ;
-+static void __guard_setup (void)
-+{
-+ int fd;
-+ if (__guard[0]!=0) return;
-+ fd = open ("/dev/urandom", 0);
-+ if (fd != -1) {
-+ ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
-+ close (fd) ;
-+ if (size == sizeof(__guard)) return;
-+ }
-+ /* If a random generator can't be used, the protector switches the guard
-+ to the "terminator canary" */
-+ ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
-+ ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
-+}
-+void __stack_smash_handler (char func[], int damaged ATTRIBUTE_UNUSED)
-+{
-+#if defined (__GNU_LIBRARY__)
-+ extern char * __progname;
-+#endif
-+ const char message[] = ": stack smashing attack in function ";
-+ int bufsz = 256, len;
-+ char buf[bufsz];
-+#if defined(HAVE_SYSLOG)
-+ int LogFile;
-+ struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */
-+#endif
-+#ifdef _POSIX_SOURCE
-+ {
-+ sigset_t mask;
-+ sigfillset(&mask);
-+ sigdelset(&mask, SIGABRT); /* Block all signal handlers */
-+ sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
-+ }
-+#endif
-+
-+ strcpy(buf, "<2>"); len=3; /* send LOG_CRIT */
-+#if defined (__GNU_LIBRARY__)
-+ strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
-+#endif
-+ if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
-+ if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);}
-+
-+ /* print error message */
-+ write (STDERR_FILENO, buf+3, len-3);
-+#if defined(HAVE_SYSLOG)
-+ if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
-+
-+ /*
-+ * Send "found" message to the "/dev/log" path
-+ */
-+ SyslogAddr.sun_family = AF_UNIX;
-+ (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
-+ sizeof(SyslogAddr.sun_path) - 1);
-+ SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
-+ sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr,
-+ sizeof(SyslogAddr));
-+ }
-+#endif
-+
-+#ifdef _POSIX_SOURCE
-+ { /* Make sure the default handler is associated with SIGABRT */
-+ struct sigaction sa;
-+
-+ memset(&sa, 0, sizeof(struct sigaction));
-+ sigfillset(&sa.sa_mask); /* Block all signals */
-+ sa.sa_flags = 0;
-+ sa.sa_handler = SIG_DFL;
-+ sigaction(SIGABRT, &sa, NULL);
-+ (void)kill(getpid(), SIGABRT);
-+ }
-+#endif
-+ _exit(127);
-+}
-+#endif
-diff -urN gcc-3.3.1/gcc/loop.c gcc-3.3.1-pp/gcc/loop.c
---- gcc-3.3.1/gcc/loop.c 2003-07-11 06:47:05.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/loop.c 2003-09-12 13:40:28.000000000 +0000
-@@ -6516,6 +6516,14 @@
- if (GET_CODE (*mult_val) == USE)
- *mult_val = XEXP (*mult_val, 0);
-
-+#ifndef FRAME_GROWS_DOWNWARD
-+ if (flag_propolice_protection
-+ && GET_CODE (*add_val) == PLUS
-+ && (XEXP (*add_val, 0) == frame_pointer_rtx
-+ || XEXP (*add_val, 1) == frame_pointer_rtx))
-+ return 0;
-+#endif
-+
- if (is_addr)
- *pbenefit += address_cost (orig_x, addr_mode) - reg_address_cost;
- else
-diff -urN gcc-3.3.1/gcc/optabs.c gcc-3.3.1-pp/gcc/optabs.c
---- gcc-3.3.1/gcc/optabs.c 2003-07-19 00:25:25.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/optabs.c 2003-09-12 13:40:28.000000000 +0000
-@@ -703,6 +703,26 @@
- if (target)
- target = protect_from_queue (target, 1);
-
-+ if (flag_propolice_protection
-+ && binoptab->code == PLUS
-+ && op0 == virtual_stack_vars_rtx
-+ && GET_CODE(op1) == CONST_INT)
-+ {
-+ int icode = (int) binoptab->handlers[(int) mode].insn_code;
-+ if (target)
-+ temp = target;
-+ else
-+ temp = gen_reg_rtx (mode);
-+
-+ if (! (*insn_data[icode].operand[0].predicate) (temp, mode)
-+ || GET_CODE (temp) != REG)
-+ temp = gen_reg_rtx (mode);
-+
-+ emit_insn (gen_rtx_SET (VOIDmode, temp,
-+ gen_rtx_PLUS (GET_MODE (op0), op0, op1)));
-+ return temp;
-+ }
-+
- if (flag_force_mem)
- {
- op0 = force_not_mem (op0);
-diff -urN gcc-3.3.1/gcc/protector.c gcc-3.3.1-pp/gcc/protector.c
---- gcc-3.3.1/gcc/protector.c 1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/protector.c 2003-09-12 13:40:28.000000000 +0000
-@@ -0,0 +1,2489 @@
-+/* RTL buffer overflow protection function for GNU C compiler
-+ Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "machmode.h"
-+
-+#include "rtl.h"
-+#include "tree.h"
-+#include "regs.h"
-+#include "flags.h"
-+#include "insn-config.h"
-+#include "insn-flags.h"
-+#include "expr.h"
-+#include "output.h"
-+#include "recog.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "except.h"
-+#include "function.h"
-+#include "toplev.h"
-+#include "conditions.h"
-+#include "insn-attr.h"
-+#include "c-tree.h"
-+#include "optabs.h"
-+#include "protector.h"
-+
-+
-+void prepare_stack_protection PARAMS ((int inlinable));
-+int search_string_def PARAMS ((tree names));
-+rtx assign_stack_local_for_pseudo_reg PARAMS ((enum machine_mode, HOST_WIDE_INT, int));
-+
-+
-+/* Warn when not issuing stack smashing protection for some reason */
-+int warn_stack_protector;
-+
-+/* Round a value to the lowest integer less than it that is a multiple of
-+ the required alignment. Avoid using division in case the value is
-+ negative. Assume the alignment is a power of two. */
-+#define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))
-+
-+/* Similar, but round to the next highest integer that meets the
-+ alignment. */
-+#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
-+
-+
-+/* Nonzero means use propolice as a stack protection method */
-+extern int flag_propolice_protection;
-+
-+/* This file contains several memory arrangement functions to protect
-+ the return address and the frame pointer of the stack
-+ from a stack-smashing attack. It also
-+ provides the function that protects pointer variables. */
-+
-+/* Nonzero if function being compiled can define string buffers that may be
-+ damaged by the stack-smash attack */
-+static int current_function_defines_vulnerable_string;
-+static int current_function_defines_short_string;
-+static int current_function_has_variable_string;
-+static int current_function_defines_vsized_array;
-+static int current_function_is_inlinable;
-+
-+static rtx guard_area, _guard;
-+static rtx function_first_insn, prologue_insert_point;
-+
-+/* */
-+static HOST_WIDE_INT sweep_frame_offset;
-+static HOST_WIDE_INT push_allocated_offset = 0;
-+static HOST_WIDE_INT push_frame_offset = 0;
-+static int saved_cse_not_expected = 0;
-+
-+static int search_string_from_argsandvars PARAMS ((int caller));
-+static int search_string_from_local_vars PARAMS ((tree block));
-+static int search_pointer_def PARAMS ((tree names));
-+static int search_func_pointer PARAMS ((tree type, int mark));
-+static void reset_used_flags_for_insns PARAMS ((rtx insn));
-+static void reset_used_flags_for_decls PARAMS ((tree block));
-+static void reset_used_flags_of_plus PARAMS ((rtx x));
-+static void rtl_prologue PARAMS ((rtx insn));
-+static void rtl_epilogue PARAMS ((rtx fnlastinsn));
-+static void arrange_var_order PARAMS ((tree blocks));
-+static void copy_args_for_protection PARAMS ((void));
-+static void sweep_string_variable PARAMS ((rtx sweep_var, HOST_WIDE_INT var_size));
-+static void sweep_string_in_decls PARAMS ((tree block, HOST_WIDE_INT sweep_offset, HOST_WIDE_INT size));
-+static void sweep_string_in_args PARAMS ((tree parms, HOST_WIDE_INT sweep_offset, HOST_WIDE_INT size));
-+static void sweep_string_use_of_insns PARAMS ((rtx insn, HOST_WIDE_INT sweep_offset, HOST_WIDE_INT size));
-+static void sweep_string_in_operand PARAMS ((rtx insn, rtx *loc, HOST_WIDE_INT sweep_offset, HOST_WIDE_INT size));
-+static void move_arg_location PARAMS ((rtx insn, rtx orig, rtx new, HOST_WIDE_INT var_size));
-+static void change_arg_use_of_insns PARAMS ((rtx insn, rtx orig, rtx *new, HOST_WIDE_INT size));
-+static void change_arg_use_of_insns_2 PARAMS ((rtx insn, rtx orig, rtx *new, HOST_WIDE_INT size));
-+static void change_arg_use_in_operand PARAMS ((rtx x, rtx orig, rtx *new, HOST_WIDE_INT size));
-+static void validate_insns_of_varrefs PARAMS ((rtx insn));
-+static void validate_operand_of_varrefs PARAMS ((rtx insn, rtx *loc));
-+
-+#define SUSPICIOUS_BUF_SIZE 8
-+
-+#define AUTO_BASEPTR(X) \
-+ (GET_CODE (X) == PLUS ? XEXP (X, 0) : X)
-+#define AUTO_OFFSET(X) \
-+ (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
-+#undef PARM_PASSED_IN_MEMORY
-+#define PARM_PASSED_IN_MEMORY(PARM) \
-+ (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
-+#define VIRTUAL_STACK_VARS_P(X) \
-+ ((X) == virtual_stack_vars_rtx || (GET_CODE (X) == REG && (X)->used))
-+
-+
-+
-+void
-+prepare_stack_protection (inlinable)
-+ int inlinable;
-+{
-+ tree blocks = DECL_INITIAL (current_function_decl);
-+ current_function_is_inlinable = inlinable && !flag_no_inline;
-+ push_frame_offset = push_allocated_offset = 0;
-+ saved_cse_not_expected = 0;
-+
-+ /*
-+ skip the protection if the function has no block or it is an inline function
-+ */
-+ if (current_function_is_inlinable) validate_insns_of_varrefs (get_insns ());
-+ if (! blocks || current_function_is_inlinable) return;
-+
-+ current_function_defines_vulnerable_string = search_string_from_argsandvars (0);
-+
-+ if (current_function_defines_vulnerable_string)
-+ {
-+ HOST_WIDE_INT offset;
-+ function_first_insn = get_insns ();
-+
-+ if (current_function_contains_functions) {
-+ if (warn_stack_protector)
-+ warning ("not protecting function: it contains functions");
-+ return;
-+ }
-+
-+ /* Initialize recognition, indicating that volatile is OK. */
-+ init_recog ();
-+
-+ sweep_frame_offset = 0;
-+
-+#ifdef STACK_GROWS_DOWNWARD
-+ /*
-+ frame_offset: offset to end of allocated area of stack frame.
-+ It is defined in the function.c
-+ */
-+
-+ /* the location must be before buffers */
-+ guard_area = assign_stack_local (BLKmode, UNITS_PER_GUARD, -1);
-+ PUT_MODE (guard_area, GUARD_m);
-+ MEM_VOLATILE_P (guard_area) = 1;
-+
-+#ifndef FRAME_GROWS_DOWNWARD
-+ sweep_frame_offset = frame_offset;
-+#endif
-+
-+ /* For making room for guard value, scan all insns and fix the offset address
-+ of the variable that is based on frame pointer.
-+ Scan all declarations of variables and fix the offset address of the variable that
-+ is based on the frame pointer */
-+ sweep_string_variable (guard_area, UNITS_PER_GUARD);
-+
-+
-+ /* the location of guard area moves to the beginning of stack frame */
-+ if ((offset = AUTO_OFFSET(XEXP (guard_area, 0))))
-+ XEXP (XEXP (guard_area, 0), 1) = gen_rtx_CONST_INT (VOIDmode, sweep_frame_offset);
-+
-+
-+ /* Insert prologue rtl instructions */
-+ rtl_prologue (function_first_insn);
-+
-+ if (! current_function_has_variable_string)
-+ {
-+ /* Generate argument saving instruction */
-+ copy_args_for_protection ();
-+
-+#ifndef FRAME_GROWS_DOWNWARD
-+ /* If frame grows upward, character string copied from an arg stays top of
-+ the guard variable. So sweep the guard variable again */
-+ sweep_frame_offset = CEIL_ROUND (frame_offset, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
-+ sweep_string_variable (guard_area, UNITS_PER_GUARD);
-+#endif
-+ }
-+ else if (warn_stack_protector)
-+ warning ("not protecting variables: it has a variable length buffer");
-+#endif
-+#ifndef FRAME_GROWS_DOWNWARD
-+ if (STARTING_FRAME_OFFSET == 0)
-+ {
-+ /* this may be only for alpha */
-+ push_allocated_offset = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
-+ assign_stack_local (BLKmode, push_allocated_offset, -1);
-+ sweep_frame_offset = frame_offset;
-+ sweep_string_variable (const0_rtx, -push_allocated_offset);
-+ sweep_frame_offset = AUTO_OFFSET (XEXP (guard_area, 0));
-+ }
-+#endif
-+
-+ /* Arrange the order of local variables */
-+ arrange_var_order (blocks);
-+
-+#ifdef STACK_GROWS_DOWNWARD
-+ /* Insert epilogue rtl instructions */
-+ rtl_epilogue (get_last_insn ());
-+#endif
-+ init_recog_no_volatile ();
-+ }
-+ else if (current_function_defines_short_string
-+ && warn_stack_protector)
-+ warning ("not protecting function: buffer is less than %d bytes long",
-+ SUSPICIOUS_BUF_SIZE);
-+}
-+
-+/*
-+ search string from arguments and local variables
-+ caller: 0 means call from protector_stack_protection
-+ 1 means call from push_frame
-+*/
-+static int
-+search_string_from_argsandvars (caller)
-+ int caller;
-+{
-+ tree blocks, parms;
-+ int string_p;
-+
-+ /* saves a latest search result as a cached infomation */
-+ static tree __latest_search_decl = 0;
-+ static int __latest_search_result = FALSE;
-+
-+ if (__latest_search_decl == current_function_decl)
-+ return __latest_search_result;
-+ else if (caller) return FALSE;
-+ __latest_search_decl = current_function_decl;
-+ __latest_search_result = TRUE;
-+
-+ current_function_defines_short_string = FALSE;
-+ current_function_has_variable_string = FALSE;
-+ current_function_defines_vsized_array = FALSE;
-+
-+ /*
-+ search a string variable from local variables
-+ */
-+ blocks = DECL_INITIAL (current_function_decl);
-+ string_p = search_string_from_local_vars (blocks);
-+
-+ if (!current_function_defines_vsized_array && current_function_calls_alloca)
-+ {
-+ current_function_has_variable_string = TRUE;
-+ return TRUE;
-+ }
-+
-+ if (string_p) return TRUE;
-+
-+#ifdef STACK_GROWS_DOWNWARD
-+ /*
-+ search a string variable from arguments
-+ */
-+ parms = DECL_ARGUMENTS (current_function_decl);
-+
-+ for (; parms; parms = TREE_CHAIN (parms))
-+ if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
-+ {
-+ if (PARM_PASSED_IN_MEMORY (parms) && DECL_NAME (parms))
-+ {
-+ string_p = search_string_def (TREE_TYPE(parms));
-+ if (string_p) return TRUE;
-+ }
-+ }
-+#endif
-+
-+ __latest_search_result = FALSE;
-+ return FALSE;
-+}
-+
-+
-+static int
-+search_string_from_local_vars (block)
-+ tree block;
-+{
-+ tree types;
-+ int found = FALSE;
-+
-+ while (block && TREE_CODE(block)==BLOCK)
-+ {
-+ types = BLOCK_VARS(block);
-+
-+ while (types)
-+ {
-+ /* skip the declaration that refers an external variable */
-+ /* name: types.decl.name.identifier.id */
-+ if (! DECL_EXTERNAL (types) && ! TREE_STATIC (types)
-+ && TREE_CODE (types) == VAR_DECL
-+ && ! DECL_ARTIFICIAL (types)
-+ && DECL_RTL_SET_P (types)
-+ && GET_CODE (DECL_RTL (types)) == MEM)
-+ {
-+ if (search_string_def (TREE_TYPE (types)))
-+ {
-+ rtx home = DECL_RTL (types);
-+
-+ if (GET_CODE (home) == MEM
-+ && (GET_CODE (XEXP (home, 0)) == MEM
-+ || (GET_CODE (XEXP (home, 0)) == REG
-+ && XEXP (home, 0) != virtual_stack_vars_rtx
-+ && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
-+ && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
-+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-+ && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
-+#endif
-+ )))
-+ /* If the value is indirect by memory or by a register
-+ that isn't the frame pointer
-+ then it means the object is variable-sized and address through
-+ that register or stack slot. The protection has no way to hide pointer variables
-+ behind the array, so all we can do is staying the order of variables and arguments. */
-+ {
-+ current_function_has_variable_string = TRUE;
-+ }
-+
-+ /* found character array */
-+ found = TRUE;
-+ }
-+ }
-+
-+ types = TREE_CHAIN(types);
-+ }
-+
-+ if (search_string_from_local_vars (BLOCK_SUBBLOCKS (block)))
-+ {
-+ found = TRUE;
-+ }
-+
-+ block = BLOCK_CHAIN (block);
-+ }
-+
-+ return found;
-+}
-+
-+
-+/*
-+ * search a character array from the specified type tree
-+ */
-+int
-+search_string_def (type)
-+ tree type;
-+{
-+ tree tem;
-+
-+ if (! type)
-+ return FALSE;
-+
-+ switch (TREE_CODE (type))
-+ {
-+ case ARRAY_TYPE:
-+ /* Check if the array is a variable-sized array */
-+ if (TYPE_DOMAIN (type) == 0
-+ || (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
-+ && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == NOP_EXPR))
-+ current_function_defines_vsized_array = TRUE;
-+
-+ /* TREE_CODE( TREE_TYPE(type) ) == INTEGER_TYPE */
-+ if (TYPE_MAIN_VARIANT (TREE_TYPE(type)) == char_type_node
-+ || TYPE_MAIN_VARIANT (TREE_TYPE(type)) == signed_char_type_node
-+ || TYPE_MAIN_VARIANT (TREE_TYPE(type)) == unsigned_char_type_node)
-+ {
-+ /* Check if the string is a variable string */
-+ if (TYPE_DOMAIN (type) == 0
-+ || (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
-+ && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == NOP_EXPR))
-+ return TRUE;
-+
-+ /* Check if the string size is greater than SUSPICIOUS_BUF_SIZE */
-+ if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
-+ && TREE_INT_CST_LOW(TYPE_MAX_VALUE(TYPE_DOMAIN(type)))+1 >= SUSPICIOUS_BUF_SIZE)
-+ return TRUE;
-+
-+ current_function_defines_short_string = TRUE;
-+ }
-+ return search_string_def(TREE_TYPE(type));
-+
-+ case UNION_TYPE:
-+ case QUAL_UNION_TYPE:
-+ case RECORD_TYPE:
-+ /* Output the name, type, position (in bits), size (in bits) of each
-+ field. */
-+ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
-+ {
-+ /* Omit here local type decls until we know how to support them. */
-+ if ((TREE_CODE (tem) == TYPE_DECL)
-+ || (TREE_CODE (tem) == VAR_DECL && TREE_STATIC (tem)))
-+ continue;
-+
-+ if (search_string_def(TREE_TYPE(tem))) return TRUE;
-+ }
-+ break;
-+
-+ case POINTER_TYPE:
-+ case REFERENCE_TYPE:
-+ /* I'm not sure whether OFFSET_TYPE needs this treatment,
-+ so I'll play safe and return 1. */
-+ case OFFSET_TYPE:
-+ default:
-+ break;
-+ }
-+
-+ return FALSE;
-+}
-+
-+/*
-+ * examine whether the input contains frame pointer addressing
-+ */
-+int
-+contains_fp (op)
-+ rtx op;
-+{
-+ register enum rtx_code code;
-+ rtx x;
-+ int i, j;
-+ const char *fmt;
-+
-+ x = op;
-+ if (x == 0)
-+ return FALSE;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case REG:
-+ case ADDRESSOF:
-+ return FALSE;
-+
-+ case PLUS:
-+ if (XEXP (x, 0) == virtual_stack_vars_rtx
-+ && CONSTANT_P (XEXP (x, 1)))
-+ return TRUE;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ {
-+ if (contains_fp (XEXP (x, i))) return TRUE;
-+ }
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ if (contains_fp (XVECEXP (x, i, j))) return TRUE;
-+
-+ return FALSE;
-+}
-+
-+
-+static int
-+search_pointer_def (type)
-+ tree type;
-+{
-+ tree tem;
-+
-+ if (! type)
-+ return FALSE;
-+
-+ switch (TREE_CODE (type))
-+ {
-+ case UNION_TYPE:
-+ case QUAL_UNION_TYPE:
-+ case RECORD_TYPE:
-+ /* Output the name, type, position (in bits), size (in bits) of each
-+ field. */
-+ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
-+ {
-+ /* Omit here local type decls until we know how to support them. */
-+ if ((TREE_CODE (tem) == TYPE_DECL)
-+ || (TREE_CODE (tem) == VAR_DECL && TREE_STATIC (tem)))
-+ continue;
-+
-+ if (search_pointer_def (TREE_TYPE(tem))) return TRUE;
-+ }
-+ break;
-+
-+ case ARRAY_TYPE:
-+ return search_pointer_def (TREE_TYPE(type));
-+
-+ case POINTER_TYPE:
-+ case REFERENCE_TYPE:
-+ /* I'm not sure whether OFFSET_TYPE needs this treatment,
-+ so I'll play safe and return 1. */
-+ case OFFSET_TYPE:
-+ if (TYPE_READONLY (TREE_TYPE (type)))
-+ {
-+ int funcp = search_func_pointer (TREE_TYPE (type), 1);
-+ /* Un-mark the type as having been visited already */
-+ search_func_pointer (TREE_TYPE (type), 0);
-+ return funcp;
-+ }
-+ return TRUE;
-+
-+ default:
-+ break;
-+ }
-+
-+ return FALSE;
-+}
-+
-+
-+static int
-+search_func_pointer (type, mark)
-+ tree type;
-+ int mark;
-+{
-+ tree tem;
-+
-+ if (! type)
-+ return FALSE;
-+
-+ switch (TREE_CODE (type))
-+ {
-+ case UNION_TYPE:
-+ case QUAL_UNION_TYPE:
-+ case RECORD_TYPE:
-+ if (TREE_ASM_WRITTEN (type) != mark)
-+ {
-+ /* mark the type as having been visited already */
-+ TREE_ASM_WRITTEN (type) = mark;
-+
-+ /* Output the name, type, position (in bits), size (in bits) of
-+ each field. */
-+ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
-+ {
-+ /* Omit here local type decls until we know how to support them. */
-+ if (TREE_CODE (tem) == FIELD_DECL
-+ && search_func_pointer (TREE_TYPE(tem), mark)) return TRUE;
-+ }
-+ }
-+ break;
-+
-+ case ARRAY_TYPE:
-+ return search_func_pointer (TREE_TYPE(type), mark);
-+
-+ case POINTER_TYPE:
-+ case REFERENCE_TYPE:
-+ /* I'm not sure whether OFFSET_TYPE needs this treatment,
-+ so I'll play safe and return 1. */
-+ case OFFSET_TYPE:
-+ return TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE;
-+
-+ default:
-+ break;
-+ }
-+
-+ return FALSE;
-+}
-+
-+
-+static void
-+reset_used_flags_for_insns (insn)
-+ rtx insn;
-+{
-+ register int i, j;
-+ register enum rtx_code code;
-+ register const char *format_ptr;
-+
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ code = GET_CODE (insn);
-+ insn->used = 0;
-+ format_ptr = GET_RTX_FORMAT (code);
-+
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
-+ {
-+ switch (*format_ptr++) {
-+ case 'e':
-+ reset_used_flags_of_plus (XEXP (insn, i));
-+ break;
-+
-+ case 'E':
-+ for (j = 0; j < XVECLEN (insn, i); j++)
-+ reset_used_flags_of_plus (XVECEXP (insn, i, j));
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+static void
-+reset_used_flags_for_decls (block)
-+ tree block;
-+{
-+ tree types;
-+ rtx home;
-+
-+ while (block && TREE_CODE(block)==BLOCK)
-+ {
-+ types = BLOCK_VARS(block);
-+
-+ while (types)
-+ {
-+ /* skip the declaration that refers an external variable and
-+ also skip an global variable */
-+ if (! DECL_EXTERNAL (types))
-+ {
-+ if (!DECL_RTL_SET_P (types)) goto next;
-+ home = DECL_RTL (types);
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
-+ {
-+ XEXP (home, 0)->used = 0;
-+ }
-+ }
-+ next:
-+ types = TREE_CHAIN(types);
-+ }
-+
-+ reset_used_flags_for_decls (BLOCK_SUBBLOCKS (block));
-+
-+ block = BLOCK_CHAIN (block);
-+ }
-+}
-+
-+/* Clear the USED bits only of type PLUS in X */
-+
-+static void
-+reset_used_flags_of_plus (x)
-+ rtx x;
-+{
-+ register int i, j;
-+ register enum rtx_code code;
-+ register const char *format_ptr;
-+
-+ if (x == 0)
-+ return;
-+
-+ code = GET_CODE (x);
-+
-+ /* These types may be freely shared so we needn't do any resetting
-+ for them. */
-+
-+ switch (code)
-+ {
-+ case REG:
-+ case QUEUED:
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ return;
-+
-+ case INSN:
-+ case JUMP_INSN:
-+ case CALL_INSN:
-+ case NOTE:
-+ case LABEL_REF:
-+ case BARRIER:
-+ /* The chain of insns is not being copied. */
-+ return;
-+
-+ case PLUS:
-+ x->used = 0;
-+ break;
-+
-+ case CALL_PLACEHOLDER:
-+ reset_used_flags_for_insns (XEXP (x, 0));
-+ reset_used_flags_for_insns (XEXP (x, 1));
-+ reset_used_flags_for_insns (XEXP (x, 2));
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ format_ptr = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
-+ {
-+ switch (*format_ptr++)
-+ {
-+ case 'e':
-+ reset_used_flags_of_plus (XEXP (x, i));
-+ break;
-+
-+ case 'E':
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ reset_used_flags_of_plus (XVECEXP (x, i, j));
-+ break;
-+ }
-+ }
-+}
-+
-+
-+static void
-+rtl_prologue (insn)
-+ rtx insn;
-+{
-+#if defined(INIT_SECTION_ASM_OP) && !defined(INVOKE__main)
-+#undef HAS_INIT_SECTION
-+#define HAS_INIT_SECTION
-+#endif
-+
-+ rtx _val;
-+
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
-+ break;
-+
-+#if !defined (HAS_INIT_SECTION)
-+ /* If this function is `main', skip a call to `__main'
-+ to run guard instruments after global initializers, etc. */
-+ if (DECL_NAME (current_function_decl)
-+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
-+ && DECL_CONTEXT (current_function_decl) == NULL_TREE)
-+ {
-+ rtx fbinsn = insn;
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
-+ break;
-+ if (insn == 0) insn = fbinsn;
-+ }
-+#endif
-+
-+ prologue_insert_point = NEXT_INSN (insn); /* mark the next insn of FUNCTION_BEG insn */
-+
-+ start_sequence ();
-+
-+ _guard = gen_rtx_MEM (GUARD_m, gen_rtx_SYMBOL_REF (Pmode, "__guard"));
-+ emit_move_insn ( guard_area, _guard);
-+
-+ _val = get_insns ();
-+ end_sequence ();
-+
-+ emit_insn_before (_val, prologue_insert_point);
-+}
-+
-+static void
-+rtl_epilogue (insn)
-+ rtx insn;
-+{
-+ rtx if_false_label;
-+ rtx _val;
-+ rtx funcname;
-+ tree funcstr;
-+ int flag_have_return = FALSE;
-+
-+ start_sequence ();
-+
-+#ifdef HAVE_return
-+ if (HAVE_return)
-+ {
-+ rtx insn;
-+ return_label = gen_label_rtx ();
-+
-+ for (insn = prologue_insert_point; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == JUMP_INSN
-+ && GET_CODE (PATTERN (insn)) == RETURN
-+ && GET_MODE (PATTERN (insn)) == VOIDmode)
-+ {
-+ rtx pat = gen_rtx_SET (VOIDmode,
-+ pc_rtx,
-+ gen_rtx_LABEL_REF (VOIDmode,
-+ return_label));
-+ PATTERN (insn) = pat;
-+ flag_have_return = TRUE;
-+ }
-+
-+
-+ emit_label (return_label);
-+ }
-+#endif
-+
-+ compare_from_rtx (guard_area, _guard, NE, 0, GUARD_m, NULL_RTX); /* if (guard_area != _guard) */
-+
-+ if_false_label = gen_label_rtx (); /* { */
-+ emit_jump_insn ( gen_beq(if_false_label));
-+
-+ /* generate string for the current function name */
-+ funcstr = build_string (strlen(current_function_name)+1, current_function_name);
-+ TREE_TYPE (funcstr) = build_array_type (char_type_node, 0);/* = char_array_type_node;*/
-+ funcname = output_constant_def (funcstr, 1);
-+
-+ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__stack_smash_handler"),
-+ 0, VOIDmode, 2,
-+ XEXP (funcname, 0), Pmode, guard_area, GUARD_m);
-+
-+ /* generate RTL to return from the current function */
-+
-+ emit_barrier (); /* } */
-+ emit_label (if_false_label);
-+
-+ /* generate RTL to return from the current function */
-+ if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
-+ use_return_register ();
-+
-+#ifdef HAVE_return
-+ if (HAVE_return && flag_have_return)
-+ {
-+ emit_jump_insn (gen_return ());
-+ emit_barrier ();
-+ }
-+#endif
-+
-+ _val = get_insns ();
-+ end_sequence ();
-+
-+ emit_insn_after (_val, insn);
-+}
-+
-+
-+static void
-+arrange_var_order (block)
-+ tree block;
-+{
-+ tree types;
-+ HOST_WIDE_INT offset;
-+
-+ while (block && TREE_CODE(block)==BLOCK)
-+ {
-+ types = BLOCK_VARS (block);
-+
-+ while (types)
-+ {
-+ /* skip the declaration that refers an external variable */
-+ /* name: types.decl.assembler_name.id */
-+ if (! DECL_EXTERNAL (types) && ! TREE_STATIC (types)
-+ && TREE_CODE (types) == VAR_DECL
-+ && ! DECL_ARTIFICIAL (types)
-+ && ! DECL_INLINE (types) /* don't sweep inlined string */
-+ && DECL_RTL_SET_P (types)
-+ && GET_CODE (DECL_RTL (types)) == MEM)
-+ {
-+ if (search_string_def (TREE_TYPE (types)))
-+ {
-+ rtx home = DECL_RTL (types);
-+
-+ if (! (GET_CODE (home) == MEM
-+ && (GET_CODE (XEXP (home, 0)) == MEM
-+ || (GET_CODE (XEXP (home, 0)) == REG
-+ && XEXP (home, 0) != virtual_stack_vars_rtx
-+ && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
-+ && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
-+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-+ && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
-+#endif
-+ ))))
-+ {
-+ /* found a string variable */
-+ HOST_WIDE_INT var_size =
-+ ((TREE_INT_CST_LOW (DECL_SIZE (types)) + BITS_PER_UNIT - 1)
-+ / BITS_PER_UNIT);
-+
-+ if (GET_MODE (DECL_RTL (types)) == BLKmode)
-+ {
-+ int alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
-+ var_size = CEIL_ROUND (var_size, alignment);
-+ }
-+
-+ /* skip the variable if it is top of the region
-+ specified by sweep_frame_offset */
-+ offset = AUTO_OFFSET (XEXP (DECL_RTL (types), 0));
-+ if (offset == sweep_frame_offset - var_size)
-+ sweep_frame_offset -= var_size;
-+
-+ else if (offset < sweep_frame_offset - var_size)
-+ sweep_string_variable (DECL_RTL (types), var_size);
-+ }
-+ }
-+ }
-+
-+ types = TREE_CHAIN(types);
-+ }
-+
-+ arrange_var_order (BLOCK_SUBBLOCKS (block));
-+
-+ block = BLOCK_CHAIN (block);
-+ }
-+}
-+
-+
-+static void
-+copy_args_for_protection ()
-+{
-+ tree parms = DECL_ARGUMENTS (current_function_decl);
-+ rtx temp_rtx;
-+
-+ parms = DECL_ARGUMENTS (current_function_decl);
-+ for (; parms; parms = TREE_CHAIN (parms))
-+ if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
-+ {
-+ if (PARM_PASSED_IN_MEMORY (parms) && DECL_NAME (parms))
-+ {
-+ int string_p;
-+
-+ /*
-+ skip arguemnt protection if the last argument is used
-+ for the variable argument
-+ */
-+ /*
-+ tree fntype;
-+ if (TREE_CHAIN (parms) == 0)
-+ {
-+ fntype = TREE_TYPE (current_function_decl);
-+
-+ if ((TYPE_ARG_TYPES (fntype) != 0 &&
-+ TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node)
-+ || current_function_varargs)
-+ continue;
-+ }
-+ */
-+
-+ string_p = search_string_def (TREE_TYPE(parms));
-+
-+ /* check if it is a candidate to move */
-+ if (string_p || search_pointer_def (TREE_TYPE (parms)))
-+ {
-+ int arg_size
-+ = ((TREE_INT_CST_LOW (DECL_SIZE (parms)) + BITS_PER_UNIT - 1)
-+ / BITS_PER_UNIT);
-+
-+ start_sequence ();
-+
-+ if (GET_CODE (DECL_RTL (parms)) == REG)
-+ {
-+ rtx safe = 0;
-+
-+ change_arg_use_of_insns (prologue_insert_point, DECL_RTL (parms), &safe, 0);
-+ if (safe)
-+ {
-+ /* generate codes for copying the content */
-+ rtx movinsn = emit_move_insn (safe, DECL_RTL (parms));
-+
-+ /* avoid register elimination in gcse.c (COPY-PROP)*/
-+ PATTERN (movinsn)->volatil = 1;
-+
-+ /* save debugger info */
-+ DECL_INCOMING_RTL (parms) = safe;
-+ }
-+ }
-+
-+ else if (GET_CODE (DECL_RTL (parms)) == MEM
-+ && GET_CODE (XEXP (DECL_RTL (parms), 0)) == ADDRESSOF)
-+ {
-+ rtx movinsn;
-+ rtx safe = gen_reg_rtx (GET_MODE (DECL_RTL (parms)));
-+
-+ /* generate codes for copying the content */
-+ movinsn = emit_move_insn (safe, DECL_INCOMING_RTL (parms));
-+ PATTERN (movinsn)->volatil = 1; /* avoid register elimination in gcse.c (COPY-PROP)*/
-+
-+ /* change the addressof information to the newly allocated pseudo register */
-+ emit_move_insn (DECL_RTL (parms), safe);
-+
-+ /* save debugger info */
-+ DECL_INCOMING_RTL (parms) = safe;
-+ }
-+
-+ else
-+ {
-+ /* declare temporary local variable DECL_NAME (parms) for it */
-+ temp_rtx
-+ = assign_stack_local (DECL_MODE (parms), arg_size,
-+ DECL_MODE (parms) == BLKmode ? -1 : 0);
-+
-+ MEM_IN_STRUCT_P (temp_rtx) = AGGREGATE_TYPE_P (TREE_TYPE (parms));
-+ set_mem_alias_set (temp_rtx, get_alias_set (parms));
-+
-+ /* generate codes for copying the content */
-+ store_expr (parms, temp_rtx, 0);
-+
-+ /* change the reference for each instructions */
-+ move_arg_location (prologue_insert_point, DECL_RTL (parms),
-+ temp_rtx, arg_size);
-+
-+ /* change the location of parms variable */
-+ SET_DECL_RTL (parms, temp_rtx);
-+
-+ /* change debugger info */
-+ DECL_INCOMING_RTL (parms) = temp_rtx;
-+ }
-+
-+ emit_insn_before (get_insns (), prologue_insert_point);
-+ end_sequence ();
-+
-+#ifdef FRAME_GROWS_DOWNWARD
-+ /* process the string argument */
-+ if (string_p && DECL_MODE (parms) == BLKmode)
-+ {
-+ int alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
-+ arg_size = CEIL_ROUND (arg_size, alignment);
-+
-+ /* change the reference for each instructions */
-+ sweep_string_variable (DECL_RTL (parms), arg_size);
-+ }
-+#endif
-+ }
-+ }
-+ }
-+}
-+
-+
-+/*
-+ sweep a string variable to the local variable addressed by sweep_frame_offset, that is
-+ a last position of string variables.
-+*/
-+static void
-+sweep_string_variable (sweep_var, var_size)
-+ rtx sweep_var;
-+ HOST_WIDE_INT var_size;
-+{
-+ HOST_WIDE_INT sweep_offset;
-+
-+ switch (GET_CODE (sweep_var))
-+ {
-+ case MEM:
-+ if (GET_CODE (XEXP (sweep_var, 0)) == ADDRESSOF
-+ && GET_CODE (XEXP (XEXP (sweep_var, 0), 0)) == REG)
-+ return;
-+ sweep_offset = AUTO_OFFSET(XEXP (sweep_var, 0));
-+ break;
-+ case CONST_INT:
-+ sweep_offset = INTVAL (sweep_var);
-+ break;
-+ default:
-+ abort ();
-+ }
-+
-+ /* scan all declarations of variables and fix the offset address of
-+ the variable based on the frame pointer */
-+ sweep_string_in_decls (DECL_INITIAL (current_function_decl), sweep_offset, var_size);
-+
-+ /* scan all argument variable and fix the offset address based on the frame pointer */
-+ sweep_string_in_args (DECL_ARGUMENTS (current_function_decl), sweep_offset, var_size);
-+
-+ /* For making room for sweep variable, scan all insns and fix the offset address
-+ of the variable that is based on frame pointer*/
-+ sweep_string_use_of_insns (function_first_insn, sweep_offset, var_size);
-+
-+
-+ /* Clear all the USED bits in operands of all insns and declarations of local vars */
-+ reset_used_flags_for_decls (DECL_INITIAL (current_function_decl));
-+ reset_used_flags_for_insns (function_first_insn);
-+
-+ sweep_frame_offset -= var_size;
-+}
-+
-+
-+
-+/*
-+ move an argument to the local variable addressed by frame_offset
-+*/
-+static void
-+move_arg_location (insn, orig, new, var_size)
-+ rtx insn, orig, new;
-+ HOST_WIDE_INT var_size;
-+{
-+ /* For making room for sweep variable, scan all insns and fix the offset address
-+ of the variable that is based on frame pointer*/
-+ change_arg_use_of_insns (insn, orig, &new, var_size);
-+
-+
-+ /* Clear all the USED bits in operands of all insns and declarations of local vars */
-+ reset_used_flags_for_insns (insn);
-+}
-+
-+
-+static void
-+sweep_string_in_decls (block, sweep_offset, sweep_size)
-+ tree block;
-+ HOST_WIDE_INT sweep_offset, sweep_size;
-+{
-+ tree types;
-+ HOST_WIDE_INT offset;
-+ rtx home;
-+
-+ while (block && TREE_CODE(block)==BLOCK)
-+ {
-+ types = BLOCK_VARS(block);
-+
-+ while (types)
-+ {
-+ /* skip the declaration that refers an external variable and
-+ also skip an global variable */
-+ if (! DECL_EXTERNAL (types) && ! TREE_STATIC (types)) {
-+
-+ if (!DECL_RTL_SET_P (types)) goto next;
-+ home = DECL_RTL (types);
-+
-+ /* process for static local variable */
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == SYMBOL_REF)
-+ goto next;
-+
-+ if (GET_CODE (home) == MEM
-+ && XEXP (home, 0) == virtual_stack_vars_rtx)
-+ {
-+ offset = 0;
-+
-+ /* the operand related to the sweep variable */
-+ if (sweep_offset <= offset
-+ && offset < sweep_offset + sweep_size)
-+ {
-+ offset = sweep_frame_offset - sweep_size - sweep_offset;
-+
-+ XEXP (home, 0) = plus_constant (virtual_stack_vars_rtx, offset);
-+ XEXP (home, 0)->used = 1;
-+ }
-+ else if (sweep_offset <= offset
-+ && offset < sweep_frame_offset)
-+ { /* the rest of variables under sweep_frame_offset, so shift the location */
-+ XEXP (home, 0) = plus_constant (virtual_stack_vars_rtx, -sweep_size);
-+ XEXP (home, 0)->used = 1;
-+ }
-+ }
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == MEM)
-+ {
-+ /* process for dynamically allocated aray */
-+ home = XEXP (home, 0);
-+ }
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == PLUS
-+ && XEXP (XEXP (home, 0), 0) == virtual_stack_vars_rtx
-+ && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
-+ {
-+ if (! XEXP (home, 0)->used)
-+ {
-+ offset = AUTO_OFFSET(XEXP (home, 0));
-+
-+ /* the operand related to the sweep variable */
-+ if (sweep_offset <= offset
-+ && offset < sweep_offset + sweep_size)
-+ {
-+
-+ offset += sweep_frame_offset - sweep_size - sweep_offset;
-+ XEXP (XEXP (home, 0), 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ else if (sweep_offset <= offset
-+ && offset < sweep_frame_offset)
-+ { /* the rest of variables under sweep_frame_offset,
-+ so shift the location */
-+
-+ XEXP (XEXP (home, 0), 1)
-+ = gen_rtx_CONST_INT (VOIDmode, offset - sweep_size);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ }
-+ }
-+
-+ }
-+ next:
-+ types = TREE_CHAIN(types);
-+ }
-+
-+ sweep_string_in_decls (BLOCK_SUBBLOCKS (block), sweep_offset, sweep_size);
-+ block = BLOCK_CHAIN (block);
-+ }
-+}
-+
-+
-+static void
-+sweep_string_in_args (parms, sweep_offset, sweep_size)
-+ tree parms;
-+ HOST_WIDE_INT sweep_offset, sweep_size;
-+{
-+ rtx home;
-+ HOST_WIDE_INT offset;
-+
-+ for (; parms; parms = TREE_CHAIN (parms))
-+ if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
-+ {
-+ if (PARM_PASSED_IN_MEMORY (parms) && DECL_NAME (parms))
-+ {
-+ home = DECL_INCOMING_RTL (parms);
-+
-+ if (XEXP (home, 0)->used) continue;
-+
-+ offset = AUTO_OFFSET(XEXP (home, 0));
-+
-+ /* the operand related to the sweep variable */
-+ if (AUTO_BASEPTR (XEXP (home, 0)) == virtual_stack_vars_rtx)
-+ {
-+ if (sweep_offset <= offset
-+ && offset < sweep_offset + sweep_size)
-+ {
-+ offset += sweep_frame_offset - sweep_size - sweep_offset;
-+ XEXP (XEXP (home, 0), 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ else if (sweep_offset <= offset
-+ && offset < sweep_frame_offset)
-+ { /* the rest of variables under sweep_frame_offset, so shift the location */
-+ XEXP (XEXP (home, 0), 1) = gen_rtx_CONST_INT (VOIDmode, offset - sweep_size);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+
-+static int has_virtual_reg;
-+
-+static void
-+sweep_string_use_of_insns (insn, sweep_offset, sweep_size)
-+ rtx insn;
-+ HOST_WIDE_INT sweep_offset, sweep_size;
-+{
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ has_virtual_reg = FALSE;
-+ sweep_string_in_operand (insn, &PATTERN (insn), sweep_offset, sweep_size);
-+ sweep_string_in_operand (insn, ®_NOTES (insn), sweep_offset, sweep_size);
-+ }
-+}
-+
-+
-+static void
-+sweep_string_in_operand (insn, loc, sweep_offset, sweep_size)
-+ rtx insn, *loc;
-+ HOST_WIDE_INT sweep_offset, sweep_size;
-+{
-+ register rtx x = *loc;
-+ register enum rtx_code code;
-+ int i, j, k = 0;
-+ HOST_WIDE_INT offset;
-+ const char *fmt;
-+
-+ if (x == 0)
-+ return;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ case ASM_INPUT:
-+ case ADDR_VEC:
-+ case ADDR_DIFF_VEC:
-+ case RETURN:
-+ case ADDRESSOF:
-+ return;
-+
-+ case REG:
-+ if (x == virtual_incoming_args_rtx
-+ || x == virtual_stack_vars_rtx
-+ || x == virtual_stack_dynamic_rtx
-+ || x == virtual_outgoing_args_rtx
-+ || x == virtual_cfa_rtx)
-+ has_virtual_reg = TRUE;
-+ return;
-+
-+ case SET:
-+ /*
-+ skip setjmp setup insn and setjmp restore insn
-+ Example:
-+ (set (MEM (reg:SI xx)) (virtual_stack_vars_rtx)))
-+ (set (virtual_stack_vars_rtx) (REG))
-+ */
-+ if (GET_CODE (XEXP (x, 0)) == MEM
-+ && XEXP (x, 1) == virtual_stack_vars_rtx)
-+ return;
-+ if (XEXP (x, 0) == virtual_stack_vars_rtx
-+ && GET_CODE (XEXP (x, 1)) == REG)
-+ return;
-+ break;
-+
-+ case PLUS:
-+ /* Handle typical case of frame register plus constant. */
-+ if (XEXP (x, 0) == virtual_stack_vars_rtx
-+ && CONSTANT_P (XEXP (x, 1)))
-+ {
-+ if (x->used) goto single_use_of_virtual_reg;
-+
-+ offset = AUTO_OFFSET(x);
-+ if (RTX_INTEGRATED_P (x)) k = -1; /* for inline base ptr */
-+
-+ /* the operand related to the sweep variable */
-+ if (sweep_offset <= offset + k
-+ && offset + k < sweep_offset + sweep_size)
-+ {
-+ offset += sweep_frame_offset - sweep_size - sweep_offset;
-+
-+ XEXP (x, 0) = virtual_stack_vars_rtx;
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+ x->used = 1;
-+ }
-+ else if (sweep_offset <= offset + k
-+ && offset + k < sweep_frame_offset)
-+ { /* the rest of variables under sweep_frame_offset, so shift the location */
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset - sweep_size);
-+ x->used = 1;
-+ }
-+
-+ single_use_of_virtual_reg:
-+ if (has_virtual_reg) {
-+ /* excerpt from insn_invalid_p in recog.c */
-+ int icode = recog_memoized (insn);
-+
-+ if (icode < 0 && asm_noperands (PATTERN (insn)) < 0)
-+ {
-+ rtx temp, seq;
-+
-+ start_sequence ();
-+ temp = force_operand (x, NULL_RTX);
-+ seq = get_insns ();
-+ end_sequence ();
-+
-+ emit_insn_before (seq, insn);
-+ if (! validate_change (insn, loc, temp, 0)
-+ && ! validate_replace_rtx (x, temp, insn))
-+ fatal_insn ("sweep_string_in_operand", insn);
-+ }
-+ }
-+
-+ has_virtual_reg = TRUE;
-+ return;
-+ }
-+
-+#ifdef FRAME_GROWS_DOWNWARD
-+ /*
-+ alert the case of frame register plus constant given by reg.
-+ */
-+ else if (XEXP (x, 0) == virtual_stack_vars_rtx
-+ && GET_CODE (XEXP (x, 1)) == REG)
-+ fatal_insn ("sweep_string_in_operand: unknown addressing", insn);
-+#endif
-+
-+ /*
-+ process further subtree:
-+ Example: (plus:SI (mem/s:SI (plus:SI (reg:SI 17) (const_int 8)))
-+ (const_int 5))
-+ */
-+ break;
-+
-+ case CALL_PLACEHOLDER:
-+ sweep_string_use_of_insns (XEXP (x, 0), sweep_offset, sweep_size);
-+ sweep_string_use_of_insns (XEXP (x, 1), sweep_offset, sweep_size);
-+ sweep_string_use_of_insns (XEXP (x, 2), sweep_offset, sweep_size);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ {
-+ /*
-+ virtual_stack_vars_rtx without offset
-+ Example:
-+ (set (reg:SI xx) (reg:SI 78))
-+ (set (reg:SI xx) (MEM (reg:SI 78)))
-+ */
-+ if (XEXP (x, i) == virtual_stack_vars_rtx)
-+ fatal_insn ("sweep_string_in_operand: unknown fp usage", insn);
-+ sweep_string_in_operand (insn, &XEXP (x, i), sweep_offset, sweep_size);
-+ }
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ sweep_string_in_operand (insn, &XVECEXP (x, i, j), sweep_offset, sweep_size);
-+}
-+
-+
-+/*
-+ change a argument variable to the local variable addressed by the "new" variable.
-+*/
-+static int flag_caui_exit;
-+
-+static void
-+change_arg_use_of_insns (insn, orig, new, size)
-+ rtx insn, orig, *new;
-+ HOST_WIDE_INT size;
-+{
-+ flag_caui_exit = FALSE;
-+ change_arg_use_of_insns_2 (insn, orig, new, size);
-+}
-+
-+static void
-+change_arg_use_of_insns_2 (insn, orig, new, size)
-+ rtx insn, orig, *new;
-+ HOST_WIDE_INT size;
-+{
-+ for (; insn && !flag_caui_exit; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ change_arg_use_in_operand (PATTERN (insn), orig, new, size);
-+ }
-+}
-+
-+
-+
-+static void
-+change_arg_use_in_operand (x, orig, new, size)
-+ rtx x, orig, *new;
-+ HOST_WIDE_INT size;
-+{
-+ register enum rtx_code code;
-+ int i, j;
-+ HOST_WIDE_INT offset;
-+ const char *fmt;
-+
-+ if (x == 0)
-+ return;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ case ASM_INPUT:
-+ case ADDR_VEC:
-+ case ADDR_DIFF_VEC:
-+ case RETURN:
-+ case REG:
-+ case ADDRESSOF:
-+ return;
-+
-+ case MEM:
-+ /* Handle special case of MEM (incoming_args) */
-+ if (GET_CODE (orig) == MEM
-+ && XEXP (x, 0) == virtual_incoming_args_rtx)
-+ {
-+ offset = 0;
-+
-+ /* the operand related to the sweep variable */
-+ if (AUTO_OFFSET(XEXP (orig, 0)) <= offset &&
-+ offset < AUTO_OFFSET(XEXP (orig, 0)) + size) {
-+
-+ offset = AUTO_OFFSET(XEXP (*new, 0))
-+ + (offset - AUTO_OFFSET(XEXP (orig, 0)));
-+
-+ XEXP (x, 0) = plus_constant (virtual_stack_vars_rtx, offset);
-+ XEXP (x, 0)->used = 1;
-+
-+ return;
-+ }
-+ }
-+ break;
-+
-+ case PLUS:
-+ /* Handle special case of frame register plus constant. */
-+ if (GET_CODE (orig) == MEM /* skip if orig is register variable in the optimization */
-+ && XEXP (x, 0) == virtual_incoming_args_rtx && CONSTANT_P (XEXP (x, 1))
-+ && ! x->used)
-+ {
-+ offset = AUTO_OFFSET(x);
-+
-+ /* the operand related to the sweep variable */
-+ if (AUTO_OFFSET(XEXP (orig, 0)) <= offset &&
-+ offset < AUTO_OFFSET(XEXP (orig, 0)) + size) {
-+
-+ offset = AUTO_OFFSET(XEXP (*new, 0))
-+ + (offset - AUTO_OFFSET(XEXP (orig, 0)));
-+
-+ XEXP (x, 0) = virtual_stack_vars_rtx;
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+ x->used = 1;
-+
-+ return;
-+ }
-+
-+ /*
-+ process further subtree:
-+ Example: (plus:SI (mem/s:SI (plus:SI (reg:SI 17) (const_int 8)))
-+ (const_int 5))
-+ */
-+ }
-+ break;
-+
-+ case SET:
-+ /* Handle special case of "set (REG or MEM) (incoming_args)".
-+ It means that the the address of the 1st argument is stored. */
-+ if (GET_CODE (orig) == MEM
-+ && XEXP (x, 1) == virtual_incoming_args_rtx)
-+ {
-+ offset = 0;
-+
-+ /* the operand related to the sweep variable */
-+ if (AUTO_OFFSET(XEXP (orig, 0)) <= offset &&
-+ offset < AUTO_OFFSET(XEXP (orig, 0)) + size) {
-+
-+ offset = AUTO_OFFSET(XEXP (*new, 0))
-+ + (offset - AUTO_OFFSET(XEXP (orig, 0)));
-+
-+ XEXP (x, 1) = plus_constant (virtual_stack_vars_rtx, offset);
-+ XEXP (x, 1)->used = 1;
-+
-+ return;
-+ }
-+ }
-+ break;
-+
-+ case CALL_PLACEHOLDER:
-+ change_arg_use_of_insns_2 (XEXP (x, 0), orig, new, size); if (flag_caui_exit) return;
-+ change_arg_use_of_insns_2 (XEXP (x, 1), orig, new, size); if (flag_caui_exit) return;
-+ change_arg_use_of_insns_2 (XEXP (x, 2), orig, new, size); if (flag_caui_exit) return;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (*new == 0
-+ && code == SET
-+ && SET_SRC (x) == orig
-+ && GET_CODE (SET_DEST (x)) == REG)
-+ {
-+ /* exit to the change_arg_use_of_insns */
-+ flag_caui_exit = TRUE;
-+ x->volatil = 1; /* avoid register elimination in gcse.c (COPY-PROP)*/
-+ return;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ {
-+ if (XEXP (x, i) == orig)
-+ {
-+ if (*new == 0) *new = gen_reg_rtx (GET_MODE (orig));
-+ XEXP (x, i) = *new;
-+ continue;
-+ }
-+ change_arg_use_in_operand (XEXP (x, i), orig, new, size);
-+ }
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ {
-+
-+ if (XVECEXP (x, i, j) == orig)
-+ {
-+ if (*new == 0) *new = gen_reg_rtx (GET_MODE (orig));
-+ XVECEXP (x, i, j) = *new;
-+ continue;
-+ }
-+ change_arg_use_in_operand (XVECEXP (x, i, j), orig, new, size);
-+ }
-+}
-+
-+
-+static void
-+validate_insns_of_varrefs (insn)
-+ rtx insn;
-+{
-+ rtx next;
-+
-+ /* Initialize recognition, indicating that volatile is OK. */
-+ init_recog ();
-+
-+ for (; insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ /* excerpt from insn_invalid_p in recog.c */
-+ int icode = recog_memoized (insn);
-+
-+ if (icode < 0 && asm_noperands (PATTERN (insn)) < 0)
-+ validate_operand_of_varrefs (insn, &PATTERN (insn));
-+ }
-+ }
-+
-+ init_recog_no_volatile ();
-+}
-+
-+
-+static void
-+validate_operand_of_varrefs (insn, loc)
-+ rtx insn, *loc;
-+{
-+ register enum rtx_code code;
-+ rtx x, temp, seq;
-+ int i, j;
-+ const char *fmt;
-+
-+ x = *loc;
-+ if (x == 0)
-+ return;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case USE:
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ case ASM_INPUT:
-+ case ADDR_VEC:
-+ case ADDR_DIFF_VEC:
-+ case RETURN:
-+ case REG:
-+ case ADDRESSOF:
-+ return;
-+
-+ case PLUS:
-+ /* validate insn of frame register plus constant. */
-+ if (GET_CODE (x) == PLUS
-+ && XEXP (x, 0) == virtual_stack_vars_rtx
-+ && CONSTANT_P (XEXP (x, 1)))
-+ {
-+ start_sequence ();
-+ /* temp = force_operand (x, NULL_RTX); */
-+ { /* excerpt from expand_binop in optabs.c */
-+ optab binoptab = add_optab;
-+ enum machine_mode mode = GET_MODE (x);
-+ int icode = (int) binoptab->handlers[(int) mode].insn_code;
-+ enum machine_mode mode1 = insn_data[icode].operand[2].mode;
-+ rtx pat;
-+ rtx xop0 = XEXP (x, 0), xop1 = XEXP (x, 1);
-+ temp = gen_reg_rtx (mode);
-+
-+ /* Now, if insn's predicates don't allow offset operands, put them into
-+ pseudo regs. */
-+
-+ if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
-+ && mode1 != VOIDmode)
-+ xop1 = copy_to_mode_reg (mode1, xop1);
-+
-+ pat = GEN_FCN (icode) (temp, xop0, xop1);
-+ if (pat)
-+ emit_insn (pat);
-+ }
-+ seq = get_insns ();
-+ end_sequence ();
-+
-+ emit_insn_before (seq, insn);
-+ if (! validate_change (insn, loc, temp, 0))
-+ abort ();
-+ return;
-+ }
-+ break;
-+
-+
-+ case CALL_PLACEHOLDER:
-+ validate_insns_of_varrefs (XEXP (x, 0));
-+ validate_insns_of_varrefs (XEXP (x, 1));
-+ validate_insns_of_varrefs (XEXP (x, 2));
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ validate_operand_of_varrefs (insn, &XEXP (x, i));
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ validate_operand_of_varrefs (insn, &XVECEXP (x, i, j));
-+}
-+
-+
-+
-+
-+/*
-+ The following codes are invoked after the instantiation of pseuso registers.
-+
-+ Reorder local variables to place a peudo register after buffers to avoid
-+ the corruption of local variables that could be used to further corrupt
-+ arbitrary memory locations.
-+*/
-+#if !defined(FRAME_GROWS_DOWNWARD) && defined(STACK_GROWS_DOWNWARD)
-+static void push_frame PARAMS ((HOST_WIDE_INT var_size, HOST_WIDE_INT boundary));
-+static void push_frame_in_decls PARAMS ((tree block, HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void push_frame_in_args PARAMS ((tree parms, HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void push_frame_of_insns PARAMS ((rtx insn, HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void push_frame_in_operand PARAMS ((rtx insn, rtx orig, HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void push_frame_of_reg_equiv_memory_loc PARAMS ((HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void push_frame_of_reg_equiv_constant PARAMS ((HOST_WIDE_INT push_size, HOST_WIDE_INT boundary));
-+static void reset_used_flags_for_push_frame PARAMS ((void));
-+static int check_out_of_frame_access PARAMS ((rtx insn, HOST_WIDE_INT boundary));
-+static int check_out_of_frame_access_in_operand PARAMS ((rtx, HOST_WIDE_INT boundary));
-+#endif
-+
-+rtx
-+assign_stack_local_for_pseudo_reg (mode, size, align)
-+ enum machine_mode mode;
-+ HOST_WIDE_INT size;
-+ int align;
-+{
-+#if defined(FRAME_GROWS_DOWNWARD) || !defined(STACK_GROWS_DOWNWARD)
-+ return assign_stack_local (mode, size, align);
-+#else
-+ tree blocks = DECL_INITIAL (current_function_decl);
-+ rtx new;
-+ HOST_WIDE_INT saved_frame_offset, units_per_push, starting_frame;
-+ int first_call_from_purge_addressof, first_call_from_global_alloc;
-+
-+ if (! flag_propolice_protection
-+ || size == 0
-+ || ! blocks
-+ || current_function_is_inlinable
-+ || ! search_string_from_argsandvars (1)
-+ || current_function_contains_functions)
-+ return assign_stack_local (mode, size, align);
-+
-+ first_call_from_purge_addressof = !push_frame_offset && !cse_not_expected;
-+ first_call_from_global_alloc = !saved_cse_not_expected && cse_not_expected;
-+ saved_cse_not_expected = cse_not_expected;
-+
-+ starting_frame = (STARTING_FRAME_OFFSET)?STARTING_FRAME_OFFSET:BIGGEST_ALIGNMENT / BITS_PER_UNIT;
-+ units_per_push = MAX(BIGGEST_ALIGNMENT / BITS_PER_UNIT,
-+ GET_MODE_SIZE (mode));
-+
-+ if (first_call_from_purge_addressof)
-+ {
-+ push_frame_offset = push_allocated_offset;
-+ if (check_out_of_frame_access (get_insns (), starting_frame))
-+ {
-+ /* if there is an access beyond frame, push dummy region to seperate
-+ the address of instantiated variables */
-+ push_frame (GET_MODE_SIZE (DImode), 0);
-+ assign_stack_local (BLKmode, GET_MODE_SIZE (DImode), -1);
-+ }
-+ }
-+
-+ if (first_call_from_global_alloc)
-+ {
-+ push_frame_offset = push_allocated_offset = 0;
-+ if (check_out_of_frame_access (get_insns (), starting_frame))
-+ {
-+ if (STARTING_FRAME_OFFSET)
-+ {
-+ /* if there is an access beyond frame, push dummy region
-+ to seperate the address of instantiated variables */
-+ push_frame (GET_MODE_SIZE (DImode), 0);
-+ assign_stack_local (BLKmode, GET_MODE_SIZE (DImode), -1);
-+ }
-+ else
-+ push_allocated_offset = starting_frame;
-+ }
-+ }
-+
-+ saved_frame_offset = frame_offset;
-+ frame_offset = push_frame_offset;
-+
-+ new = assign_stack_local (mode, size, align);
-+
-+ push_frame_offset = frame_offset;
-+ frame_offset = saved_frame_offset;
-+
-+ if (push_frame_offset > push_allocated_offset)
-+ {
-+ push_frame (units_per_push, push_allocated_offset + STARTING_FRAME_OFFSET);
-+
-+ assign_stack_local (BLKmode, units_per_push, -1);
-+ push_allocated_offset += units_per_push;
-+ }
-+
-+ /* At the second call from global alloc, alpha push frame and assign
-+ a local variable to the top of the stack */
-+ if (first_call_from_global_alloc && STARTING_FRAME_OFFSET == 0)
-+ push_frame_offset = push_allocated_offset = 0;
-+
-+ return new;
-+#endif
-+}
-+
-+
-+#if !defined(FRAME_GROWS_DOWNWARD) && defined(STACK_GROWS_DOWNWARD)
-+/*
-+ push frame infomation for instantiating pseudo register at the top of stack.
-+ This is only for the "frame grows upward", it means FRAME_GROWS_DOWNWARD is
-+ not defined.
-+
-+ It is called by purge_addressof function and global_alloc (or reload)
-+ function.
-+*/
-+static void
-+push_frame (var_size, boundary)
-+ HOST_WIDE_INT var_size, boundary;
-+{
-+ reset_used_flags_for_push_frame();
-+
-+ /* scan all declarations of variables and fix the offset address of the variable based on the frame pointer */
-+ push_frame_in_decls (DECL_INITIAL (current_function_decl), var_size, boundary);
-+
-+ /* scan all argument variable and fix the offset address based on the frame pointer */
-+ push_frame_in_args (DECL_ARGUMENTS (current_function_decl), var_size, boundary);
-+
-+ /* scan all operands of all insns and fix the offset address based on the frame pointer */
-+ push_frame_of_insns (get_insns (), var_size, boundary);
-+
-+ /* scan all reg_equiv_memory_loc and reg_equiv_constant*/
-+ push_frame_of_reg_equiv_memory_loc (var_size, boundary);
-+ push_frame_of_reg_equiv_constant (var_size, boundary);
-+
-+ reset_used_flags_for_push_frame();
-+}
-+
-+static void
-+reset_used_flags_for_push_frame()
-+{
-+ int i;
-+ extern rtx *reg_equiv_memory_loc;
-+ extern rtx *reg_equiv_constant;
-+
-+ /* Clear all the USED bits in operands of all insns and declarations of local vars */
-+ reset_used_flags_for_decls (DECL_INITIAL (current_function_decl));
-+ reset_used_flags_for_insns (get_insns ());
-+
-+
-+ /* The following codes are processed if the push_frame is called from
-+ global_alloc (or reload) function */
-+ if (reg_equiv_memory_loc == 0) return;
-+
-+ for (i=LAST_VIRTUAL_REGISTER+1; i < max_regno; i++)
-+ if (reg_equiv_memory_loc[i])
-+ {
-+ rtx x = reg_equiv_memory_loc[i];
-+
-+ if (GET_CODE (x) == MEM
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && AUTO_BASEPTR (XEXP (x, 0)) == frame_pointer_rtx)
-+ {
-+ /* reset */
-+ XEXP (x, 0)->used = 0;
-+ }
-+ }
-+
-+
-+ if (reg_equiv_constant == 0) return;
-+
-+ for (i=LAST_VIRTUAL_REGISTER+1; i < max_regno; i++)
-+ if (reg_equiv_constant[i])
-+ {
-+ rtx x = reg_equiv_constant[i];
-+
-+ if (GET_CODE (x) == PLUS
-+ && AUTO_BASEPTR (x) == frame_pointer_rtx)
-+ {
-+ /* reset */
-+ x->used = 0;
-+ }
-+ }
-+}
-+
-+static void
-+push_frame_in_decls (block, push_size, boundary)
-+ tree block;
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ tree types;
-+ HOST_WIDE_INT offset;
-+ rtx home;
-+
-+ while (block && TREE_CODE(block)==BLOCK)
-+ {
-+ types = BLOCK_VARS(block);
-+
-+ while (types)
-+ {
-+ /* skip the declaration that refers an external variable and
-+ also skip an global variable */
-+ if (! DECL_EXTERNAL (types) && ! TREE_STATIC (types))
-+ {
-+
-+ if (!DECL_RTL_SET_P (types)) goto next;
-+ home = DECL_RTL (types);
-+
-+ /* process for static local variable */
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == SYMBOL_REF)
-+ goto next;
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == REG)
-+ {
-+ if (XEXP (home, 0) != frame_pointer_rtx
-+ || boundary != 0)
-+ goto next;
-+
-+ XEXP (home, 0) = plus_constant (frame_pointer_rtx,
-+ push_size);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == MEM)
-+ {
-+
-+ /* process for dynamically allocated aray */
-+ home = XEXP (home, 0);
-+ }
-+
-+ if (GET_CODE (home) == MEM
-+ && GET_CODE (XEXP (home, 0)) == PLUS
-+ && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
-+ {
-+ offset = AUTO_OFFSET(XEXP (home, 0));
-+
-+ if (! XEXP (home, 0)->used
-+ && offset >= boundary)
-+ {
-+ offset += push_size;
-+ XEXP (XEXP (home, 0), 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ }
-+
-+ }
-+ next:
-+ types = TREE_CHAIN(types);
-+ }
-+
-+ push_frame_in_decls (BLOCK_SUBBLOCKS (block), push_size, boundary);
-+ block = BLOCK_CHAIN (block);
-+ }
-+}
-+
-+
-+static void
-+push_frame_in_args (parms, push_size, boundary)
-+ tree parms;
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ rtx home;
-+ HOST_WIDE_INT offset;
-+
-+ for (; parms; parms = TREE_CHAIN (parms))
-+ if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
-+ {
-+ if (PARM_PASSED_IN_MEMORY (parms) && DECL_NAME (parms))
-+ {
-+ home = DECL_INCOMING_RTL (parms);
-+ offset = AUTO_OFFSET(XEXP (home, 0));
-+
-+ if (XEXP (home, 0)->used || offset < boundary) continue;
-+
-+ /* the operand related to the sweep variable */
-+ if (AUTO_BASEPTR (XEXP (home, 0)) == frame_pointer_rtx)
-+ {
-+ if (XEXP (home, 0) == frame_pointer_rtx)
-+ XEXP (home, 0) = plus_constant (frame_pointer_rtx,
-+ push_size);
-+ else {
-+ offset += push_size;
-+ XEXP (XEXP (home, 0), 1) = gen_rtx_CONST_INT (VOIDmode,
-+ offset);
-+ }
-+
-+ /* mark */
-+ XEXP (home, 0)->used = 1;
-+ }
-+ }
-+ }
-+}
-+
-+
-+static int insn_pushed;
-+static int *fp_equiv = 0;
-+
-+static void
-+push_frame_of_insns (insn, push_size, boundary)
-+ rtx insn;
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ /* init fp_equiv */
-+ fp_equiv = (int *) xcalloc (max_reg_num (), sizeof (int));
-+
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ insn_pushed = FALSE;
-+ push_frame_in_operand (insn, PATTERN (insn), push_size, boundary);
-+
-+ if (insn_pushed)
-+ {
-+ rtx trial = insn;
-+ rtx before = PREV_INSN (trial);
-+ rtx after = NEXT_INSN (trial);
-+ int has_barrier = 0;
-+ rtx tem;
-+ rtx seq = split_insns (PATTERN (insn), insn);
-+
-+ /* If we are splitting a JUMP_INSN, it might be followed by a
-+ BARRIER. We may need to handle this specially. */
-+ if (after && GET_CODE (after) == BARRIER)
-+ {
-+ has_barrier = 1;
-+ after = NEXT_INSN (after);
-+ }
-+
-+ if (seq && GET_CODE (seq) == SEQUENCE)
-+ {
-+ if (XVECLEN (seq, 0) == 2)
-+ {
-+ rtx pattern = PATTERN (XVECEXP (seq, 0, 1));
-+
-+ if (GET_CODE (pattern) == SET
-+ && GET_CODE (XEXP (pattern, 0)) == REG
-+ && GET_CODE (XEXP (pattern, 1)) == PLUS
-+ && XEXP (pattern, 0) == XEXP (XEXP (pattern, 1), 0)
-+ && CONSTANT_P (XEXP (XEXP (pattern, 1), 1)))
-+ {
-+ rtx offset = XEXP (XEXP (pattern, 1), 1);
-+ fp_equiv[REGNO (XEXP (pattern, 0))] = INTVAL (offset);
-+
-+ /* replace the pattern of the insn */
-+ add_insn_after (XVECEXP (seq, 0, 0), before);
-+ delete_insn (trial);
-+ goto next;
-+ }
-+ }
-+
-+ /* excerpt from emit-rtl.c: L3320 */
-+ tem = emit_insn_after (seq, trial);
-+
-+ delete_related_insns (trial);
-+ if (has_barrier)
-+ emit_barrier_after (tem);
-+
-+ /* Recursively call try_split for each new insn created */
-+ for (tem = NEXT_INSN (before); tem != after;
-+ tem = NEXT_INSN (tem))
-+ if (! INSN_DELETED_P (tem) && INSN_P (tem))
-+ tem = try_split (PATTERN (tem), tem, 1);
-+ }
-+ }
-+
-+ next:
-+ /* push frame in NOTE */
-+ push_frame_in_operand (insn, REG_NOTES (insn), push_size, boundary);
-+
-+ /* push frame in CALL EXPR_LIST */
-+ if (GET_CODE (insn) == CALL_INSN)
-+ push_frame_in_operand (insn, CALL_INSN_FUNCTION_USAGE (insn), push_size, boundary);
-+ }
-+
-+ /* Clean up. */
-+ free (fp_equiv);
-+}
-+
-+
-+static void
-+push_frame_in_operand (insn, orig, push_size, boundary)
-+ rtx insn, orig;
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ register rtx x = orig;
-+ register enum rtx_code code;
-+ int i, j;
-+ HOST_WIDE_INT offset;
-+ const char *fmt;
-+
-+ if (x == 0)
-+ return;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ case ASM_INPUT:
-+ case ADDR_VEC:
-+ case ADDR_DIFF_VEC:
-+ case RETURN:
-+ case REG:
-+ case ADDRESSOF:
-+ case USE:
-+ return;
-+
-+ case SET:
-+ /*
-+ skip setjmp setup insn and setjmp restore insn
-+ alpha case:
-+ (set (MEM (reg:SI xx)) (frame_pointer_rtx)))
-+ (set (frame_pointer_rtx) (REG))
-+ */
-+ if (GET_CODE (XEXP (x, 0)) == MEM
-+ && XEXP (x, 1) == frame_pointer_rtx)
-+ return;
-+ if (XEXP (x, 0) == frame_pointer_rtx
-+ && GET_CODE (XEXP (x, 1)) == REG)
-+ return;
-+
-+ /*
-+ powerpc case: restores setjmp address
-+ (set (frame_pointer_rtx) (plus frame_pointer_rtx const_int -n))
-+ or
-+ (set (reg) (plus frame_pointer_rtx const_int -n))
-+ (set (frame_pointer_rtx) (reg))
-+ */
-+ if (GET_CODE (XEXP (x, 0)) == REG
-+ && GET_CODE (XEXP (x, 1)) == PLUS
-+ && XEXP (XEXP (x, 1), 0) == frame_pointer_rtx
-+ && CONSTANT_P (XEXP (XEXP (x, 1), 1))
-+ && INTVAL (XEXP (XEXP (x, 1), 1)) < 0)
-+ {
-+ x = XEXP (x, 1);
-+ offset = AUTO_OFFSET(x);
-+ if (x->used || abs (offset) < boundary)
-+ return;
-+
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset - push_size);
-+ x->used = 1; insn_pushed = TRUE;
-+ return;
-+ }
-+
-+ /* reset fp_equiv register */
-+ else if (GET_CODE (XEXP (x, 0)) == REG
-+ && fp_equiv[REGNO (XEXP (x, 0))])
-+ fp_equiv[REGNO (XEXP (x, 0))] = 0;
-+
-+ /* propagete fp_equiv register */
-+ else if (GET_CODE (XEXP (x, 0)) == REG
-+ && GET_CODE (XEXP (x, 1)) == REG
-+ && fp_equiv[REGNO (XEXP (x, 1))])
-+ if (REGNO (XEXP (x, 0)) <= LAST_VIRTUAL_REGISTER
-+ || reg_renumber[REGNO (XEXP (x, 0))] > 0)
-+ fp_equiv[REGNO (XEXP (x, 0))] = fp_equiv[REGNO (XEXP (x, 1))];
-+ break;
-+
-+ case MEM:
-+ if (XEXP (x, 0) == frame_pointer_rtx
-+ && boundary == 0)
-+ {
-+ XEXP (x, 0) = plus_constant (frame_pointer_rtx, push_size);
-+ XEXP (x, 0)->used = 1; insn_pushed = TRUE;
-+ return;
-+ }
-+ break;
-+
-+ case PLUS:
-+ offset = AUTO_OFFSET(x);
-+
-+ /* Handle special case of frame register plus constant. */
-+ if (CONSTANT_P (XEXP (x, 1))
-+ && XEXP (x, 0) == frame_pointer_rtx)
-+ {
-+ if (x->used || offset < boundary)
-+ return;
-+
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset + push_size);
-+ x->used = 1; insn_pushed = TRUE;
-+
-+ return;
-+ }
-+ /*
-+ Handle alpha case:
-+ (plus:SI (subreg:SI (reg:DI 63 FP) 0) (const_int 64 [0x40]))
-+ */
-+ if (CONSTANT_P (XEXP (x, 1))
-+ && GET_CODE (XEXP (x, 0)) == SUBREG
-+ && SUBREG_REG (XEXP (x, 0)) == frame_pointer_rtx)
-+ {
-+ if (x->used || offset < boundary)
-+ return;
-+
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset + push_size);
-+ x->used = 1; insn_pushed = TRUE;
-+
-+ return;
-+ }
-+ /*
-+ Handle powerpc case:
-+ (set (reg x) (plus fp const))
-+ (set (.....) (... (plus (reg x) (const B))))
-+ */
-+ else if (CONSTANT_P (XEXP (x, 1))
-+ && GET_CODE (XEXP (x, 0)) == REG
-+ && fp_equiv[REGNO (XEXP (x, 0))])
-+ {
-+ if (x->used) return;
-+
-+ offset += fp_equiv[REGNO (XEXP (x, 0))];
-+
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+ x->used = 1; insn_pushed = TRUE;
-+
-+ return;
-+ }
-+ /*
-+ Handle special case of frame register plus reg (constant).
-+ (set (reg x) (const B))
-+ (set (....) (...(plus fp (reg x))))
-+ */
-+ else if (XEXP (x, 0) == frame_pointer_rtx
-+ && GET_CODE (XEXP (x, 1)) == REG
-+ && PREV_INSN (insn)
-+ && PATTERN (PREV_INSN (insn))
-+ && SET_DEST (PATTERN (PREV_INSN (insn))) == XEXP (x, 1)
-+ && CONSTANT_P (SET_SRC (PATTERN (PREV_INSN (insn)))))
-+ {
-+ HOST_WIDE_INT offset = INTVAL (SET_SRC (PATTERN (PREV_INSN (insn))));
-+
-+ if (x->used || offset < boundary)
-+ return;
-+
-+ SET_SRC (PATTERN (PREV_INSN (insn)))
-+ = gen_rtx_CONST_INT (VOIDmode, offset + push_size);
-+ x->used = 1;
-+ XEXP (x, 1)->used = 1;
-+
-+ return;
-+ }
-+ /* Handle special case of frame register plus reg (used). */
-+ else if (XEXP (x, 0) == frame_pointer_rtx
-+ && XEXP (x, 1)->used)
-+ {
-+ x->used = 1;
-+ return;
-+ }
-+ /*
-+ process further subtree:
-+ Example: (plus:SI (mem/s:SI (plus:SI (reg:SI 17) (const_int 8)))
-+ (const_int 5))
-+ */
-+ break;
-+
-+ case CALL_PLACEHOLDER:
-+ push_frame_of_insns (XEXP (x, 0), push_size, boundary);
-+ push_frame_of_insns (XEXP (x, 1), push_size, boundary);
-+ push_frame_of_insns (XEXP (x, 2), push_size, boundary);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ {
-+ if (XEXP (x, i) == frame_pointer_rtx && boundary == 0)
-+ fatal_insn ("push_frame_in_operand", insn);
-+ push_frame_in_operand (insn, XEXP (x, i), push_size, boundary);
-+ }
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ push_frame_in_operand (insn, XVECEXP (x, i, j), push_size, boundary);
-+}
-+
-+static void
-+push_frame_of_reg_equiv_memory_loc (push_size, boundary)
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ int i;
-+ extern rtx *reg_equiv_memory_loc;
-+
-+ /* This function is processed if the push_frame is called from
-+ global_alloc (or reload) function */
-+ if (reg_equiv_memory_loc == 0) return;
-+
-+ for (i=LAST_VIRTUAL_REGISTER+1; i < max_regno; i++)
-+ if (reg_equiv_memory_loc[i])
-+ {
-+ rtx x = reg_equiv_memory_loc[i];
-+ int offset;
-+
-+ if (GET_CODE (x) == MEM
-+ && GET_CODE (XEXP (x, 0)) == PLUS
-+ && XEXP (XEXP (x, 0), 0) == frame_pointer_rtx)
-+ {
-+ offset = AUTO_OFFSET(XEXP (x, 0));
-+
-+ if (! XEXP (x, 0)->used
-+ && offset >= boundary)
-+ {
-+ offset += push_size;
-+ XEXP (XEXP (x, 0), 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+
-+ /* mark */
-+ XEXP (x, 0)->used = 1;
-+ }
-+ }
-+ else if (GET_CODE (x) == MEM
-+ && XEXP (x, 0) == frame_pointer_rtx
-+ && boundary == 0)
-+ {
-+ XEXP (x, 0) = plus_constant (frame_pointer_rtx, push_size);
-+ XEXP (x, 0)->used = 1; insn_pushed = TRUE;
-+ }
-+ }
-+}
-+
-+static void
-+push_frame_of_reg_equiv_constant (push_size, boundary)
-+ HOST_WIDE_INT push_size, boundary;
-+{
-+ int i;
-+ extern rtx *reg_equiv_constant;
-+
-+ /* This function is processed if the push_frame is called from
-+ global_alloc (or reload) function */
-+ if (reg_equiv_constant == 0) return;
-+
-+ for (i=LAST_VIRTUAL_REGISTER+1; i < max_regno; i++)
-+ if (reg_equiv_constant[i])
-+ {
-+ rtx x = reg_equiv_constant[i];
-+ int offset;
-+
-+ if (GET_CODE (x) == PLUS
-+ && XEXP (x, 0) == frame_pointer_rtx)
-+ {
-+ offset = AUTO_OFFSET(x);
-+
-+ if (! x->used
-+ && offset >= boundary)
-+ {
-+ offset += push_size;
-+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset);
-+
-+ /* mark */
-+ x->used = 1;
-+ }
-+ }
-+ else if (x == frame_pointer_rtx
-+ && boundary == 0)
-+ {
-+ reg_equiv_constant[i]
-+ = plus_constant (frame_pointer_rtx, push_size);
-+ reg_equiv_constant[i]->used = 1; insn_pushed = TRUE;
-+ }
-+ }
-+}
-+
-+static int
-+check_out_of_frame_access (insn, boundary)
-+ rtx insn;
-+ HOST_WIDE_INT boundary;
-+{
-+ for (; insn; insn = NEXT_INSN (insn))
-+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-+ || GET_CODE (insn) == CALL_INSN)
-+ {
-+ if (check_out_of_frame_access_in_operand (PATTERN (insn), boundary))
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+
-+static int
-+check_out_of_frame_access_in_operand (orig, boundary)
-+ rtx orig;
-+ HOST_WIDE_INT boundary;
-+{
-+ register rtx x = orig;
-+ register enum rtx_code code;
-+ int i, j;
-+ const char *fmt;
-+
-+ if (x == 0)
-+ return FALSE;
-+
-+ code = GET_CODE (x);
-+
-+ switch (code)
-+ {
-+ case CONST_INT:
-+ case CONST_DOUBLE:
-+ case CONST:
-+ case SYMBOL_REF:
-+ case CODE_LABEL:
-+ case PC:
-+ case CC0:
-+ case ASM_INPUT:
-+ case ADDR_VEC:
-+ case ADDR_DIFF_VEC:
-+ case RETURN:
-+ case REG:
-+ case ADDRESSOF:
-+ return FALSE;
-+
-+ case MEM:
-+ if (XEXP (x, 0) == frame_pointer_rtx)
-+ if (0 < boundary) return TRUE;
-+ break;
-+
-+ case PLUS:
-+ /* Handle special case of frame register plus constant. */
-+ if (CONSTANT_P (XEXP (x, 1))
-+ && XEXP (x, 0) == frame_pointer_rtx)
-+ {
-+ if (0 <= AUTO_OFFSET(x)
-+ && AUTO_OFFSET(x) < boundary) return TRUE;
-+ return FALSE;
-+ }
-+ /*
-+ process further subtree:
-+ Example: (plus:SI (mem/s:SI (plus:SI (reg:SI 17) (const_int 8)))
-+ (const_int 5))
-+ */
-+ break;
-+
-+ case CALL_PLACEHOLDER:
-+ if (check_out_of_frame_access (XEXP (x, 0), boundary)) return TRUE;
-+ if (check_out_of_frame_access (XEXP (x, 1), boundary)) return TRUE;
-+ if (check_out_of_frame_access (XEXP (x, 2), boundary)) return TRUE;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /* Scan all subexpressions. */
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
-+ if (*fmt == 'e')
-+ {
-+ if (check_out_of_frame_access_in_operand (XEXP (x, i), boundary))
-+ return TRUE;
-+ }
-+ else if (*fmt == 'E')
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ if (check_out_of_frame_access_in_operand (XVECEXP (x, i, j), boundary))
-+ return TRUE;
-+
-+ return FALSE;
-+}
-+#endif
-diff -urN gcc-3.3.1/gcc/protector.h gcc-3.3.1-pp/gcc/protector.h
---- gcc-3.3.1/gcc/protector.h 1970-01-01 00:00:00.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/protector.h 2003-09-12 13:40:28.000000000 +0000
-@@ -0,0 +1,48 @@
-+/* RTL buffer overflow protection function for GNU C compiler
-+ Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+
-+/* declaration of GUARD variable */
-+#define GUARD_m Pmode
-+#define UNITS_PER_GUARD MAX(BIGGEST_ALIGNMENT / BITS_PER_UNIT, GET_MODE_SIZE (GUARD_m))
-+
-+#ifndef L_stack_smash_handler
-+
-+/* insert a guard variable before a character buffer and change the order
-+ of pointer variables, character buffers and pointer arguments */
-+
-+extern void prepare_stack_protection PARAMS ((int inlinable));
-+
-+#ifdef TREE_CODE
-+/* search a character array from the specified type tree */
-+
-+extern int search_string_def PARAMS ((tree names));
-+#endif
-+
-+/* examine whether the input contains frame pointer addressing */
-+
-+extern int contains_fp PARAMS ((rtx op));
-+
-+/* allocate a local variable in the stack area before character buffers
-+ to avoid the corruption of it */
-+
-+extern rtx assign_stack_local_for_pseudo_reg PARAMS ((enum machine_mode, HOST_WIDE_INT, int));
-+
-+#endif
-diff -urN gcc-3.3.1/gcc/reload1.c gcc-3.3.1-pp/gcc/reload1.c
---- gcc-3.3.1/gcc/reload1.c 2003-06-07 05:30:09.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/reload1.c 2003-09-12 13:40:28.000000000 +0000
-@@ -42,6 +42,7 @@
- #include "toplev.h"
- #include "except.h"
- #include "tree.h"
-+#include "protector.h"
-
- /* This file contains the reload pass of the compiler, which is
- run after register allocation has been done. It checks that
-@@ -1992,7 +1993,7 @@
- if (from_reg == -1)
- {
- /* No known place to spill from => no slot to reuse. */
-- x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size,
-+ x = assign_stack_local_for_pseudo_reg (GET_MODE (regno_reg_rtx[i]), total_size,
- inherent_size == total_size ? 0 : -1);
- if (BYTES_BIG_ENDIAN)
- /* Cancel the big-endian correction done in assign_stack_local.
-diff -urN gcc-3.3.1/gcc/simplify-rtx.c gcc-3.3.1-pp/gcc/simplify-rtx.c
---- gcc-3.3.1/gcc/simplify-rtx.c 2003-07-03 07:38:22.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/simplify-rtx.c 2003-09-12 13:40:28.000000000 +0000
-@@ -1670,7 +1670,8 @@
- int n_ops = 2, input_ops = 2, input_consts = 0, n_consts;
- int first, negate, changed;
- int i, j;
--
-+ HOST_WIDE_INT fp_offset = 0;
-+
- memset ((char *) ops, 0, sizeof ops);
-
- /* Set up the two operands and then expand them until nothing has been
-@@ -1695,6 +1696,10 @@
- switch (this_code)
- {
- case PLUS:
-+ if (flag_propolice_protection
-+ && XEXP (this_op, 0) == virtual_stack_vars_rtx
-+ && GET_CODE (XEXP (this_op, 1)) == CONST_INT)
-+ fp_offset = INTVAL (XEXP (this_op, 1));
- case MINUS:
- if (n_ops == 7)
- return NULL_RTX;
-@@ -1849,10 +1854,10 @@
- && GET_CODE (ops[n_ops - 1].op) == CONST_INT
- && CONSTANT_P (ops[n_ops - 2].op))
- {
-- rtx value = ops[n_ops - 1].op;
-+ int value = INTVAL (ops[n_ops - 1].op);
- if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
-- value = neg_const_int (mode, value);
-- ops[n_ops - 2].op = plus_constant (ops[n_ops - 2].op, INTVAL (value));
-+ value = -value;
-+ ops[n_ops - 2].op = plus_constant (ops[n_ops - 2].op, value);
- n_ops--;
- }
-
-@@ -1871,6 +1876,54 @@
- || (n_ops + n_consts == input_ops && n_consts <= input_consts)))
- return NULL_RTX;
-
-+ if (flag_propolice_protection)
-+ {
-+ /* keep the addressing style of local variables
-+ as (plus (virtual_stack_vars_rtx) (CONST_int x))
-+ (1) inline function is expanded, (+ (+VFP c1) -c2)=>(+ VFP c1-c2)
-+ (2) the case ary[r-1], (+ (+VFP c1) (+r -1))=>(+ R (+r -1))
-+ */
-+ for (i = 0; i < n_ops; i++)
-+#ifdef FRAME_GROWS_DOWNWARD
-+ if (ops[i].op == virtual_stack_vars_rtx)
-+#else
-+ if (ops[i].op == virtual_stack_vars_rtx
-+ || ops[i].op == frame_pointer_rtx)
-+#endif
-+ {
-+ if (GET_CODE (ops[n_ops - 1].op) == CONST_INT)
-+ {
-+ HOST_WIDE_INT value = INTVAL (ops[n_ops - 1].op);
-+ if (n_ops < 3 || value >= fp_offset)
-+ {
-+ ops[i].op = plus_constant (ops[i].op, value);
-+ n_ops--;
-+ }
-+ else
-+ {
-+ if (!force
-+ && (n_ops+1 + n_consts > input_ops
-+ || (n_ops+1 + n_consts == input_ops && n_consts <= input_consts)))
-+ return NULL_RTX;
-+ ops[n_ops - 1].op = GEN_INT (value-fp_offset);
-+ ops[i].op = plus_constant (ops[i].op, fp_offset);
-+ }
-+ }
-+ /* buf[BUFSIZE]: buf is the first local variable (+ (+ fp -S) S)
-+ or (+ (fp 0) r) ==> ((+ (+fp 1) r) -1) */
-+ else if (fp_offset != 0)
-+ return NULL_RTX;
-+#ifndef FRAME_GROWS_DOWNWARD
-+ /*
-+ * For the case of buf[i], i: REG, buf: (plus fp 0),
-+ */
-+ else if (fp_offset == 0)
-+ return NULL_RTX;
-+#endif
-+ break;
-+ }
-+ }
-+
- /* Put a non-negated operand first. If there aren't any, make all
- operands positive and negate the whole thing later. */
-
-diff -urN gcc-3.3.1/gcc/toplev.c gcc-3.3.1-pp/gcc/toplev.c
---- gcc-3.3.1/gcc/toplev.c 2003-07-18 06:59:16.000000000 +0000
-+++ gcc-3.3.1-pp/gcc/toplev.c 2003-09-12 13:40:28.000000000 +0000
-@@ -904,6 +904,13 @@
- minimum function alignment. Zero means no alignment is forced. */
- int force_align_functions_log;
-
-+#if defined(STACK_PROTECTOR) && defined(STACK_GROWS_DOWNWARD)
-+/* Nonzero means use propolice as a stack protection method */
-+int flag_propolice_protection = 1;
-+#else
-+int flag_propolice_protection = 0;
-+#endif
-+
- /* Table of supported debugging formats. */
- static const struct
- {
-@@ -1188,6 +1195,10 @@
- N_("Trap for signed overflow in addition / subtraction / multiplication") },
- { "new-ra", &flag_new_regalloc, 1,
- N_("Use graph coloring register allocation.") },
-+ {"stack-protector", &flag_propolice_protection, 1,
-+ N_("Enables stack protection") },
-+ {"no-stack-protector", &flag_propolice_protection, 0,
-+ N_("Disables stack protection") },
- };
-
- /* Table of language-specific options. */
-@@ -1547,7 +1558,9 @@
- {"missing-noreturn", &warn_missing_noreturn, 1,
- N_("Warn about functions which might be candidates for attribute noreturn") },
- {"strict-aliasing", &warn_strict_aliasing, 1,
-- N_ ("Warn about code which might break the strict aliasing rules") }
-+ N_ ("Warn about code which might break the strict aliasing rules") },
-+ {"stack-protector", &warn_stack_protector, 1,
-+ N_("Warn when disabling stack protector for some reason")}
- };
-
- void
-@@ -2449,6 +2462,8 @@
-
- insns = get_insns ();
-
-+ if (flag_propolice_protection) prepare_stack_protection (inlinable);
-+
- /* Dump the rtl code if we are dumping rtl. */
-
- if (open_dump_file (DFI_rtl, decl))