diff options
| author | Gerd Moellmann | 2000-10-24 12:41:23 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-10-24 12:41:23 +0000 |
| commit | 5dcab13e691fee1fbd8b3c842363a0587c74ce3b (patch) | |
| tree | 99704694ff1f7a2898a54fa0deec44b1c8401fe2 /src/gmalloc.c | |
| parent | a98397797d98297dd46511b78807ccf11ae1563b (diff) | |
| download | emacs-5dcab13e691fee1fbd8b3c842363a0587c74ce3b.tar.gz emacs-5dcab13e691fee1fbd8b3c842363a0587c74ce3b.zip | |
(state_protected_p, last_state_size, last_heapinfo)
[GC_MALLOC_CHECK && GC_PROTECT_MALLOC_STATE]: New variables.
(protect_malloc_state) [GC_MALLOC_CHECK &&
GC_PROTECT_MALLOC_STATE]: New function.
(PROTECT_MALLOC_STATE): New macro.
(__malloc_initialize, morecore, _malloc_internal)
(_free_internal) _realloc_internal): Use it to make _heapinfo
read-only outside of gmalloc.
Diffstat (limited to 'src/gmalloc.c')
| -rw-r--r-- | src/gmalloc.c | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c index 2ce168c71c8..e7cc2c3947e 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -380,6 +380,53 @@ __malloc_size_t __malloc_extra_blocks; | |||
| 380 | void (*__malloc_initialize_hook) PP ((void)); | 380 | void (*__malloc_initialize_hook) PP ((void)); |
| 381 | void (*__after_morecore_hook) PP ((void)); | 381 | void (*__after_morecore_hook) PP ((void)); |
| 382 | 382 | ||
| 383 | #if defined GC_MALLOC_CHECK && defined GC_PROTECT_MALLOC_STATE | ||
| 384 | |||
| 385 | /* Some code for hunting a bug writing into _heapinfo. | ||
| 386 | |||
| 387 | Call this macro with argument PROT non-zero to protect internal | ||
| 388 | malloc state against writing to it, call it with a zero argument to | ||
| 389 | make it readable and writable. | ||
| 390 | |||
| 391 | Note that this only works if BLOCKSIZE == page size, which is | ||
| 392 | the case on the i386. */ | ||
| 393 | |||
| 394 | #include <sys/types.h> | ||
| 395 | #include <sys/mman.h> | ||
| 396 | |||
| 397 | static int state_protected_p; | ||
| 398 | static __malloc_size_t last_state_size; | ||
| 399 | static malloc_info *last_heapinfo; | ||
| 400 | |||
| 401 | void | ||
| 402 | protect_malloc_state (protect_p) | ||
| 403 | int protect_p; | ||
| 404 | { | ||
| 405 | /* If _heapinfo has been relocated, make sure its old location | ||
| 406 | isn't left read-only; it will be reused by malloc. */ | ||
| 407 | if (_heapinfo != last_heapinfo | ||
| 408 | && last_heapinfo | ||
| 409 | && state_protected_p) | ||
| 410 | mprotect (last_heapinfo, last_state_size, PROT_READ | PROT_WRITE); | ||
| 411 | |||
| 412 | last_state_size = _heaplimit * sizeof *_heapinfo; | ||
| 413 | last_heapinfo = _heapinfo; | ||
| 414 | |||
| 415 | if (protect_p != state_protected_p) | ||
| 416 | { | ||
| 417 | state_protected_p = protect_p; | ||
| 418 | if (mprotect (_heapinfo, last_state_size, | ||
| 419 | protect_p ? PROT_READ : PROT_READ | PROT_WRITE) != 0) | ||
| 420 | abort (); | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | #define PROTECT_MALLOC_STATE(PROT) protect_malloc_state(PROT) | ||
| 425 | |||
| 426 | #else | ||
| 427 | #define PROTECT_MALLOC_STATE(PROT) /* empty */ | ||
| 428 | #endif | ||
| 429 | |||
| 383 | 430 | ||
| 384 | /* Aligned allocation. */ | 431 | /* Aligned allocation. */ |
| 385 | static __ptr_t align PP ((__malloc_size_t)); | 432 | static __ptr_t align PP ((__malloc_size_t)); |
| @@ -492,6 +539,7 @@ __malloc_initialize () | |||
| 492 | register_heapinfo (); | 539 | register_heapinfo (); |
| 493 | 540 | ||
| 494 | __malloc_initialized = 1; | 541 | __malloc_initialized = 1; |
| 542 | PROTECT_MALLOC_STATE (1); | ||
| 495 | return 1; | 543 | return 1; |
| 496 | } | 544 | } |
| 497 | 545 | ||
| @@ -516,6 +564,8 @@ morecore (size) | |||
| 516 | if (result == NULL) | 564 | if (result == NULL) |
| 517 | return NULL; | 565 | return NULL; |
| 518 | 566 | ||
| 567 | PROTECT_MALLOC_STATE (0); | ||
| 568 | |||
| 519 | /* Check if we need to grow the info table. */ | 569 | /* Check if we need to grow the info table. */ |
| 520 | if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) | 570 | if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) |
| 521 | { | 571 | { |
| @@ -599,6 +649,7 @@ morecore (size) | |||
| 599 | it can relocate or resize the info table. */ | 649 | it can relocate or resize the info table. */ |
| 600 | _heaplimit = 0; | 650 | _heaplimit = 0; |
| 601 | _free_internal (oldinfo); | 651 | _free_internal (oldinfo); |
| 652 | PROTECT_MALLOC_STATE (0); | ||
| 602 | 653 | ||
| 603 | /* The new heap limit includes the new table just allocated. */ | 654 | /* The new heap limit includes the new table just allocated. */ |
| 604 | _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); | 655 | _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); |
| @@ -632,6 +683,8 @@ _malloc_internal (size) | |||
| 632 | return NULL; | 683 | return NULL; |
| 633 | #endif | 684 | #endif |
| 634 | 685 | ||
| 686 | PROTECT_MALLOC_STATE (0); | ||
| 687 | |||
| 635 | if (size < sizeof (struct list)) | 688 | if (size < sizeof (struct list)) |
| 636 | size = sizeof (struct list); | 689 | size = sizeof (struct list); |
| 637 | 690 | ||
| @@ -680,11 +733,15 @@ _malloc_internal (size) | |||
| 680 | and break it into fragments, returning the first. */ | 733 | and break it into fragments, returning the first. */ |
| 681 | #ifdef GC_MALLOC_CHECK | 734 | #ifdef GC_MALLOC_CHECK |
| 682 | result = _malloc_internal (BLOCKSIZE); | 735 | result = _malloc_internal (BLOCKSIZE); |
| 736 | PROTECT_MALLOC_STATE (0); | ||
| 683 | #else | 737 | #else |
| 684 | result = malloc (BLOCKSIZE); | 738 | result = malloc (BLOCKSIZE); |
| 685 | #endif | 739 | #endif |
| 686 | if (result == NULL) | 740 | if (result == NULL) |
| 687 | return NULL; | 741 | { |
| 742 | PROTECT_MALLOC_STATE (1); | ||
| 743 | return NULL; | ||
| 744 | } | ||
| 688 | 745 | ||
| 689 | /* Link all fragments but the first into the free list. */ | 746 | /* Link all fragments but the first into the free list. */ |
| 690 | next = (struct list *) ((char *) result + (1 << log)); | 747 | next = (struct list *) ((char *) result + (1 << log)); |
| @@ -803,6 +860,7 @@ _malloc_internal (size) | |||
| 803 | _heapinfo[block + blocks].busy.info.size = -blocks; | 860 | _heapinfo[block + blocks].busy.info.size = -blocks; |
| 804 | } | 861 | } |
| 805 | 862 | ||
| 863 | PROTECT_MALLOC_STATE (1); | ||
| 806 | return result; | 864 | return result; |
| 807 | } | 865 | } |
| 808 | 866 | ||
| @@ -913,6 +971,8 @@ _free_internal (ptr) | |||
| 913 | if (ptr == NULL) | 971 | if (ptr == NULL) |
| 914 | return; | 972 | return; |
| 915 | 973 | ||
| 974 | PROTECT_MALLOC_STATE (0); | ||
| 975 | |||
| 916 | for (l = _aligned_blocks; l != NULL; l = l->next) | 976 | for (l = _aligned_blocks; l != NULL; l = l->next) |
| 917 | if (l->aligned == ptr) | 977 | if (l->aligned == ptr) |
| 918 | { | 978 | { |
| @@ -1035,6 +1095,7 @@ _free_internal (ptr) | |||
| 1035 | /* Allocate new space for the info table and move its data. */ | 1095 | /* Allocate new space for the info table and move its data. */ |
| 1036 | newinfo = (malloc_info *) _malloc_internal (info_blocks | 1096 | newinfo = (malloc_info *) _malloc_internal (info_blocks |
| 1037 | * BLOCKSIZE); | 1097 | * BLOCKSIZE); |
| 1098 | PROTECT_MALLOC_STATE (0); | ||
| 1038 | memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); | 1099 | memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); |
| 1039 | _heapinfo = newinfo; | 1100 | _heapinfo = newinfo; |
| 1040 | 1101 | ||
| @@ -1133,6 +1194,8 @@ _free_internal (ptr) | |||
| 1133 | } | 1194 | } |
| 1134 | break; | 1195 | break; |
| 1135 | } | 1196 | } |
| 1197 | |||
| 1198 | PROTECT_MALLOC_STATE (1); | ||
| 1136 | } | 1199 | } |
| 1137 | 1200 | ||
| 1138 | /* Return memory to the heap. */ | 1201 | /* Return memory to the heap. */ |
| @@ -1296,6 +1359,8 @@ _realloc_internal (ptr, size) | |||
| 1296 | 1359 | ||
| 1297 | block = BLOCK (ptr); | 1360 | block = BLOCK (ptr); |
| 1298 | 1361 | ||
| 1362 | PROTECT_MALLOC_STATE (0); | ||
| 1363 | |||
| 1299 | type = _heapinfo[block].busy.type; | 1364 | type = _heapinfo[block].busy.type; |
| 1300 | switch (type) | 1365 | switch (type) |
| 1301 | { | 1366 | { |
| @@ -1344,6 +1409,7 @@ _realloc_internal (ptr, size) | |||
| 1344 | _heaplimit = 0; | 1409 | _heaplimit = 0; |
| 1345 | _free_internal (ptr); | 1410 | _free_internal (ptr); |
| 1346 | result = _malloc_internal (size); | 1411 | result = _malloc_internal (size); |
| 1412 | PROTECT_MALLOC_STATE (0); | ||
| 1347 | if (_heaplimit == 0) | 1413 | if (_heaplimit == 0) |
| 1348 | _heaplimit = oldlimit; | 1414 | _heaplimit = oldlimit; |
| 1349 | if (result == NULL) | 1415 | if (result == NULL) |
| @@ -1387,6 +1453,7 @@ _realloc_internal (ptr, size) | |||
| 1387 | break; | 1453 | break; |
| 1388 | } | 1454 | } |
| 1389 | 1455 | ||
| 1456 | PROTECT_MALLOC_STATE (1); | ||
| 1390 | return result; | 1457 | return result; |
| 1391 | } | 1458 | } |
| 1392 | 1459 | ||