aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c136
1 files changed, 78 insertions, 58 deletions
diff --git a/src/alloc.c b/src/alloc.c
index f679787e95c..5cdd5af9ecf 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -70,7 +70,7 @@ extern POINTER_TYPE *sbrk ();
70#include <malloc.h> 70#include <malloc.h>
71/* malloc.h #defines this as size_t, at least in glibc2. */ 71/* malloc.h #defines this as size_t, at least in glibc2. */
72#ifndef __malloc_size_t 72#ifndef __malloc_size_t
73#define __malloc_size_t int 73#define __malloc_size_t size_t
74#endif 74#endif
75 75
76/* Specify maximum number of areas to mmap. It would be nice to use a 76/* Specify maximum number of areas to mmap. It would be nice to use a
@@ -214,12 +214,12 @@ EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,};
214/* Pointer to the pure area, and its size. */ 214/* Pointer to the pure area, and its size. */
215 215
216static char *purebeg; 216static char *purebeg;
217static size_t pure_size; 217static ptrdiff_t pure_size;
218 218
219/* Number of bytes of pure storage used before pure storage overflowed. 219/* Number of bytes of pure storage used before pure storage overflowed.
220 If this is non-zero, this implies that an overflow occurred. */ 220 If this is non-zero, this implies that an overflow occurred. */
221 221
222static size_t pure_bytes_used_before_overflow; 222static ptrdiff_t pure_bytes_used_before_overflow;
223 223
224/* Value is non-zero if P points into pure space. */ 224/* Value is non-zero if P points into pure space. */
225 225
@@ -252,7 +252,7 @@ const char *pending_malloc_warning;
252 252
253#if MAX_SAVE_STACK > 0 253#if MAX_SAVE_STACK > 0
254static char *stack_copy; 254static char *stack_copy;
255static size_t stack_copy_size; 255static ptrdiff_t stack_copy_size;
256#endif 256#endif
257 257
258/* Non-zero means ignore malloc warnings. Set during initialization. 258/* Non-zero means ignore malloc warnings. Set during initialization.
@@ -486,14 +486,15 @@ buffer_memory_full (EMACS_INT nbytes)
486 486
487 487
488#ifndef XMALLOC_OVERRUN_CHECK 488#ifndef XMALLOC_OVERRUN_CHECK
489#define XMALLOC_OVERRUN_CHECK_SIZE 0 489#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
490#else 490#else
491 491
492/* Check for overrun in malloc'ed buffers by wrapping a 16 byte header 492/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
493 and a 16 byte trailer around each block. 493 around each block.
494 494
495 The header consists of 12 fixed bytes + a 4 byte integer contaning the 495 The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
496 original block size, while the trailer consists of 16 fixed bytes. 496 containing the original block size in little-endian order,
497 while the trailer consists of 16 fixed bytes.
497 498
498 The header is used to detect whether this block has been allocated 499 The header is used to detect whether this block has been allocated
499 through these functions -- as it seems that some low-level libc 500 through these functions -- as it seems that some low-level libc
@@ -502,31 +503,47 @@ buffer_memory_full (EMACS_INT nbytes)
502 503
503 504
504#define XMALLOC_OVERRUN_CHECK_SIZE 16 505#define XMALLOC_OVERRUN_CHECK_SIZE 16
506#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
507 (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t))
505 508
506static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] = 509static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
507 { 0x9a, 0x9b, 0xae, 0xaf, 510 { '\x9a', '\x9b', '\xae', '\xaf',
508 0xbf, 0xbe, 0xce, 0xcf, 511 '\xbf', '\xbe', '\xce', '\xcf',
509 0xea, 0xeb, 0xec, 0xed }; 512 '\xea', '\xeb', '\xec', '\xed',
513 '\xdf', '\xde', '\x9c', '\x9d' };
510 514
511static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = 515static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
512 { 0xaa, 0xab, 0xac, 0xad, 516 { '\xaa', '\xab', '\xac', '\xad',
513 0xba, 0xbb, 0xbc, 0xbd, 517 '\xba', '\xbb', '\xbc', '\xbd',
514 0xca, 0xcb, 0xcc, 0xcd, 518 '\xca', '\xcb', '\xcc', '\xcd',
515 0xda, 0xdb, 0xdc, 0xdd }; 519 '\xda', '\xdb', '\xdc', '\xdd' };
516 520
517/* Macros to insert and extract the block size in the header. */ 521/* Insert and extract the block size in the header. */
518 522
519#define XMALLOC_PUT_SIZE(ptr, size) \ 523static void
520 (ptr[-1] = (size & 0xff), \ 524xmalloc_put_size (unsigned char *ptr, size_t size)
521 ptr[-2] = ((size >> 8) & 0xff), \ 525{
522 ptr[-3] = ((size >> 16) & 0xff), \ 526 int i;
523 ptr[-4] = ((size >> 24) & 0xff)) 527 for (i = 0; i < sizeof (size_t); i++)
528 {
529 *--ptr = size & (1 << CHAR_BIT) - 1;
530 size >>= CHAR_BIT;
531 }
532}
524 533
525#define XMALLOC_GET_SIZE(ptr) \ 534static size_t
526 (size_t)((unsigned)(ptr[-1]) | \ 535xmalloc_get_size (unsigned char *ptr)
527 ((unsigned)(ptr[-2]) << 8) | \ 536{
528 ((unsigned)(ptr[-3]) << 16) | \ 537 size_t size = 0;
529 ((unsigned)(ptr[-4]) << 24)) 538 int i;
539 ptr -= sizeof (size_t);
540 for (i = 0; i < sizeof (size_t); i++)
541 {
542 size <<= CHAR_BIT;
543 size += *ptr++;
544 }
545 return size;
546}
530 547
531 548
532/* The call depth in overrun_check functions. For example, this might happen: 549/* The call depth in overrun_check functions. For example, this might happen:
@@ -545,10 +562,10 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
545 562
546 xfree(10032) 563 xfree(10032)
547 overrun_check_free(10032) 564 overrun_check_free(10032)
548 decrease overhed 565 decrease overhead
549 free(10016) <- crash, because 10000 is the original pointer. */ 566 free(10016) <- crash, because 10000 is the original pointer. */
550 567
551static int check_depth; 568static ptrdiff_t check_depth;
552 569
553/* Like malloc, but wraps allocated block with header and trailer. */ 570/* Like malloc, but wraps allocated block with header and trailer. */
554 571
@@ -556,15 +573,16 @@ static POINTER_TYPE *
556overrun_check_malloc (size_t size) 573overrun_check_malloc (size_t size)
557{ 574{
558 register unsigned char *val; 575 register unsigned char *val;
559 size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; 576 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
577 if (SIZE_MAX - overhead < size)
578 abort ();
560 579
561 val = (unsigned char *) malloc (size + overhead); 580 val = (unsigned char *) malloc (size + overhead);
562 if (val && check_depth == 1) 581 if (val && check_depth == 1)
563 { 582 {
564 memcpy (val, xmalloc_overrun_check_header, 583 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
565 XMALLOC_OVERRUN_CHECK_SIZE - 4); 584 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
566 val += XMALLOC_OVERRUN_CHECK_SIZE; 585 xmalloc_put_size (val, size);
567 XMALLOC_PUT_SIZE(val, size);
568 memcpy (val + size, xmalloc_overrun_check_trailer, 586 memcpy (val + size, xmalloc_overrun_check_trailer,
569 XMALLOC_OVERRUN_CHECK_SIZE); 587 XMALLOC_OVERRUN_CHECK_SIZE);
570 } 588 }
@@ -580,31 +598,32 @@ static POINTER_TYPE *
580overrun_check_realloc (POINTER_TYPE *block, size_t size) 598overrun_check_realloc (POINTER_TYPE *block, size_t size)
581{ 599{
582 register unsigned char *val = (unsigned char *) block; 600 register unsigned char *val = (unsigned char *) block;
583 size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; 601 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
602 if (SIZE_MAX - overhead < size)
603 abort ();
584 604
585 if (val 605 if (val
586 && check_depth == 1 606 && check_depth == 1
587 && memcmp (xmalloc_overrun_check_header, 607 && memcmp (xmalloc_overrun_check_header,
588 val - XMALLOC_OVERRUN_CHECK_SIZE, 608 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
589 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) 609 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
590 { 610 {
591 size_t osize = XMALLOC_GET_SIZE (val); 611 size_t osize = xmalloc_get_size (val);
592 if (memcmp (xmalloc_overrun_check_trailer, val + osize, 612 if (memcmp (xmalloc_overrun_check_trailer, val + osize,
593 XMALLOC_OVERRUN_CHECK_SIZE)) 613 XMALLOC_OVERRUN_CHECK_SIZE))
594 abort (); 614 abort ();
595 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 615 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
596 val -= XMALLOC_OVERRUN_CHECK_SIZE; 616 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
597 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE); 617 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
598 } 618 }
599 619
600 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); 620 val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
601 621
602 if (val && check_depth == 1) 622 if (val && check_depth == 1)
603 { 623 {
604 memcpy (val, xmalloc_overrun_check_header, 624 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
605 XMALLOC_OVERRUN_CHECK_SIZE - 4); 625 val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
606 val += XMALLOC_OVERRUN_CHECK_SIZE; 626 xmalloc_put_size (val, size);
607 XMALLOC_PUT_SIZE(val, size);
608 memcpy (val + size, xmalloc_overrun_check_trailer, 627 memcpy (val + size, xmalloc_overrun_check_trailer,
609 XMALLOC_OVERRUN_CHECK_SIZE); 628 XMALLOC_OVERRUN_CHECK_SIZE);
610 } 629 }
@@ -623,20 +642,20 @@ overrun_check_free (POINTER_TYPE *block)
623 if (val 642 if (val
624 && check_depth == 1 643 && check_depth == 1
625 && memcmp (xmalloc_overrun_check_header, 644 && memcmp (xmalloc_overrun_check_header,
626 val - XMALLOC_OVERRUN_CHECK_SIZE, 645 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
627 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) 646 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
628 { 647 {
629 size_t osize = XMALLOC_GET_SIZE (val); 648 size_t osize = xmalloc_get_size (val);
630 if (memcmp (xmalloc_overrun_check_trailer, val + osize, 649 if (memcmp (xmalloc_overrun_check_trailer, val + osize,
631 XMALLOC_OVERRUN_CHECK_SIZE)) 650 XMALLOC_OVERRUN_CHECK_SIZE))
632 abort (); 651 abort ();
633#ifdef XMALLOC_CLEAR_FREE_MEMORY 652#ifdef XMALLOC_CLEAR_FREE_MEMORY
634 val -= XMALLOC_OVERRUN_CHECK_SIZE; 653 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
635 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_SIZE*2); 654 memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
636#else 655#else
637 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); 656 memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
638 val -= XMALLOC_OVERRUN_CHECK_SIZE; 657 val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
639 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE); 658 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
640#endif 659#endif
641 } 660 }
642 661
@@ -1661,7 +1680,8 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
1661 calculating a value to be passed to malloc. */ 1680 calculating a value to be passed to malloc. */
1662#define STRING_BYTES_MAX \ 1681#define STRING_BYTES_MAX \
1663 min (STRING_BYTES_BOUND, \ 1682 min (STRING_BYTES_BOUND, \
1664 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_SIZE - GC_STRING_EXTRA \ 1683 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD \
1684 - GC_STRING_EXTRA \
1665 - offsetof (struct sblock, first_data) \ 1685 - offsetof (struct sblock, first_data) \
1666 - SDATA_DATA_OFFSET) \ 1686 - SDATA_DATA_OFFSET) \
1667 & ~(sizeof (EMACS_INT) - 1))) 1687 & ~(sizeof (EMACS_INT) - 1)))
@@ -3320,7 +3340,7 @@ refill_memory_reserve (void)
3320{ 3340{
3321#ifndef SYSTEM_MALLOC 3341#ifndef SYSTEM_MALLOC
3322 if (spare_memory[0] == 0) 3342 if (spare_memory[0] == 0)
3323 spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); 3343 spare_memory[0] = (char *) malloc (SPARE_MEMORY);
3324 if (spare_memory[1] == 0) 3344 if (spare_memory[1] == 0)
3325 spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), 3345 spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block),
3326 MEM_TYPE_CONS); 3346 MEM_TYPE_CONS);
@@ -4922,7 +4942,7 @@ returns nil, because real GC can't be done. */)
4922 if (NILP (Vpurify_flag)) 4942 if (NILP (Vpurify_flag))
4923 { 4943 {
4924 char *stack; 4944 char *stack;
4925 size_t stack_size; 4945 ptrdiff_t stack_size;
4926 if (&stack_top_variable < stack_bottom) 4946 if (&stack_top_variable < stack_bottom)
4927 { 4947 {
4928 stack = &stack_top_variable; 4948 stack = &stack_top_variable;
@@ -5233,7 +5253,7 @@ static int last_marked_index;
5233 links of a list, in mark_object. In debugging, 5253 links of a list, in mark_object. In debugging,
5234 the call to abort will hit a breakpoint. 5254 the call to abort will hit a breakpoint.
5235 Normally this is zero and the check never goes off. */ 5255 Normally this is zero and the check never goes off. */
5236static size_t mark_object_loop_halt; 5256ptrdiff_t mark_object_loop_halt EXTERNALLY_VISIBLE;
5237 5257
5238static void 5258static void
5239mark_vectorlike (struct Lisp_Vector *ptr) 5259mark_vectorlike (struct Lisp_Vector *ptr)
@@ -5290,7 +5310,7 @@ mark_object (Lisp_Object arg)
5290 void *po; 5310 void *po;
5291 struct mem_node *m; 5311 struct mem_node *m;
5292#endif 5312#endif
5293 size_t cdr_count = 0; 5313 ptrdiff_t cdr_count = 0;
5294 5314
5295 loop: 5315 loop:
5296 5316