From: David Miller <da...@davemloft.net>
Date: Tue, 20 Nov 2012 21:20:40 -0500 (EST)

> Those seem to be the only problems that need to be resolved for this
> feature to be fully working.

FWIW, here are the changes I am using which, besides the sparc backend
bits, has some temporary workarounds for the issues I brought up.

The address violation detection seems to work properly and the only
thing that seems to be left are some backtrace/unwind issues.  These
are perhaps similar to the unwind bits that the powerpc folks ran
into.

diff --git a/gcc/asan.c b/gcc/asan.c
index bd90e0a..d9b3f1b 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -321,7 +321,10 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT 
*offsets, tree *decls,
                              NULL_RTX, 1, OPTAB_DIRECT);
   gcc_assert (asan_shadow_set != -1
              && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
-  shadow_mem = gen_rtx_MEM (SImode, shadow_base);
+  if (STRICT_ALIGNMENT)
+    shadow_mem = gen_rtx_MEM (QImode, shadow_base);
+  else
+    shadow_mem = gen_rtx_MEM (SImode, shadow_base);
   set_mem_alias_set (shadow_mem, asan_shadow_set);
   prev_offset = base_offset;
   for (l = length; l; l -= 2)
@@ -349,7 +352,20 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT 
*offsets, tree *decls,
              }
            else
              shadow_bytes[i] = ASAN_STACK_MAGIC_PARTIAL;
-         emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
+         if (STRICT_ALIGNMENT)
+           {
+             for (i = 0; i < 4; i++)
+               {
+                 rtx mem = adjust_address (shadow_mem, VOIDmode, i);
+                 rtx val;
+
+                 val = GEN_INT (trunc_int_for_mode (shadow_bytes[i],
+                                                    QImode));
+                 emit_move_insn (mem, val);
+               }
+           }
+         else
+           emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
          offset = aoff;
        }
       while (offset <= offsets[l - 2] - ASAN_RED_ZONE_SIZE)
@@ -359,7 +375,22 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT 
*offsets, tree *decls,
                                       >> ASAN_SHADOW_SHIFT);
          prev_offset = offset;
          memset (shadow_bytes, cur_shadow_byte, 4);
-         emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
+         if (STRICT_ALIGNMENT)
+           {
+             int i;
+
+             for (i = 0; i < 4; i++)
+               {
+                 rtx mem = adjust_address (shadow_mem, VOIDmode, i);
+                 rtx val;
+
+                 val = GEN_INT (trunc_int_for_mode (shadow_bytes[i],
+                                                    QImode));
+                 emit_move_insn (mem, val);
+               }
+           }
+         else
+           emit_move_insn (shadow_mem, asan_shadow_cst (shadow_bytes));
          offset += ASAN_RED_ZONE_SIZE;
        }
       cur_shadow_byte = ASAN_STACK_MAGIC_MIDDLE;
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 4e9de98..7bcc815 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -600,6 +600,7 @@ static void sparc_print_operand_address (FILE *, rtx);
 static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
                                           enum machine_mode,
                                           secondary_reload_info *);
+static unsigned HOST_WIDE_INT sparc_asan_shadow_offset (void);
 
 #ifdef SUBTARGET_ATTRIBUTE_TABLE
 /* Table of valid machine attributes.  */
@@ -754,6 +755,9 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE sparc_option_override
 
+#undef TARGET_ASAN_SHADOW_OFFSET
+#define TARGET_ASAN_SHADOW_OFFSET sparc_asan_shadow_offset
+
 #if TARGET_GNU_TLS && defined(HAVE_AS_SPARC_UA_PCREL)
 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
 #define TARGET_ASM_OUTPUT_DWARF_DTPREL sparc_output_dwarf_dtprel
@@ -11034,6 +11038,14 @@ get_some_local_dynamic_name_1 (rtx *px, void *data 
ATTRIBUTE_UNUSED)
   return 0;
 }
 
+/* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
+
+static unsigned HOST_WIDE_INT
+sparc_asan_shadow_offset (void)
+{
+  return (unsigned HOST_WIDE_INT) 1 << (TARGET_ARCH64 ? 44 : 29);
+}
+
 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
    We need to emit DTP-relative relocations.  */
 
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h 
b/libsanitizer/sanitizer_common/sanitizer_common.h
index cddefd7..00628fc 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -21,7 +21,7 @@ namespace __sanitizer {
 // Constants.
 const uptr kWordSize = __WORDSIZE / 8;
 const uptr kWordSizeInBits = 8 * kWordSize;
-const uptr kPageSizeBits = 12;
+const uptr kPageSizeBits = 13;
 const uptr kPageSize = 1UL << kPageSizeBits;
 const uptr kCacheLineSize = 64;
 #ifndef _WIN32

Reply via email to