diff options
author | Jussi Lahdenniemi <jussi@aprikoodi.fi> | 2016-01-16 11:11:12 +0200 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2016-01-16 11:11:12 +0200 |
commit | 15c23aaf8368215613b0ffd02fe3bb742935f12e (patch) | |
tree | 49ef2d902791b43feff3cecaaa5b82f4ccb3d6b5 | |
parent | 39afa422ad0b3cef00292e260d424b7cd589b90d (diff) |
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
-rw-r--r-- | nt/inc/ms-w32.h | 4 | ||||
-rw-r--r-- | src/w32heap.c | 89 |
2 files changed, 87 insertions, 6 deletions
diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index cdbfac03c6..a37510e745 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -457,6 +457,10 @@ extern void *malloc_after_dump(size_t); extern void *realloc_after_dump(void *, size_t); extern void free_after_dump(void *); +extern void *malloc_after_dump_9x(size_t); +extern void *realloc_after_dump_9x(void *, size_t); +extern void free_after_dump_9x(void *); + extern malloc_fn the_malloc_fn; extern realloc_fn the_realloc_fn; extern free_fn the_free_fn; diff --git a/src/w32heap.c b/src/w32heap.c index 54646bfbe3..3d1c5ff50a 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -258,9 +258,18 @@ init_heap (void) } #endif - the_malloc_fn = malloc_after_dump; - the_realloc_fn = realloc_after_dump; - the_free_fn = free_after_dump; + if (os_subtype == OS_9X) + { + the_malloc_fn = malloc_after_dump_9x; + the_realloc_fn = realloc_after_dump_9x; + the_free_fn = free_after_dump_9x; + } + else + { + the_malloc_fn = malloc_after_dump; + the_realloc_fn = realloc_after_dump; + the_free_fn = free_after_dump; + } } else { @@ -291,9 +300,18 @@ init_heap (void) exit (-1); } heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, ¶ms); - the_malloc_fn = malloc_before_dump; - the_realloc_fn = realloc_before_dump; - the_free_fn = free_before_dump; + + if (os_subtype == OS_9X) + { + fprintf (stderr, "Cannot dump Emacs on Windows 9X; exiting.\n"); + exit (-1); + } + else + { + the_malloc_fn = malloc_before_dump; + the_realloc_fn = realloc_before_dump; + the_free_fn = free_before_dump; + } } /* Update system version information to match current system. */ @@ -504,6 +522,65 @@ free_before_dump (void *ptr) } } +/* On Windows 9X, HeapAlloc may return pointers that are not aligned + on 8-byte boundary, alignment which is required by the Lisp memory + management. To circumvent this problem, manually enforce alignment + on Windows 9X. */ + +void * +malloc_after_dump_9x (size_t size) +{ + void *p = malloc_after_dump (size + 8); + void *pa; + if (p == NULL) + return p; + pa = (void*)(((intptr_t)p + 8) & ~7); + *((void**)pa-1) = p; + return pa; +} + +void * +realloc_after_dump_9x (void *ptr, size_t size) +{ + if (FREEABLE_P (ptr)) + { + void *po = *((void**)ptr-1); + void *p; + void *pa; + p = realloc_after_dump (po, size + 8); + if (p == NULL) + return p; + pa = (void*)(((intptr_t)p + 8) & ~7); + if (ptr != NULL && + (char*)pa - (char*)p != (char*)ptr - (char*)po) + { + /* Handle the case where alignment in pre-realloc and + post-realloc blocks does not match. */ + MoveMemory (pa, (void*)((char*)p + ((char*)ptr - (char*)po)), size); + } + *((void**)pa-1) = p; + return pa; + } + else + { + /* Non-freeable pointers have no alignment-enforcing header + (since dumping is not allowed on Windows 9X). */ + void* p = malloc_after_dump_9x (size); + if (p != NULL) + CopyMemory (p, ptr, size); + return p; + } +} + +void +free_after_dump_9x (void *ptr) +{ + if (FREEABLE_P (ptr)) + { + free_after_dump (*((void**)ptr-1)); + } +} + #ifdef ENABLE_CHECKING void report_temacs_memory_usage (void) |