diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexmacosx.c | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/src/unexmacosx.c b/src/unexmacosx.c index 1f2b4c96620..fc369eab7cd 100644 --- a/src/unexmacosx.c +++ b/src/unexmacosx.c | |||
| @@ -105,6 +105,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 105 | #include <objc/malloc.h> | 105 | #include <objc/malloc.h> |
| 106 | #endif | 106 | #endif |
| 107 | 107 | ||
| 108 | #include <assert.h> | ||
| 109 | |||
| 108 | 110 | ||
| 109 | #define VERBOSE 1 | 111 | #define VERBOSE 1 |
| 110 | 112 | ||
| @@ -998,6 +1000,23 @@ unexec_init_emacs_zone () | |||
| 998 | malloc_set_zone_name (emacs_zone, "EmacsZone"); | 1000 | malloc_set_zone_name (emacs_zone, "EmacsZone"); |
| 999 | } | 1001 | } |
| 1000 | 1002 | ||
| 1003 | #ifndef MACOSX_MALLOC_MULT16 | ||
| 1004 | #define MACOSX_MALLOC_MULT16 1 | ||
| 1005 | #endif | ||
| 1006 | |||
| 1007 | typedef struct unexec_malloc_header { | ||
| 1008 | union { | ||
| 1009 | char c[8]; | ||
| 1010 | size_t size; | ||
| 1011 | } u; | ||
| 1012 | } unexec_malloc_header_t; | ||
| 1013 | |||
| 1014 | #if MACOSX_MALLOC_MULT16 | ||
| 1015 | |||
| 1016 | #define ptr_in_unexec_regions(p) ((((vm_address_t) (p)) & 8) != 0) | ||
| 1017 | |||
| 1018 | #else | ||
| 1019 | |||
| 1001 | int | 1020 | int |
| 1002 | ptr_in_unexec_regions (void *ptr) | 1021 | ptr_in_unexec_regions (void *ptr) |
| 1003 | { | 1022 | { |
| @@ -1011,36 +1030,75 @@ ptr_in_unexec_regions (void *ptr) | |||
| 1011 | return 0; | 1030 | return 0; |
| 1012 | } | 1031 | } |
| 1013 | 1032 | ||
| 1033 | #endif | ||
| 1034 | |||
| 1014 | void * | 1035 | void * |
| 1015 | unexec_malloc (size_t size) | 1036 | unexec_malloc (size_t size) |
| 1016 | { | 1037 | { |
| 1017 | if (in_dumped_exec) | 1038 | if (in_dumped_exec) |
| 1018 | return malloc (size); | 1039 | { |
| 1040 | void *p; | ||
| 1041 | |||
| 1042 | p = malloc (size); | ||
| 1043 | #if MACOSX_MALLOC_MULT16 | ||
| 1044 | assert (((vm_address_t) p % 16) == 0); | ||
| 1045 | #endif | ||
| 1046 | return p; | ||
| 1047 | } | ||
| 1019 | else | 1048 | else |
| 1020 | return malloc_zone_malloc (emacs_zone, size); | 1049 | { |
| 1050 | unexec_malloc_header_t *ptr; | ||
| 1051 | |||
| 1052 | ptr = (unexec_malloc_header_t *) | ||
| 1053 | malloc_zone_malloc (emacs_zone, size + sizeof (unexec_malloc_header_t)); | ||
| 1054 | ptr->u.size = size; | ||
| 1055 | ptr++; | ||
| 1056 | #if MACOSX_MALLOC_MULT16 | ||
| 1057 | assert (((vm_address_t) ptr % 16) == 8); | ||
| 1058 | #endif | ||
| 1059 | return (void *) ptr; | ||
| 1060 | } | ||
| 1021 | } | 1061 | } |
| 1022 | 1062 | ||
| 1023 | void * | 1063 | void * |
| 1024 | unexec_realloc (void *old_ptr, size_t new_size) | 1064 | unexec_realloc (void *old_ptr, size_t new_size) |
| 1025 | { | 1065 | { |
| 1026 | if (in_dumped_exec) | 1066 | if (in_dumped_exec) |
| 1027 | if (ptr_in_unexec_regions (old_ptr)) | 1067 | { |
| 1028 | { | 1068 | void *p; |
| 1029 | char *p = malloc (new_size); | 1069 | |
| 1030 | /* 2002-04-15 T. Ikegami <ikegami@adam.uprr.pr>. The original | 1070 | if (ptr_in_unexec_regions (old_ptr)) |
| 1031 | code to get size failed to reallocate read_buffer | 1071 | { |
| 1032 | (lread.c). */ | 1072 | p = (size_t *) malloc (new_size); |
| 1033 | int old_size = malloc_default_zone()->size (emacs_zone, old_ptr); | 1073 | size_t old_size = ((unexec_malloc_header_t *) old_ptr)[-1].u.size; |
| 1034 | int size = new_size > old_size ? old_size : new_size; | 1074 | size_t size = new_size > old_size ? old_size : new_size; |
| 1035 | 1075 | ||
| 1036 | if (size) | 1076 | if (size) |
| 1037 | memcpy (p, old_ptr, size); | 1077 | memcpy (p, old_ptr, size); |
| 1038 | return p; | 1078 | } |
| 1039 | } | 1079 | else |
| 1040 | else | 1080 | { |
| 1041 | return realloc (old_ptr, new_size); | 1081 | p = realloc (old_ptr, new_size); |
| 1082 | } | ||
| 1083 | #if MACOSX_MALLOC_MULT16 | ||
| 1084 | assert (((vm_address_t) p % 16) == 0); | ||
| 1085 | #endif | ||
| 1086 | return p; | ||
| 1087 | } | ||
| 1042 | else | 1088 | else |
| 1043 | return malloc_zone_realloc (emacs_zone, old_ptr, new_size); | 1089 | { |
| 1090 | unexec_malloc_header_t *ptr; | ||
| 1091 | |||
| 1092 | ptr = (unexec_malloc_header_t *) | ||
| 1093 | malloc_zone_realloc (emacs_zone, (unexec_malloc_header_t *) old_ptr - 1, | ||
| 1094 | new_size + sizeof (unexec_malloc_header_t)); | ||
| 1095 | ptr->u.size = new_size; | ||
| 1096 | ptr++; | ||
| 1097 | #if MACOSX_MALLOC_MULT16 | ||
| 1098 | assert (((vm_address_t) ptr % 16) == 8); | ||
| 1099 | #endif | ||
| 1100 | return (void *) ptr; | ||
| 1101 | } | ||
| 1044 | } | 1102 | } |
| 1045 | 1103 | ||
| 1046 | void | 1104 | void |
| @@ -1052,7 +1110,7 @@ unexec_free (void *ptr) | |||
| 1052 | free (ptr); | 1110 | free (ptr); |
| 1053 | } | 1111 | } |
| 1054 | else | 1112 | else |
| 1055 | malloc_zone_free (emacs_zone, ptr); | 1113 | malloc_zone_free (emacs_zone, (unexec_malloc_header_t *) ptr - 1); |
| 1056 | } | 1114 | } |
| 1057 | 1115 | ||
| 1058 | /* arch-tag: 1a784f7b-a184-4c4f-9544-da8619593d72 | 1116 | /* arch-tag: 1a784f7b-a184-4c4f-9544-da8619593d72 |