On Tue, Jul 8, 2014 at 5:16 PM, Alexey Preobrazhensky <[email protected]> wrote: > > > On Friday, June 20, 2014 6:26:37 PM UTC+4, Yuri Gribov wrote: >> >> On Fri, Jun 20, 2014 at 4:50 PM, Andrey Ryabinin <[email protected]> >> wrote: >> > --param asan-memintrin=0 --param asan-fixed-shadow-offset=0 >> >> This wasn't yet upstreamed. > > > Can you share remaining patches with us?
Sure, attached. The patch is somewhat ugly: asan-fixed-shadow-offset is only supported for stack prologues/epilogues (memory accesses still use constant shadow offset) because I only needed to make it work for Kasan. I can further improve this patch (and probably upstream it) if people find it useful. -Y -- You received this message because you are subscribed to the Google Groups "address-sanitizer" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
commit 220af201fe980065f5ee6f74a46380b93744c68f Author: Yury Gribov <[email protected]> Date: Tue Jun 3 12:11:15 2014 +0400 2014-05-27 Yury Gribov <[email protected]> gcc/ChangeLog: * asan.c (asan_emit_stack_protection): Support non-fixed shadow offset. * params.def (PARAM_ASAN_FIXED_SHADOW_OFFSET): New parameter. * params.h: Likewise. libsanitizer/ChangeLog: * asan/asan_rtl.cc (__asan_get_shadow_ptr): New function. diff --git a/gcc/asan.c b/gcc/asan.c index 667a662..0b897d9 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -952,6 +952,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, HOST_WIDE_INT *offsets, tree *decls, int length) { rtx shadow_base, shadow_mem, ret, mem, orig_base, lab; + rtx shadow_start, shadow_start_lab = NULL_RTX, shadow_start_lab2 = NULL_RTX; char buf[30]; unsigned char shadow_bytes[4]; HOST_WIDE_INT base_offset = offsets[length - 1]; @@ -1047,7 +1048,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, use_after_return_class); ret = init_one_libfunc (buf); rtx addr = convert_memory_address (ptr_mode, base); - ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 2, + ret = emit_library_call_value (ret, NULL_RTX, LCT_PURE, ptr_mode, 2, GEN_INT (asan_frame_size + base_align_bias), TYPE_MODE (pointer_sized_int_node), @@ -1085,10 +1086,27 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, 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); + shadow_start_lab = gen_label_rtx (); + int very_unlikely = REG_BR_PROB_BASE / 100 - 1; + emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, + VOIDmode, 0, shadow_start_lab, 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); @@ -1137,6 +1155,8 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE; } do_pending_stack_adjust (); + if (shadow_start_lab != NULL_RTX) + emit_label (shadow_start_lab); /* Construct epilogue sequence. */ start_sequence (); @@ -1182,6 +1202,16 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, emit_label (lab2); } + if (!ASAN_FIXED_SHADOW_OFFSET) + { +// ret = init_one_libfunc ("__asan_get_shadow_ptr"); +// shadow_start = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 0); + shadow_start_lab2 = gen_label_rtx (); + int very_unlikely = REG_BR_PROB_BASE / 100 - 1; + emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, + VOIDmode, 0, shadow_start_lab2, very_unlikely); + } + shadow_mem = gen_rtx_MEM (BLKmode, shadow_base); set_mem_alias_set (shadow_mem, asan_shadow_set); @@ -1218,6 +1248,8 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, } do_pending_stack_adjust (); + if (shadow_start_lab2 != NULL_RTX) + emit_label (shadow_start_lab2); if (lab) emit_label (lab); diff --git a/gcc/params.def b/gcc/params.def index 24b42f9..570b3d5 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -1055,6 +1055,11 @@ DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, " 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 " diff --git a/gcc/params.h b/gcc/params.h index 0470c1a..5de8838 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -232,5 +232,7 @@ extern void init_param_values (int *params); 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 */ diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc index d202415..fe5f08b 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cc @@ -275,6 +275,11 @@ void __asan_report_ ## type ## _n(uptr addr, uptr size) { \ ASAN_REPORT_ERROR_N(load, false) ASAN_REPORT_ERROR_N(store, true) +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
