aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-09-29 20:25:46 -0700
committerPaul Eggert2011-09-29 20:25:46 -0700
commitcb993c584c8ef91f5352ec9aa97d26fd76cfd643 (patch)
tree923b3bcb5b390d9b3d5f34e941b29f4d80f13477 /src
parent5f91c1e5303017cad6ed7d7d903440b3328fe7ff (diff)
downloademacs-cb993c584c8ef91f5352ec9aa97d26fd76cfd643.tar.gz
emacs-cb993c584c8ef91f5352ec9aa97d26fd76cfd643.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog20
-rw-r--r--src/alloc.c47
-rw-r--r--src/charset.c2
-rw-r--r--src/lisp.h48
4 files changed, 84 insertions, 33 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index dcbeffac1b4..d6e5390c84f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,23 @@
12011-09-30 Paul Eggert <eggert@cs.ucla.edu>
2
3 Port --enable-checking=all to Fedora 14 x86.
4 * alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
5 Move to lisp.h.
6 (xmalloc_put_size, xmalloc_get_size, overrun_check_malloc)
7 (overrun_check_realloc, overrun_check_free):
8 Use XMALLOC_OVERRUN_SIZE_SIZE, not sizeof (size_t).
9 That way, xmalloc returns a properly-aligned pointer even if
10 XMALLOC_OVERRUN_CHECK is defined. The old debugging code happened
11 to align OK on typical 64-bit hosts, but not on Fedora 14 x86.
12 * charset.c (syms_of_charset): Take XMALLOC_OVERRUN_CHECK_OVERHEAD
13 into account when calculating the initial malloc maximum.
14 * lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
15 Move here from alloc.c, so that charset.c can use it too.
16 Properly align; the old code wasn't right for common 32-bit hosts
17 when configured with --enable-checking=all.
18 (XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
19 (XMALLOC_OVERRUN_SIZE_SIZE): New macros.
20
12011-09-29 Eli Zaretskii <eliz@gnu.org> 212011-09-29 Eli Zaretskii <eliz@gnu.org>
2 22
3 * sysdep.c (snprintf) [EOVERFLOW]: If EOVERFLOW is not defined, 23 * sysdep.c (snprintf) [EOVERFLOW]: If EOVERFLOW is not defined,
diff --git a/src/alloc.c b/src/alloc.c
index ad1741e308f..4c5094b8f48 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -482,27 +482,10 @@ buffer_memory_full (EMACS_INT nbytes)
482 xsignal (Qnil, Vmemory_signal_data); 482 xsignal (Qnil, Vmemory_signal_data);
483} 483}
484 484
485 485#ifdef XMALLOC_OVERRUN_CHECK
486#ifndef XMALLOC_OVERRUN_CHECK
487#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
488#else
489 486
490/* Check for overrun in malloc'ed buffers by wrapping a header and trailer 487/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
491 around each block. 488 around each block. */
492
493 The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
494 containing the original block size in little-endian order,
495 while the trailer consists of 16 fixed bytes.
496
497 The header is used to detect whether this block has been allocated
498 through these functions -- as it seems that some low-level libc
499 functions may bypass the malloc hooks.
500*/
501
502
503#define XMALLOC_OVERRUN_CHECK_SIZE 16
504#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
505 (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t))
506 489
507static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = 490static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
508 { '\x9a', '\x9b', '\xae', '\xaf', 491 { '\x9a', '\x9b', '\xae', '\xaf',
@@ -522,9 +505,9 @@ static void
522xmalloc_put_size (unsigned char *ptr, size_t size) 505xmalloc_put_size (unsigned char *ptr, size_t size)
523{ 506{
524 int i; 507 int i;
525 for (i = 0; i < sizeof (size_t); i++) 508 for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
526 { 509 {
527 *--ptr = size & (1 << CHAR_BIT) - 1; 510 *--ptr = size & ((1 << CHAR_BIT) - 1);
528 size >>= CHAR_BIT; 511 size >>= CHAR_BIT;
529 } 512 }
530} 513}
@@ -534,8 +517,8 @@ xmalloc_get_size (unsigned char *ptr)
534{ 517{
535 size_t size = 0; 518 size_t size = 0;
536 int i; 519 int i;
537 ptr -= sizeof (size_t); 520 ptr -= XMALLOC_OVERRUN_SIZE_SIZE;
538 for (i = 0; i < sizeof (size_t); i++) 521 for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
539 { 522 {
540 size <<= CHAR_BIT; 523 size <<= CHAR_BIT;
541 size += *ptr++; 524 size += *ptr++;
@@ -579,7 +562,7 @@ overrun_check_malloc (size_t size)
579 if (val && check_depth == 1) 562 if (val && check_depth == 1)
580 { 563 {
581 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 564 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
582 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 565 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
583 xmalloc_put_size (val, size); 566 xmalloc_put_size (val, size);
584 memcpy (val + size, xmalloc_overrun_check_trailer, 567 memcpy (val + size, xmalloc_overrun_check_trailer,
585 XMALLOC_OVERRUN_CHECK_SIZE); 568 XMALLOC_OVERRUN_CHECK_SIZE);
@@ -603,7 +586,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
603 if (val 586 if (val
604 && check_depth == 1 587 && check_depth == 1
605 && memcmp (xmalloc_overrun_check_header, 588 && memcmp (xmalloc_overrun_check_header,
606 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t), 589 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
607 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 590 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
608 { 591 {
609 size_t osize = xmalloc_get_size (val); 592 size_t osize = xmalloc_get_size (val);
@@ -611,8 +594,8 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
611 XMALLOC_OVERRUN_CHECK_SIZE)) 594 XMALLOC_OVERRUN_CHECK_SIZE))
612 abort (); 595 abort ();
613 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 596 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
614 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 597 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
615 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)); 598 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
616 } 599 }
617 600
618 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); 601 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
@@ -620,7 +603,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
620 if (val && check_depth == 1) 603 if (val && check_depth == 1)
621 { 604 {
622 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 605 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
623 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 606 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
624 xmalloc_put_size (val, size); 607 xmalloc_put_size (val, size);
625 memcpy (val + size, xmalloc_overrun_check_trailer, 608 memcpy (val + size, xmalloc_overrun_check_trailer,
626 XMALLOC_OVERRUN_CHECK_SIZE); 609 XMALLOC_OVERRUN_CHECK_SIZE);
@@ -640,7 +623,7 @@ overrun_check_free (POINTER_TYPE *block)
640 if (val 623 if (val
641 && check_depth == 1 624 && check_depth == 1
642 && memcmp (xmalloc_overrun_check_header, 625 && memcmp (xmalloc_overrun_check_header,
643 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t), 626 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
644 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 627 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
645 { 628 {
646 size_t osize = xmalloc_get_size (val); 629 size_t osize = xmalloc_get_size (val);
@@ -648,12 +631,12 @@ overrun_check_free (POINTER_TYPE *block)
648 XMALLOC_OVERRUN_CHECK_SIZE)) 631 XMALLOC_OVERRUN_CHECK_SIZE))
649 abort (); 632 abort ();
650#ifdef XMALLOC_CLEAR_FREE_MEMORY 633#ifdef XMALLOC_CLEAR_FREE_MEMORY
651 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 634 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
652 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD); 635 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
653#else 636#else
654 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 637 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
655 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 638 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
656 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)); 639 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
657#endif 640#endif
658 } 641 }
659 642
diff --git a/src/charset.c b/src/charset.c
index 6967b9df611..1209ac6b68d 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2337,7 +2337,7 @@ syms_of_charset (void)
2337 mmap for larger allocations, and these don't work well across dumped 2337 mmap for larger allocations, and these don't work well across dumped
2338 systems. */ 2338 systems. */
2339 enum { 2339 enum {
2340 initial_malloc_max = (1 << 16) - 1, 2340 initial_malloc_max = (1 << 16) - 1 - XMALLOC_OVERRUN_CHECK_OVERHEAD,
2341 charset_table_size_init = initial_malloc_max / sizeof (struct charset) 2341 charset_table_size_init = initial_malloc_max / sizeof (struct charset)
2342 }; 2342 };
2343 2343
diff --git a/src/lisp.h b/src/lisp.h
index e9a525a32b5..7aba299f162 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3568,6 +3568,54 @@ extern int initialized;
3568 3568
3569extern int immediate_quit; /* Nonzero means ^G can quit instantly */ 3569extern int immediate_quit; /* Nonzero means ^G can quit instantly */
3570 3570
3571/* Overhead for overrun check in malloc'ed buffers. The check
3572 operates by wrapping a header and trailer around each block.
3573
3574 The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes
3575 followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original
3576 block size in little-endian order. The trailer consists of
3577 XMALLOC_OVERRUN_CHECK_SIZE fixed bytes.
3578
3579 The header is used to detect whether this block has been allocated
3580 through these functions, as some low-level libc functions may
3581 bypass the malloc hooks. */
3582
3583#ifndef XMALLOC_OVERRUN_CHECK
3584# define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
3585#else
3586
3587# define XMALLOC_OVERRUN_CHECK_SIZE 16
3588# define XMALLOC_OVERRUN_CHECK_OVERHEAD \
3589 (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE)
3590
3591/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to
3592 hold a size_t value and (2) the header size is a multiple of the
3593 alignment that Emacs needs for C types and for USE_LSB_TAG. */
3594# define XMALLOC_BASE_ALIGNMENT \
3595 offsetof ( \
3596 struct { \
3597 union { long double d; intmax_t i; void *p; } u; \
3598 char c; \
3599 }, \
3600 c)
3601# ifdef USE_LSB_TAG
3602/* A common multiple of the positive integers A and B. Ideally this
3603 would be the least common multiple, but there's no way to do that
3604 as a constant expression in C, so do the best that we can easily do. */
3605# define COMMON_MULTIPLE(a, b) \
3606 ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
3607# define XMALLOC_HEADER_ALIGNMENT \
3608 COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT)
3609# else
3610# define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT
3611# endif
3612# define XMALLOC_OVERRUN_SIZE_SIZE \
3613 (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \
3614 + XMALLOC_HEADER_ALIGNMENT - 1) \
3615 / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \
3616 - XMALLOC_OVERRUN_CHECK_SIZE)
3617#endif
3618
3571extern POINTER_TYPE *xmalloc (size_t); 3619extern POINTER_TYPE *xmalloc (size_t);
3572extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t); 3620extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t);
3573extern void xfree (POINTER_TYPE *); 3621extern void xfree (POINTER_TYPE *);