aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 6bcb216bb5e..286421ebe47 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -490,9 +490,9 @@ buffer_memory_full (ptrdiff_t nbytes)
490/* Check for overrun in malloc'ed buffers by wrapping a header and trailer 490/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
491 around each block. 491 around each block.
492 492
493 The header consists of 16 fixed bytes followed by sizeof (size_t) bytes 493 The header consists of 16 fixed bytes followed by
494 containing the original block size in little-endian order, 494 XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original block size
495 while the trailer consists of 16 fixed bytes. 495 in little-endian order. The trailer consists of 16 fixed bytes.
496 496
497 The header is used to detect whether this block has been allocated 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 498 through these functions -- as it seems that some low-level libc
@@ -502,7 +502,24 @@ buffer_memory_full (ptrdiff_t nbytes)
502 502
503#define XMALLOC_OVERRUN_CHECK_SIZE 16 503#define XMALLOC_OVERRUN_CHECK_SIZE 16
504#define XMALLOC_OVERRUN_CHECK_OVERHEAD \ 504#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
505 (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)) 505 (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE)
506
507/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to
508 hold a size_t value and (2) so that the header size is a multiple
509 of the alignment that Emacs needs. */
510#define alignof(type) offsetof (struct { char c; type x; }, x)
511#define XMALLOC_BASE_ALIGNMENT \
512 max (max (alignof (double), alignof (long double)), alignof (intmax_t))
513#ifdef USE_LSB_TAG
514# define XMALLOC_HEADER_ALIGNMENT max (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT)
515#else
516# define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT
517#endif
518#define XMALLOC_OVERRUN_SIZE_SIZE \
519 (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \
520 + XMALLOC_HEADER_ALIGNMENT - 1) \
521 / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \
522 - XMALLOC_OVERRUN_CHECK_SIZE)
506 523
507static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = 524static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
508 { '\x9a', '\x9b', '\xae', '\xaf', 525 { '\x9a', '\x9b', '\xae', '\xaf',
@@ -522,9 +539,9 @@ static void
522xmalloc_put_size (unsigned char *ptr, size_t size) 539xmalloc_put_size (unsigned char *ptr, size_t size)
523{ 540{
524 int i; 541 int i;
525 for (i = 0; i < sizeof (size_t); i++) 542 for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
526 { 543 {
527 *--ptr = size & (1 << CHAR_BIT) - 1; 544 *--ptr = size & ((1 << CHAR_BIT) - 1);
528 size >>= CHAR_BIT; 545 size >>= CHAR_BIT;
529 } 546 }
530} 547}
@@ -534,8 +551,8 @@ xmalloc_get_size (unsigned char *ptr)
534{ 551{
535 size_t size = 0; 552 size_t size = 0;
536 int i; 553 int i;
537 ptr -= sizeof (size_t); 554 ptr -= XMALLOC_OVERRUN_SIZE_SIZE;
538 for (i = 0; i < sizeof (size_t); i++) 555 for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++)
539 { 556 {
540 size <<= CHAR_BIT; 557 size <<= CHAR_BIT;
541 size += *ptr++; 558 size += *ptr++;
@@ -579,7 +596,7 @@ overrun_check_malloc (size_t size)
579 if (val && check_depth == 1) 596 if (val && check_depth == 1)
580 { 597 {
581 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 598 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
582 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 599 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
583 xmalloc_put_size (val, size); 600 xmalloc_put_size (val, size);
584 memcpy (val + size, xmalloc_overrun_check_trailer, 601 memcpy (val + size, xmalloc_overrun_check_trailer,
585 XMALLOC_OVERRUN_CHECK_SIZE); 602 XMALLOC_OVERRUN_CHECK_SIZE);
@@ -603,7 +620,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
603 if (val 620 if (val
604 && check_depth == 1 621 && check_depth == 1
605 && memcmp (xmalloc_overrun_check_header, 622 && memcmp (xmalloc_overrun_check_header,
606 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t), 623 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
607 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 624 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
608 { 625 {
609 size_t osize = xmalloc_get_size (val); 626 size_t osize = xmalloc_get_size (val);
@@ -611,8 +628,8 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
611 XMALLOC_OVERRUN_CHECK_SIZE)) 628 XMALLOC_OVERRUN_CHECK_SIZE))
612 abort (); 629 abort ();
613 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 630 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
614 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 631 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
615 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)); 632 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
616 } 633 }
617 634
618 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); 635 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
@@ -620,7 +637,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size)
620 if (val && check_depth == 1) 637 if (val && check_depth == 1)
621 { 638 {
622 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 639 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
623 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 640 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
624 xmalloc_put_size (val, size); 641 xmalloc_put_size (val, size);
625 memcpy (val + size, xmalloc_overrun_check_trailer, 642 memcpy (val + size, xmalloc_overrun_check_trailer,
626 XMALLOC_OVERRUN_CHECK_SIZE); 643 XMALLOC_OVERRUN_CHECK_SIZE);
@@ -640,7 +657,7 @@ overrun_check_free (POINTER_TYPE *block)
640 if (val 657 if (val
641 && check_depth == 1 658 && check_depth == 1
642 && memcmp (xmalloc_overrun_check_header, 659 && memcmp (xmalloc_overrun_check_header,
643 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t), 660 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
644 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 661 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
645 { 662 {
646 size_t osize = xmalloc_get_size (val); 663 size_t osize = xmalloc_get_size (val);
@@ -648,12 +665,12 @@ overrun_check_free (POINTER_TYPE *block)
648 XMALLOC_OVERRUN_CHECK_SIZE)) 665 XMALLOC_OVERRUN_CHECK_SIZE))
649 abort (); 666 abort ();
650#ifdef XMALLOC_CLEAR_FREE_MEMORY 667#ifdef XMALLOC_CLEAR_FREE_MEMORY
651 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 668 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
652 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD); 669 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
653#else 670#else
654 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 671 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
655 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t); 672 val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
656 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)); 673 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
657#endif 674#endif
658 } 675 }
659 676