@@ -8477,6 +8477,71 @@ ix86_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
setup_incoming_varargs_64 (&next_cum);
}
+static void
+ix86_setup_incoming_vararg_bounds (cumulative_args_t cum_v,
+ enum machine_mode mode,
+ tree type,
+ int *pretend_size ATTRIBUTE_UNUSED,
+ int no_rtl)
+{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ CUMULATIVE_ARGS next_cum;
+ tree fntype;
+ rtx save_area;
+ int bnd_reg, i, max;
+
+ gcc_assert (!no_rtl);
+
+ /* Do nothing if we use plain pointer to argument area. */
+ if (!TARGET_64BIT || cum->call_abi == MS_ABI)
+ return;
+
+ fntype = TREE_TYPE (current_function_decl);
+
+ /* For varargs, we do not want to skip the dummy va_dcl argument.
+ For stdargs, we do want to skip the last named argument. */
+ next_cum = *cum;
+ if (stdarg_p (fntype))
+ ix86_function_arg_advance (pack_cumulative_args (&next_cum), mode, type,
+ true);
+ save_area = frame_pointer_rtx;
+
+ max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
+ if (max > X86_64_REGPARM_MAX)
+ max = X86_64_REGPARM_MAX;
+
+ bnd_reg = cum->bnd_regno + cum->force_bnd_pass;
+ if (chkp_function_instrumented_p (current_function_decl))
+ for (i = cum->regno; i < max; i++)
+ {
+ rtx addr = plus_constant (Pmode, save_area, i * UNITS_PER_WORD);
+ rtx reg = gen_rtx_REG (DImode,
+ x86_64_int_parameter_registers[i]);
+ rtx ptr = reg;
+ rtx bounds;
+
+ if (bnd_reg <= LAST_BND_REG)
+ bounds = gen_rtx_REG (BNDmode, bnd_reg);
+ else
+ {
+ rtx ldx_addr =
+ plus_constant (Pmode, arg_pointer_rtx,
+ (LAST_BND_REG - bnd_reg) * GET_MODE_SIZE (Pmode));
+ bounds = gen_reg_rtx (BNDmode);
+ emit_insn (BNDmode == BND64mode
+ ? gen_bnd64_ldx (bounds, ldx_addr, ptr)
+ : gen_bnd32_ldx (bounds, ldx_addr, ptr));
+ }
+
+ emit_insn (BNDmode == BND64mode
+ ? gen_bnd64_stx (addr, ptr, bounds)
+ : gen_bnd32_stx (addr, ptr, bounds));
+
+ bnd_reg++;
+ }
+}
+
+
/* Checks if TYPE is of kind va_list char *. */
static bool
@@ -8550,6 +8615,13 @@ ix86_va_start (tree valist, rtx nextarg)
crtl->args.arg_offset_rtx,
NULL_RTX, 0, OPTAB_LIB_WIDEN);
convert_move (va_r, next, 0);
+
+ /* Store zero bounds for va_list. */
+ if (chkp_function_instrumented_p (current_function_decl))
+ chkp_expand_bounds_reset_for_mem (valist,
+ make_tree (TREE_TYPE (valist),
+ next));
+
}
return;
}
@@ -8603,6 +8675,11 @@ ix86_va_start (tree valist, rtx nextarg)
t = make_tree (type, ovf_rtx);
if (words != 0)
t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
+
+ /* Store zero bounds for overflow area pointer. */
+ if (chkp_function_instrumented_p (current_function_decl))
+ chkp_expand_bounds_reset_for_mem (ovf, t);
+
t = build2 (MODIFY_EXPR, type, ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -8615,6 +8692,11 @@ ix86_va_start (tree valist, rtx nextarg)
t = make_tree (type, frame_pointer_rtx);
if (!ix86_varargs_gpr_size)
t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
+
+ /* Store zero bounds for save area pointer. */
+ if (chkp_function_instrumented_p (current_function_decl))
+ chkp_expand_bounds_reset_for_mem (sav, t);
+
t = build2 (MODIFY_EXPR, type, sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -48313,6 +48395,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts)
#undef TARGET_CHKP_INITIALIZE_BOUNDS
#define TARGET_CHKP_INITIALIZE_BOUNDS ix86_initialize_bounds
+#undef TARGET_SETUP_INCOMING_VARARG_BOUNDS
+#define TARGET_SETUP_INCOMING_VARARG_BOUNDS ix86_setup_incoming_vararg_bounds
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"