-#ifndef XMALLOC_OVERRUN_CHECK
-#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
-#else
-
-/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
- around each block.
-
- The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes
- followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original
- block size in little-endian order. The trailer consists of
- XMALLOC_OVERRUN_CHECK_SIZE fixed bytes.
-
- The header is used to detect whether this block has been allocated
- through these functions, as some low-level libc functions may
- bypass the malloc hooks. */
-
-#define XMALLOC_OVERRUN_CHECK_SIZE 16
-#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
- (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE)
-
-/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to
- hold a size_t value and (2) the header size is a multiple of the
- alignment that Emacs needs for C types and for USE_LSB_TAG. */
-#define XMALLOC_BASE_ALIGNMENT \
- alignof (union { long double d; intmax_t i; void *p; })
-
-#if USE_LSB_TAG
-# define XMALLOC_HEADER_ALIGNMENT \
- COMMON_MULTIPLE (GCALIGNMENT, XMALLOC_BASE_ALIGNMENT)
-#else
-# define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT
-#endif
-#define XMALLOC_OVERRUN_SIZE_SIZE \
- (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \
- + XMALLOC_HEADER_ALIGNMENT - 1) \
- / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \
- - XMALLOC_OVERRUN_CHECK_SIZE)
-
-static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
- { '\x9a', '\x9b', '\xae', '\xaf',
- '\xbf', '\xbe', '\xce', '\xcf',
- '\xea', '\xeb', '\xec', '\xed',
- '\xdf', '\xde', '\x9c', '\x9d' };
-
-static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
- { '\xaa', '\xab', '\xac', '\xad',
- '\xba', '\xbb', '\xbc', '\xbd',
- '\xca', '\xcb', '\xcc', '\xcd',
- '\xda', '\xdb', '\xdc', '\xdd' };
-
-/* Insert and extract the block size in the header. */
-
-static void
-xmalloc_put_size (unsigned char *ptr, size_t size)
-{
- int i;
- for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
- {
- *--ptr = size & ((1 << CHAR_BIT) - 1);
- size >>= CHAR_BIT;
- }
-}
-
-static size_t
-xmalloc_get_size (unsigned char *ptr)
-{
- size_t size = 0;
- int i;
- ptr -= XMALLOC_OVERRUN_SIZE_SIZE;
- for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
- {
- size <<= CHAR_BIT;
- size += *ptr++;
- }
- return size;
-}
-
-
-/* Like malloc, but wraps allocated block with header and trailer. */
-
-static void *
-overrun_check_malloc (size_t size)
-{
- register unsigned char *val;
- if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
- emacs_abort ();
-
- val = malloc (size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
- if (val)
- {
- memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
- val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
- xmalloc_put_size (val, size);
- memcpy (val + size, xmalloc_overrun_check_trailer,
- XMALLOC_OVERRUN_CHECK_SIZE);
- }
- return val;
-}
-
-
-/* Like realloc, but checks old block for overrun, and wraps new block
- with header and trailer. */
-
-static void *
-overrun_check_realloc (void *block, size_t size)
-{
- register unsigned char *val = (unsigned char *) block;
- if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
- emacs_abort ();
-
- if (val
- && memcmp (xmalloc_overrun_check_header,
- val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
- XMALLOC_OVERRUN_CHECK_SIZE) == 0)
- {
- size_t osize = xmalloc_get_size (val);
- if (memcmp (xmalloc_overrun_check_trailer, val + osize,
- XMALLOC_OVERRUN_CHECK_SIZE))
- emacs_abort ();
- memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
- val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
- memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
- }
-
- val = realloc (val, size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
-
- if (val)
- {
- memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
- val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
- xmalloc_put_size (val, size);
- memcpy (val + size, xmalloc_overrun_check_trailer,
- XMALLOC_OVERRUN_CHECK_SIZE);
- }
- return val;
-}
-
-/* Like free, but checks block for overrun. */
-
-static void
-overrun_check_free (void *block)
-{
- unsigned char *val = (unsigned char *) block;
-
- if (val
- && memcmp (xmalloc_overrun_check_header,
- val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
- XMALLOC_OVERRUN_CHECK_SIZE) == 0)
- {
- size_t osize = xmalloc_get_size (val);
- if (memcmp (xmalloc_overrun_check_trailer, val + osize,
- XMALLOC_OVERRUN_CHECK_SIZE))
- emacs_abort ();
-#ifdef XMALLOC_CLEAR_FREE_MEMORY
- val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
- memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
-#else
- memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
- val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
- memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
-#endif
- }
-
- free (val);
-}
-
-#undef malloc
-#undef realloc
-#undef free
-#define malloc overrun_check_malloc
-#define realloc overrun_check_realloc
-#define free overrun_check_free
-#endif
-