@@ -1543,6 +1543,13 @@ process_options (void)
flag_omit_frame_pointer = 0;
}
+ /* Address Sanitizer needs porting to each target architecture. */
+ if (flag_asan && targetm.asan_shadow_offset == NULL)
+ {
+ warning (0, "-fasan not supported for this target");
+ flag_asan = 0;
+ }
+
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
have not been set. */
if (!global_options_set.x_warnings_are_errors
@@ -1,5 +1,5 @@
/* AddressSanitizer, a fast memory error detector.
- Copyright (C) 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011, 2012 Free Software Foundation, Inc.
Contributed by Kostya Serebryany <kcc@google.com>
This file is part of GCC.
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.
#include "gimple.h"
#include "asan.h"
#include "gimple-pretty-print.h"
+#include "target.h"
/*
AddressSanitizer finds out-of-bounds and use-after-free bugs
@@ -78,15 +79,6 @@ along with GCC; see the file COPYING3.
to create redzones for stack and global object and poison them.
*/
-/* The shadow address is computed as (X>>asan_scale) + (1<<asan_offset_log).
- We may want to add command line flags to change these values. */
-
-static const int asan_scale = 3;
-static const int asan_offset_log_32 = 29;
-static const int asan_offset_log_64 = 44;
-static int asan_offset_log;
-
-
/* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16}.
IS_STORE is either 1 (for a store) or 0 (for a load).
SIZE_IN_BYTES is one of 1, 2, 4, 8, 16. */
@@ -202,15 +194,13 @@ build_check_stmt (tree base,
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
- /* Build (base_addr >> asan_scale) + (1 << asan_offset_log). */
+ /* Build
+ (base_addr >> ASAN_SHADOW_SHIFT) | targetm.asan_shadow_offset (). */
t = build2 (RSHIFT_EXPR, uintptr_type, base_addr,
- build_int_cst (uintptr_type, asan_scale));
+ build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT));
t = build2 (PLUS_EXPR, uintptr_type, t,
- build2 (LSHIFT_EXPR, uintptr_type,
- build_int_cst (uintptr_type, 1),
- build_int_cst (uintptr_type, asan_offset_log)
- ));
+ build_int_cst (uintptr_type, targetm.asan_shadow_offset ()));
t = build1 (INDIRECT_REF, shadow_type,
build1 (VIEW_CONVERT_EXPR, shadow_ptr_type, t));
t = force_gimple_operand (t, &stmts, false, NULL_TREE);
@@ -367,9 +357,6 @@ static unsigned int
asan_instrument (void)
{
struct gimplify_ctx gctx;
- tree uintptr_type = lang_hooks.types.type_for_mode (ptr_mode, true);
- int is_64 = tree_low_cst (TYPE_SIZE (uintptr_type), 0) == 64;
- asan_offset_log = is_64 ? asan_offset_log_64 : asan_offset_log_32;
push_gimplify_context (&gctx);
transform_statements ();
pop_gimplify_context (NULL);
@@ -1,5 +1,5 @@
/* AddressSanitizer, a fast memory error detector.
- Copyright (C) 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011, 2012 Free Software Foundation, Inc.
Contributed by Kostya Serebryany <kcc@google.com>
This file is part of GCC.
@@ -23,4 +23,8 @@ along with GCC; see the file COPYING3.
extern void asan_finish_file(void);
+/* Shadow memory is found at
+ (address >> ASAN_SHADOW_SHIFT) | targetm.asan_shadow_offset (). */
+#define ASAN_SHADOW_SHIFT 3
+
#endif /* TREE_ASAN */
@@ -2025,6 +2025,17 @@ DEFHOOK
"",
unsigned HOST_WIDE_INT, (unsigned HOST_WIDE_INT val), NULL)
+/* Defines an offset bitwise ored into shifted address to get corresponding
+ Address Sanitizer shadow address, or -1 if Address Sanitizer is not
+ supported by the target. */
+DEFHOOK
+(asan_shadow_offset,
+ "Return the offset bitwise ored into shifted address to get corresponding\n\
+Address Sanitizer shadow memory address. NULL if Address Sanitizer is not\n\
+supported by the target.",
+ unsigned HOST_WIDE_INT, (void),
+ NULL)
+
/* Functions relating to calls - argument passing, returns, etc. */
/* Members of struct call have no special macro prefix. */
HOOK_VECTOR (TARGET_CALLS, calls)
@@ -11303,6 +11303,12 @@ MIPS, where add-immediate takes a 16-bit
@code{TARGET_CONST_ANCHOR} is set to @samp{0x8000}. The default value
is zero, which disables this optimization. @end deftypevr
+@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_ASAN_SHADOW_OFFSET (void)
+Return the offset bitwise ored into shifted address to get corresponding
+Address Sanitizer shadow memory address. NULL if Address Sanitizer is not
+supported by the target.
+@end deftypefn
+
@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_CHECK (unsigned HOST_WIDE_INT @var{val})
Validate target specific memory model mask bits. When NULL no target specific
memory model bits are allowed.
@@ -11157,6 +11157,8 @@ MIPS, where add-immediate takes a 16-bit
@code{TARGET_CONST_ANCHOR} is set to @samp{0x8000}. The default value
is zero, which disables this optimization. @end deftypevr
+@hook TARGET_ASAN_SHADOW_OFFSET
+
@hook TARGET_MEMMODEL_CHECK
Validate target specific memory model mask bits. When NULL no target specific
memory model bits are allowed.
@@ -2204,7 +2204,7 @@ stor-layout.o : stor-layout.c $(CONFIG_H
asan.o : asan.c asan.h $(CONFIG_H) pointer-set.h \
$(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
output.h $(DIAGNOSTIC_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H) \
- tree-pretty-print.h
+ tree-pretty-print.h $(TARGET_H)
tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
@@ -5619,6 +5619,14 @@ ix86_legitimate_combined_insn (rtx insn)
return true;
}
+/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
+
+static unsigned HOST_WIDE_INT
+ix86_asan_shadow_offset (void)
+{
+ return (unsigned HOST_WIDE_INT) 1 << (Pmode == DImode ? 44 : 29);
+}
+
/* Argument support functions. */
/* Return true when register may be used to pass function parameters. */
@@ -41074,6 +41082,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_
#undef TARGET_LEGITIMATE_COMBINED_INSN
#define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
+#undef TARGET_ASAN_SHADOW_OFFSET
+#define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
+
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg