===================================================================
@@ -979,6 +979,8 @@
HOST_WIDE_INT *offsets, tree *decls, int length)
{
rtx shadow_base, shadow_mem, ret, mem, orig_base, lab;
+ rtx shadow_start = NULL_RTX;
+ rtx skip_prologue_lab = NULL_RTX, skip_epilogue_lab = NULL_RTX;
char buf[30];
unsigned char shadow_bytes[4];
HOST_WIDE_INT base_offset = offsets[length - 1];
@@ -1112,10 +1114,26 @@
shadow_base = expand_binop (Pmode, lshr_optab, base,
GEN_INT (ASAN_SHADOW_SHIFT),
NULL_RTX, 1, OPTAB_DIRECT);
- shadow_base
- = plus_constant (Pmode, shadow_base,
- targetm.asan_shadow_offset ()
- + (base_align_bias >> ASAN_SHADOW_SHIFT));
+ if (ASAN_FIXED_SHADOW_OFFSET)
+ {
+ shadow_base
+ = plus_constant (Pmode, shadow_base,
+ targetm.asan_shadow_offset ()
+ + (base_align_bias >> ASAN_SHADOW_SHIFT));
+ }
+ else
+ {
+ ret = init_one_libfunc ("__asan_get_shadow_ptr");
+ shadow_start = gen_reg_rtx (ptr_mode);
+ emit_library_call_value (ret, shadow_start, LCT_NORMAL, ptr_mode, 0);
+ skip_prologue_lab = gen_label_rtx ();
+ emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, VOIDmode,
+ 0, skip_prologue_lab, PROB_VERY_UNLIKELY);
+ shadow_base = expand_binop (Pmode, add_optab, shadow_base, shadow_start,
+ NULL_RTX, 1, OPTAB_DIRECT);
+ shadow_base = plus_constant (Pmode, shadow_base,
+ base_align_bias >> ASAN_SHADOW_SHIFT);
+ }
gcc_assert (asan_shadow_set != -1
&& (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
shadow_mem = gen_rtx_MEM (SImode, shadow_base);
@@ -1165,17 +1183,19 @@
}
do_pending_stack_adjust ();
+ if (skip_prologue_lab)
+ emit_label (skip_prologue_lab);
+
/* Construct epilogue sequence. */
start_sequence ();
- lab = NULL_RTX;
if (use_after_return_class != -1)
{
- rtx lab2 = gen_label_rtx ();
char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
int very_likely = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+ lab = gen_label_rtx ();
emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
- VOIDmode, 0, lab2, very_likely);
+ VOIDmode, 0, lab, very_likely);
shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
set_mem_alias_set (shadow_mem, asan_shadow_set);
mem = gen_rtx_MEM (ptr_mode, base);
@@ -1204,11 +1224,19 @@
TYPE_MODE (pointer_sized_int_node),
orig_addr, ptr_mode);
}
- lab = gen_label_rtx ();
- emit_jump (lab);
- emit_label (lab2);
+ skip_epilogue_lab = gen_label_rtx ();
+ emit_jump (skip_epilogue_lab);
+ emit_label (lab);
}
+ if (!ASAN_FIXED_SHADOW_OFFSET)
+ {
+ if (!skip_epilogue_lab)
+ skip_epilogue_lab = gen_label_rtx ();
+ emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, VOIDmode,
+ 0, skip_epilogue_lab, PROB_VERY_UNLIKELY);
+ }
+
shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
set_mem_alias_set (shadow_mem, asan_shadow_set);
@@ -1245,9 +1273,10 @@
}
do_pending_stack_adjust ();
- if (lab)
- emit_label (lab);
+ if (skip_epilogue_lab)
+ emit_label (skip_epilogue_lab);
+
ret = get_insns ();
end_sequence ();
return ret;
===================================================================
@@ -1081,6 +1081,11 @@
" in function becomes greater or equal than this threshold",
10000, 0, INT_MAX)
+DEFPARAM (PARAM_ASAN_FIXED_SHADOW_OFFSET,
+ "asan-fixed-shadow-offset",
+ "Use fixed offset of shadow memory region",
+ 1, 0, 1)
+
DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
"uninit-control-dep-attempts",
"Maximum number of nested calls to search for control dependencies "
===================================================================
@@ -234,5 +234,7 @@
PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
#define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \
PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
+#define ASAN_FIXED_SHADOW_OFFSET \
+ PARAM_VALUE (PARAM_ASAN_FIXED_SHADOW_OFFSET)
#endif /* ! GCC_PARAMS_H */
===================================================================
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-fixed-shadow-offset=0 -save-temps" } */
+
+extern void f(char *);
+
+int main() {
+ char buf[64];
+ f(buf);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "__asan_get_shadow_ptr" } } */
+/* { dg-final { cleanup-saved-temps } } */
===================================================================
@@ -430,6 +430,11 @@
}
}
+extern "C"
+NOINLINE INTERFACE_ATTRIBUTE uptr __asan_get_shadow_ptr() {
+ return (uptr)SHADOW_OFFSET;
+}
+
// Force the linker to keep the symbols for various ASan interface functions.
// We want to keep those in the executable in order to let the instrumented
// dynamic libraries access the symbol even if it is not used by the executable