Commit cb993c58 authored by Paul Eggert's avatar Paul Eggert

Port --enable-checking=all to Fedora 14 x86.

* alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move to lisp.h.
(xmalloc_put_size, xmalloc_get_size, overrun_check_malloc)
(overrun_check_realloc, overrun_check_free):
Use XMALLOC_OVERRUN_SIZE_SIZE, not sizeof (size_t).
That way, xmalloc returns a properly-aligned pointer even if
XMALLOC_OVERRUN_CHECK is defined.  The old debugging code happened
to align OK on typical 64-bit hosts, but not on Fedora 14 x86.
* charset.c (syms_of_charset): Take XMALLOC_OVERRUN_CHECK_OVERHEAD
into account when calculating the initial malloc maximum.
* lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move here from alloc.c, so that charset.c can use it too.
Properly align; the old code wasn't right for common 32-bit hosts
when configured with --enable-checking=all.
(XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
(XMALLOC_OVERRUN_SIZE_SIZE): New macros.
parent 5f91c1e5
2011-09-30 Paul Eggert <eggert@cs.ucla.edu>
Port --enable-checking=all to Fedora 14 x86.
* alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move to lisp.h.
(xmalloc_put_size, xmalloc_get_size, overrun_check_malloc)
(overrun_check_realloc, overrun_check_free):
Use XMALLOC_OVERRUN_SIZE_SIZE, not sizeof (size_t).
That way, xmalloc returns a properly-aligned pointer even if
XMALLOC_OVERRUN_CHECK is defined. The old debugging code happened
to align OK on typical 64-bit hosts, but not on Fedora 14 x86.
* charset.c (syms_of_charset): Take XMALLOC_OVERRUN_CHECK_OVERHEAD
into account when calculating the initial malloc maximum.
* lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move here from alloc.c, so that charset.c can use it too.
Properly align; the old code wasn't right for common 32-bit hosts
when configured with --enable-checking=all.
(XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
(XMALLOC_OVERRUN_SIZE_SIZE): New macros.
2011-09-29 Eli Zaretskii <eliz@gnu.org>
* sysdep.c (snprintf) [EOVERFLOW]: If EOVERFLOW is not defined,
......
......@@ -482,27 +482,10 @@ buffer_memory_full (EMACS_INT nbytes)
xsignal (Qnil, Vmemory_signal_data);
}
#ifndef XMALLOC_OVERRUN_CHECK
#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
#else
#ifdef XMALLOC_OVERRUN_CHECK
/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
around each block.
The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
containing the original block size in little-endian order,
while the trailer consists of 16 fixed bytes.
The header is used to detect whether this block has been allocated
through these functions -- as it seems that 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 + sizeof (size_t))
around each block. */
static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
{ '\x9a', '\x9b', '\xae', '\xaf',
......@@ -522,9 +505,9 @@ static void
xmalloc_put_size (unsigned char *ptr, size_t size)
{
int i;
for (i = 0; i < sizeof (size_t); i++)
for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
{
*--ptr = size & (1 << CHAR_BIT) - 1;
*--ptr = size & ((1 << CHAR_BIT) - 1);
size >>= CHAR_BIT;
}
}
......@@ -534,8 +517,8 @@ xmalloc_get_size (unsigned char *ptr)
{
size_t size = 0;
int i;
ptr -= sizeof (size_t);
for (i = 0; i < sizeof (size_t); i++)
ptr -= XMALLOC_OVERRUN_SIZE_SIZE;
for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
{
size <<= CHAR_BIT;
size += *ptr++;
......@@ -579,7 +562,7 @@ overrun_check_malloc (size_t size)
if (val && check_depth == 1)
{
memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
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);
......@@ -603,7 +586,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
if (val
&& check_depth == 1
&& memcmp (xmalloc_overrun_check_header,
val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
XMALLOC_OVERRUN_CHECK_SIZE) == 0)
{
size_t osize = xmalloc_get_size (val);
......@@ -611,8 +594,8 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
XMALLOC_OVERRUN_CHECK_SIZE))
abort ();
memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
}
val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
......@@ -620,7 +603,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
if (val && check_depth == 1)
{
memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
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);
......@@ -640,7 +623,7 @@ overrun_check_free (POINTER_TYPE *block)
if (val
&& check_depth == 1
&& memcmp (xmalloc_overrun_check_header,
val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
XMALLOC_OVERRUN_CHECK_SIZE) == 0)
{
size_t osize = xmalloc_get_size (val);
......@@ -648,12 +631,12 @@ overrun_check_free (POINTER_TYPE *block)
XMALLOC_OVERRUN_CHECK_SIZE))
abort ();
#ifdef XMALLOC_CLEAR_FREE_MEMORY
val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
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 + sizeof (size_t);
memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
#endif
}
......
......@@ -2337,7 +2337,7 @@ syms_of_charset (void)
mmap for larger allocations, and these don't work well across dumped
systems. */
enum {
initial_malloc_max = (1 << 16) - 1,
initial_malloc_max = (1 << 16) - 1 - XMALLOC_OVERRUN_CHECK_OVERHEAD,
charset_table_size_init = initial_malloc_max / sizeof (struct charset)
};
......
......@@ -3568,6 +3568,54 @@ extern int initialized;
extern int immediate_quit; /* Nonzero means ^G can quit instantly */
/* Overhead for overrun check in malloc'ed buffers. The check
operates 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. */
#ifndef XMALLOC_OVERRUN_CHECK
# define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
#else
# 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 \
offsetof ( \
struct { \
union { long double d; intmax_t i; void *p; } u; \
char c; \
}, \
c)
# ifdef USE_LSB_TAG
/* A common multiple of the positive integers A and B. Ideally this
would be the least common multiple, but there's no way to do that
as a constant expression in C, so do the best that we can easily do. */
# define COMMON_MULTIPLE(a, b) \
((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
# define XMALLOC_HEADER_ALIGNMENT \
COMMON_MULTIPLE (1 << GCTYPEBITS, 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)
#endif
extern POINTER_TYPE *xmalloc (size_t);
extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t);
extern void xfree (POINTER_TYPE *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment