#include <stdio.h>
#include <limits.h> /* For CHAR_BIT. */
-
-#ifdef ENABLE_CHECKING
-#include <signal.h> /* For SIGABRT. */
-#endif
+#include <signal.h> /* For SIGABRT, SIGDANGER. */
#ifdef HAVE_PTHREAD
#include <pthread.h>
#include "dispextern.h"
#include "intervals.h"
#include "puresize.h"
+#include "sheap.h"
#include "systime.h"
#include "character.h"
#include "buffer.h"
#include "dosfns.h" /* For dos_memory_info. */
#endif
+#ifdef HAVE_MALLOC_H
+# include <malloc.h>
+#endif
+
#if (defined ENABLE_CHECKING \
&& defined HAVE_VALGRIND_VALGRIND_H \
&& !defined USE_VALGRIND)
#include "w32heap.h" /* for sbrk */
#endif
-#ifdef DOUG_LEA_MALLOC
+#if defined DOUG_LEA_MALLOC || defined GNU_LINUX
+/* The address where the heap starts. */
+void *
+my_heap_start (void)
+{
+ static void *start;
+ if (! start)
+ start = sbrk (0);
+ return start;
+}
+#endif
-#include <malloc.h>
+#ifdef DOUG_LEA_MALLOC
/* Specify maximum number of areas to mmap. It would be nice to use a
value that explicitly means "no limit". */
#define MMAP_MAX_AREAS 100000000
-#endif /* not DOUG_LEA_MALLOC */
+/* A pointer to the memory allocated that copies that static data
+ inside glibc's malloc. */
+static void *malloc_state_ptr;
+
+/* Restore the dumped malloc state. Because malloc can be invoked
+ even before main (e.g. by the dynamic linker), the dumped malloc
+ state must be restored as early as possible using this special hook. */
+static void
+malloc_initialize_hook (void)
+{
+ static bool malloc_using_checking;
+
+ if (! initialized)
+ {
+ my_heap_start ();
+ malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
+ }
+ else
+ {
+ if (!malloc_using_checking)
+ {
+ /* Work around a bug in glibc's malloc. MALLOC_CHECK_ must be
+ ignored if the heap to be restored was constructed without
+ malloc checking. Can't use unsetenv, since that calls malloc. */
+ char **p = environ;
+ if (p)
+ for (; *p; p++)
+ if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
+ {
+ do
+ *p = p[1];
+ while (*++p);
+
+ break;
+ }
+ }
+
+ malloc_set_state (malloc_state_ptr);
+# ifndef XMALLOC_OVERRUN_CHECK
+ alloc_unexec_post ();
+# endif
+ }
+}
+
+/* Declare the malloc initialization hook, which runs before 'main' starts.
+ EXTERNALLY_VISIBLE works around Bug#22522. */
+# ifndef __MALLOC_HOOK_VOLATILE
+# define __MALLOC_HOOK_VOLATILE
+# endif
+voidfuncptr __MALLOC_HOOK_VOLATILE __malloc_initialize_hook EXTERNALLY_VISIBLE
+ = malloc_initialize_hook;
+
+#endif
+
+/* Allocator-related actions to do just before and after unexec. */
+
+void
+alloc_unexec_pre (void)
+{
+#ifdef DOUG_LEA_MALLOC
+ malloc_state_ptr = malloc_get_state ();
+#endif
+#ifdef HYBRID_MALLOC
+ bss_sbrk_did_unexec = true;
+#endif
+}
+
+void
+alloc_unexec_post (void)
+{
+#ifdef DOUG_LEA_MALLOC
+ free (malloc_state_ptr);
+#endif
+#ifdef HYBRID_MALLOC
+ bss_sbrk_did_unexec = false;
+#endif
+}
/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
to a struct Lisp_String. */
Malloc
************************************************************************/
+#if defined SIGDANGER || (!defined SYSTEM_MALLOC && !defined HYBRID_MALLOC)
+
/* Function malloc calls this if it finds we are near exhausting storage. */
void
pending_malloc_warning = str;
}
+#endif
/* Display an already-pending malloc warning. */
/* 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 && !defined HYBRID_MALLOC
-# define USE_ALIGNED_ALLOC 1
-/* Defined in gmalloc.c. */
-void *aligned_alloc (size_t, size_t);
-# elif defined HYBRID_MALLOC
-# if defined ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
-# define USE_ALIGNED_ALLOC 1
-# define aligned_alloc hybrid_aligned_alloc
-/* Defined in gmalloc.c. */
-void *aligned_alloc (size_t, size_t);
-# endif
-# elif defined HAVE_ALIGNED_ALLOC
+ clang 3.3 anyway. Aligned allocation is incompatible with
+ unexmacosx.c, so don't use it on Darwin. */
+
+#if ! ADDRESS_SANITIZER && !defined DARWIN_OS
+# if (defined HAVE_ALIGNED_ALLOC \
+ || (defined HYBRID_MALLOC \
+ ? defined HAVE_POSIX_MEMALIGN \
+ : !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC))
# define USE_ALIGNED_ALLOC 1
-# elif defined HAVE_POSIX_MEMALIGN
+# elif !defined HYBRID_MALLOC && defined HAVE_POSIX_MEMALIGN
# define USE_ALIGNED_ALLOC 1
static void *
aligned_alloc (size_t alignment, size_t size)