+2013-12-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix core dumps with gcc -fsanitize=address and GNU/Linux.
+ * configure.ac: Check whether addresses are sanitized.
+ (CANNOT_DUMP): Warn if addresses are sanitized and not CANNOT_DUMP.
+ (DOUG_LEA_MALLOC): Do not define if addresses are sanitized.
+ (SYSTEM_MALLOC): Define if addresses are sanitized.
+
2013-12-24 Paul Eggert <eggert@cs.ucla.edu>
Automate the procedure for updating copyright year.
LDFLAGS="$late_LDFLAGS"
+AC_CACHE_CHECK([whether addresses are sanitized],
+ [emacs_cv_sanitize_address],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#ifndef __has_feature
+ #define __has_feature(f) 0
+ #endif
+ #if defined __SANITIZE_ADDRESS__ || __has_feature (address_sanitizer)
+ #else
+ #error "Addresses are not sanitized."
+ #endif
+ ]])],
+ [emacs_cv_sanitize_address=yes],
+ [emacs_cv_sanitize_address=no])])
+
dnl The function dump-emacs will not be defined and temacs will do
dnl (load "loadup") automatically unless told otherwise.
test "x$CANNOT_DUMP" = "x" && CANNOT_DUMP=no
your-opsys-here) CANNOT_DUMP=yes ;;
esac
-test "$CANNOT_DUMP" = "yes" && \
+if test "$CANNOT_DUMP" = "yes"; then
AC_DEFINE(CANNOT_DUMP, 1, [Define if Emacs cannot be dumped on your system.])
+elif test "$emacs_cv_sanitize_address" = yes; then
+ AC_MSG_WARN([[Addresses are sanitized; suggest CANNOT_DUMP=yes]])
+fi
AC_SUBST(CANNOT_DUMP)
AC_CACHE_CHECK(
[whether malloc is Doug Lea style],
[emacs_cv_var_doug_lea_malloc],
- [AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <malloc.h>
- static void hook (void) {}]],
- [[malloc_set_state (malloc_get_state ());
- __after_morecore_hook = hook;
- __malloc_initialize_hook = hook;]])],
- [emacs_cv_var_doug_lea_malloc=yes],
- [emacs_cv_var_doug_lea_malloc=no])])
+ [emacs_cv_var_doug_lea_malloc=no
+ dnl Hooks do not work with address sanitization.
+ if test "$emacs_cv_sanitize_address" != yes; then
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <malloc.h>
+ static void hook (void) {}]],
+ [[malloc_set_state (malloc_get_state ());
+ __after_morecore_hook = hook;
+ __malloc_initialize_hook = hook;]])],
+ [emacs_cv_var_doug_lea_malloc=yes])])
+ fi
doug_lea_malloc=$emacs_cv_var_doug_lea_malloc
-
-dnl See comments in aix4-2.h about maybe using system malloc there.
-system_malloc=no
+system_malloc=$emacs_cv_sanitize_address
case "$opsys" in
## darwin ld insists on the use of malloc routines in the System framework.
darwin|sol2-10) system_malloc=yes ;;
+2013-12-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix core dumps with gcc -fsanitize=address and GNU/Linux.
+ On my Fedora 19 platform the core dumps were so big that
+ my desktop became nearly catatonic.
+ * alloc.c (no_sanitize_memcpy) [MAX_SAVE_STACK > 0]: New function.
+ (Fgarbage_collect) [MAX_SAVE_STACK > 0]: Use it.
+ (USE_ALIGNED_MALLOC): Do not define if addresses are sanitized.
+ (mark_memory): Use ATTRIBUTE_NO_SANITIZE_ADDRESS rather than
+ a clang-only syntax.
+ * conf_post.h (__has_feature): New macro, if not already defined.
+ (ADDRESS_SANITIZER, ADDRESS_SANITIZER_WORKAROUND)
+ (ATTRIBUTE_NO_SANITIZE_ADDRESS): New macros.
+
2013-12-25 Eli Zaretskii <eliz@gnu.org>
* w32fns.c (Fw32_shell_execute): Make DOCUMENT absolute only if it
#if MAX_SAVE_STACK > 0
static char *stack_copy;
static ptrdiff_t stack_copy_size;
-#endif
+
+/* Copy to DEST a block of memory from SRC of size SIZE bytes,
+ avoiding any address sanitization. */
+
+static void * ATTRIBUTE_NO_SANITIZE_ADDRESS
+no_sanitize_memcpy (void *dest, void const *src, size_t size)
+{
+ if (! ADDRESS_SANITIZER)
+ return memcpy (dest, src, size);
+ else
+ {
+ size_t i;
+ char *d = dest;
+ char const *s = src;
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+ return dest;
+ }
+}
+
+#endif /* MAX_SAVE_STACK > 0 */
static Lisp_Object Qconses;
static Lisp_Object Qsymbols;
/* The entry point is lisp_align_malloc which returns blocks of at most
BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
-#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
-# define USE_ALIGNED_ALLOC 1
+/* Use aligned_alloc if it or a simple substitute is available.
+ Address sanitization breaks aligned allocation, as of gcc 4.8.2 and
+ clang 3.3 anyway. */
+
+#if ! ADDRESS_SANITIZER
+# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
+# define USE_ALIGNED_ALLOC 1
/* Defined in gmalloc.c. */
void *aligned_alloc (size_t, size_t);
-#elif defined HAVE_ALIGNED_ALLOC
-# define USE_ALIGNED_ALLOC 1
-#elif defined HAVE_POSIX_MEMALIGN
-# define USE_ALIGNED_ALLOC 1
+# elif defined HAVE_ALIGNED_ALLOC
+# define USE_ALIGNED_ALLOC 1
+# elif defined HAVE_POSIX_MEMALIGN
+# define USE_ALIGNED_ALLOC 1
static void *
aligned_alloc (size_t alignment, size_t size)
{
void *p;
return posix_memalign (&p, alignment, size) == 0 ? p : 0;
}
+# endif
#endif
/* BLOCK_ALIGN has to be a power of 2. */
/* Mark Lisp objects referenced from the address range START+OFFSET..END
or END+OFFSET..START. */
-static void
+static void ATTRIBUTE_NO_SANITIZE_ADDRESS
mark_memory (void *start, void *end)
-#if defined (__clang__) && defined (__has_feature)
-#if __has_feature(address_sanitizer)
- /* Do not allow -faddress-sanitizer to check this function, since it
- crosses the function stack boundary, and thus would yield many
- false positives. */
- __attribute__((no_address_safety_analysis))
-#endif
-#endif
{
void **pp;
int i;
stack_copy = xrealloc (stack_copy, stack_size);
stack_copy_size = stack_size;
}
- memcpy (stack_copy, stack, stack_size);
+ no_sanitize_memcpy (stack_copy, stack, stack_size);
}
}
#endif /* MAX_SAVE_STACK > 0 */
#endif
#endif
+/* When not using Clang, assume its attributes and features are absent. */
#ifndef __has_attribute
-# define __has_attribute(a) false /* non-clang */
+# define __has_attribute(a) false
+#endif
+#ifndef __has_feature
+# define __has_feature(a) false
+#endif
+
+/* True if addresses are being sanitized. */
+#if defined __SANITIZE_ADDRESS__ || __has_feature (address_sanitizer)
+# define ADDRESS_SANITIZER true
+#else
+# define ADDRESS_SANITIZER false
#endif
#ifdef DARWIN_OS
#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
+/* Work around GCC bug 59600: when a function is inlined, the inlined
+ code may have its addresses sanitized even if the function has the
+ no_sanitize_address attribute. This bug is present in GCC 4.8.2
+ and clang 3.3, the latest releases as of December 2013, and the
+ only platforms known to support address sanitization. When the bug
+ is fixed the #if can be updated accordingly. */
+#if ADDRESS_SANITIZER
+# define ADDRESS_SANITIZER_WORKAROUND NO_INLINE
+#else
+# define ADDRESS_SANITIZER_WORKAROUND
+#endif
+
+/* Attribute of functions whose code should not have addresses
+ sanitized. */
+
+#if (__has_attribute (no_sanitize_address) \
+ || 4 < __GNUC__ + (8 <= __GNUC_MINOR__))
+# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
+ __attribute__ ((no_sanitize_address)) ADDRESS_SANITIZER_WORKAROUND
+#elif __has_attribute (no_address_safety_analysis)
+# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
+ __attribute__ ((no_address_safety_analysis)) ADDRESS_SANITIZER_WORKAROUND
+#else
+# define ATTRIBUTE_NO_SANITIZE_ADDRESS
+#endif
+
/* Some versions of GNU/Linux define noinline in their headers. */
#ifdef noinline
#undef noinline