diff options
| author | Jussi Lahdenniemi | 2016-01-16 11:11:12 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-01-16 11:11:12 +0200 |
| commit | 15c23aaf8368215613b0ffd02fe3bb742935f12e (patch) | |
| tree | 49ef2d902791b43feff3cecaaa5b82f4ccb3d6b5 /src | |
| parent | 39afa422ad0b3cef00292e260d424b7cd589b90d (diff) | |
| download | emacs-15c23aaf8368215613b0ffd02fe3bb742935f12e.tar.gz emacs-15c23aaf8368215613b0ffd02fe3bb742935f12e.zip | |
Ensure 8-byte aligned memory allocation on MS-Windows 9X
* src/w32heap.c (init_heap): Redirect malloc, realloc, and free to
special functions on Windows 9X. Refuse to dump Emacs on Windows 9X.
(malloc_after_dump_9x, realloc_after_dump_9x)
(free_after_dump_9x): New functions. (Bug#22379) See also
http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg00852.html
for more details about the original problem.
* nt/inc/ms-w32.h (malloc_after_dump_9x, realloc_after_dump_9x)
(free_after_dump_9x): Add prototypes.
Copyright-paperwork-exempt: yes
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32heap.c | 89 |
1 files changed, 83 insertions, 6 deletions
diff --git a/src/w32heap.c b/src/w32heap.c index 54646bfbe3e..3d1c5ff50a2 100644 --- a/src/w32heap.c +++ b/src/w32heap.c | |||
| @@ -258,9 +258,18 @@ init_heap (void) | |||
| 258 | } | 258 | } |
| 259 | #endif | 259 | #endif |
| 260 | 260 | ||
| 261 | the_malloc_fn = malloc_after_dump; | 261 | if (os_subtype == OS_9X) |
| 262 | the_realloc_fn = realloc_after_dump; | 262 | { |
| 263 | the_free_fn = free_after_dump; | 263 | the_malloc_fn = malloc_after_dump_9x; |
| 264 | the_realloc_fn = realloc_after_dump_9x; | ||
| 265 | the_free_fn = free_after_dump_9x; | ||
| 266 | } | ||
| 267 | else | ||
| 268 | { | ||
| 269 | the_malloc_fn = malloc_after_dump; | ||
| 270 | the_realloc_fn = realloc_after_dump; | ||
| 271 | the_free_fn = free_after_dump; | ||
| 272 | } | ||
| 264 | } | 273 | } |
| 265 | else | 274 | else |
| 266 | { | 275 | { |
| @@ -291,9 +300,18 @@ init_heap (void) | |||
| 291 | exit (-1); | 300 | exit (-1); |
| 292 | } | 301 | } |
| 293 | heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, ¶ms); | 302 | heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, ¶ms); |
| 294 | the_malloc_fn = malloc_before_dump; | 303 | |
| 295 | the_realloc_fn = realloc_before_dump; | 304 | if (os_subtype == OS_9X) |
| 296 | the_free_fn = free_before_dump; | 305 | { |
| 306 | fprintf (stderr, "Cannot dump Emacs on Windows 9X; exiting.\n"); | ||
| 307 | exit (-1); | ||
| 308 | } | ||
| 309 | else | ||
| 310 | { | ||
| 311 | the_malloc_fn = malloc_before_dump; | ||
| 312 | the_realloc_fn = realloc_before_dump; | ||
| 313 | the_free_fn = free_before_dump; | ||
| 314 | } | ||
| 297 | } | 315 | } |
| 298 | 316 | ||
| 299 | /* Update system version information to match current system. */ | 317 | /* Update system version information to match current system. */ |
| @@ -504,6 +522,65 @@ free_before_dump (void *ptr) | |||
| 504 | } | 522 | } |
| 505 | } | 523 | } |
| 506 | 524 | ||
| 525 | /* On Windows 9X, HeapAlloc may return pointers that are not aligned | ||
| 526 | on 8-byte boundary, alignment which is required by the Lisp memory | ||
| 527 | management. To circumvent this problem, manually enforce alignment | ||
| 528 | on Windows 9X. */ | ||
| 529 | |||
| 530 | void * | ||
| 531 | malloc_after_dump_9x (size_t size) | ||
| 532 | { | ||
| 533 | void *p = malloc_after_dump (size + 8); | ||
| 534 | void *pa; | ||
| 535 | if (p == NULL) | ||
| 536 | return p; | ||
| 537 | pa = (void*)(((intptr_t)p + 8) & ~7); | ||
| 538 | *((void**)pa-1) = p; | ||
| 539 | return pa; | ||
| 540 | } | ||
| 541 | |||
| 542 | void * | ||
| 543 | realloc_after_dump_9x (void *ptr, size_t size) | ||
| 544 | { | ||
| 545 | if (FREEABLE_P (ptr)) | ||
| 546 | { | ||
| 547 | void *po = *((void**)ptr-1); | ||
| 548 | void *p; | ||
| 549 | void *pa; | ||
| 550 | p = realloc_after_dump (po, size + 8); | ||
| 551 | if (p == NULL) | ||
| 552 | return p; | ||
| 553 | pa = (void*)(((intptr_t)p + 8) & ~7); | ||
| 554 | if (ptr != NULL && | ||
| 555 | (char*)pa - (char*)p != (char*)ptr - (char*)po) | ||
| 556 | { | ||
| 557 | /* Handle the case where alignment in pre-realloc and | ||
| 558 | post-realloc blocks does not match. */ | ||
| 559 | MoveMemory (pa, (void*)((char*)p + ((char*)ptr - (char*)po)), size); | ||
| 560 | } | ||
| 561 | *((void**)pa-1) = p; | ||
| 562 | return pa; | ||
| 563 | } | ||
| 564 | else | ||
| 565 | { | ||
| 566 | /* Non-freeable pointers have no alignment-enforcing header | ||
| 567 | (since dumping is not allowed on Windows 9X). */ | ||
| 568 | void* p = malloc_after_dump_9x (size); | ||
| 569 | if (p != NULL) | ||
| 570 | CopyMemory (p, ptr, size); | ||
| 571 | return p; | ||
| 572 | } | ||
| 573 | } | ||
| 574 | |||
| 575 | void | ||
| 576 | free_after_dump_9x (void *ptr) | ||
| 577 | { | ||
| 578 | if (FREEABLE_P (ptr)) | ||
| 579 | { | ||
| 580 | free_after_dump (*((void**)ptr-1)); | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 507 | #ifdef ENABLE_CHECKING | 584 | #ifdef ENABLE_CHECKING |
| 508 | void | 585 | void |
| 509 | report_temacs_memory_usage (void) | 586 | report_temacs_memory_usage (void) |