Mercurial > hg > xemacs-beta
comparison src/dumper.c @ 2551:9f70af3ac939
[xemacs-hg @ 2005-02-03 16:14:02 by james]
Commit Olivier Galibert's dumper updates for bignums and use them.
See xemacs-patches message with ID <ps8y685c6p.fsf@diannao.ittc.ku.edu>.
author | james |
---|---|
date | Thu, 03 Feb 2005 16:14:08 +0000 |
parents | 3d8143fc88e1 |
children | b880fa9b5d8a |
comparison
equal
deleted
inserted
replaced
2550:317f30471f4e | 2551:9f70af3ac939 |
---|---|
1 /* Portable data dumper for XEmacs. | 1 /* Portable data dumper for XEmacs. |
2 Copyright (C) 1999-2000 Olivier Galibert | 2 Copyright (C) 1999-2000,2004 Olivier Galibert |
3 Copyright (C) 2001 Martin Buchholz | 3 Copyright (C) 2001 Martin Buchholz |
4 Copyright (C) 2001, 2002, 2003, 2004 Ben Wing. | 4 Copyright (C) 2001, 2002, 2003, 2004 Ben Wing. |
5 | 5 |
6 This file is part of XEmacs. | 6 This file is part of XEmacs. |
7 | 7 |
76 Dynarr_declare (pdump_root_block_ptr); | 76 Dynarr_declare (pdump_root_block_ptr); |
77 } pdump_root_block_ptr_dynarr; | 77 } pdump_root_block_ptr_dynarr; |
78 | 78 |
79 typedef struct | 79 typedef struct |
80 { | 80 { |
81 const void *object; | |
82 void *data; | |
83 Bytecount size; | |
84 EMACS_INT offset; | |
85 EMACS_INT dest_offset; | |
86 EMACS_INT save_offset; | |
87 const struct opaque_convert_functions *fcts; | |
88 } pdump_cv_data_info; | |
89 | |
90 typedef struct | |
91 { | |
92 Dynarr_declare (pdump_cv_data_info); | |
93 } pdump_cv_data_info_dynarr; | |
94 | |
95 typedef struct | |
96 { | |
97 EMACS_INT dest_offset; | |
98 EMACS_INT save_offset; | |
99 Bytecount size; | |
100 } pdump_cv_data_dump_info; | |
101 | |
102 typedef struct | |
103 { | |
104 const void *object; | |
105 void *data; | |
106 Bytecount size; | |
107 EMACS_INT index; | |
108 EMACS_INT save_offset; | |
109 const struct opaque_convert_functions *fcts; | |
110 } pdump_cv_ptr_info; | |
111 | |
112 typedef struct | |
113 { | |
114 Dynarr_declare (pdump_cv_ptr_info); | |
115 } pdump_cv_ptr_info_dynarr; | |
116 | |
117 typedef struct | |
118 { | |
119 EMACS_INT save_offset; | |
120 Bytecount size; | |
121 } pdump_cv_ptr_dump_info; | |
122 | |
123 typedef struct | |
124 { | |
125 EMACS_INT save_offset; | |
126 Bytecount size; | |
127 void *adr; | |
128 } pdump_cv_ptr_load_info; | |
129 | |
130 typedef struct | |
131 { | |
81 Lisp_Object *address; | 132 Lisp_Object *address; |
82 Lisp_Object value; | 133 Lisp_Object value; |
83 } pdump_static_Lisp_Object; | 134 } pdump_static_Lisp_Object; |
84 | 135 |
85 typedef struct | 136 typedef struct |
90 | 141 |
91 static pdump_root_block_dynarr *pdump_root_blocks; | 142 static pdump_root_block_dynarr *pdump_root_blocks; |
92 static pdump_root_block_ptr_dynarr *pdump_root_block_ptrs; | 143 static pdump_root_block_ptr_dynarr *pdump_root_block_ptrs; |
93 static Lisp_Object_ptr_dynarr *pdump_root_lisp_objects; | 144 static Lisp_Object_ptr_dynarr *pdump_root_lisp_objects; |
94 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; | 145 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; |
146 static pdump_cv_data_info_dynarr *pdump_cv_data; | |
147 static pdump_cv_ptr_info_dynarr *pdump_cv_ptr; | |
95 | 148 |
96 /* Mark SIZE bytes at non-heap address BLOCKADDR for dumping, described | 149 /* Mark SIZE bytes at non-heap address BLOCKADDR for dumping, described |
97 by DESC. Called by outside callers during XEmacs initialization. */ | 150 by DESC. Called by outside callers during XEmacs initialization. */ |
98 | 151 |
99 void | 152 void |
208 | 261 |
209 | 262 |
210 /* The structure of the dump file looks like this: | 263 /* The structure of the dump file looks like this: |
211 0 - header | 264 0 - header |
212 - dumped objects | 265 - dumped objects |
213 stab_offset - nb_root_block_ptrs*struct(void *, adr) | 266 stab_offset - nb_cv_data*struct(dest, adr) for in-object externally |
267 represented data | |
268 - nb_cv_ptr*(adr) for pointed-to externally represented data | |
269 - nb_root_block_ptrs*struct(void *, adr) | |
214 for global pointers to heap blocks | 270 for global pointers to heap blocks |
215 - nb_root_blocks*struct(void *, size, info) for global | 271 - nb_root_blocks*struct(void *, size, info) for global |
216 data-segment blocks to restore | 272 data-segment blocks to restore |
217 - relocation table | 273 - relocation table |
218 - root lisp object address/value couples with the count | 274 - root lisp object address/value couples with the count |
229 unsigned int id; | 285 unsigned int id; |
230 EMACS_UINT stab_offset; | 286 EMACS_UINT stab_offset; |
231 EMACS_UINT reloc_address; | 287 EMACS_UINT reloc_address; |
232 int nb_root_block_ptrs; | 288 int nb_root_block_ptrs; |
233 int nb_root_blocks; | 289 int nb_root_blocks; |
290 int nb_cv_data; | |
291 int nb_cv_ptr; | |
234 } pdump_header; | 292 } pdump_header; |
235 | 293 |
236 Rawbyte *pdump_start; | 294 Rawbyte *pdump_start; |
237 Rawbyte *pdump_end; | 295 Rawbyte *pdump_end; |
238 static Bytecount pdump_length; | 296 static Bytecount pdump_length; |
297 | |
298 static pdump_cv_data_dump_info *pdump_loaded_cv_data; | |
299 static pdump_cv_ptr_load_info *pdump_loaded_cv_ptr; | |
239 | 300 |
240 #ifdef WIN32_NATIVE | 301 #ifdef WIN32_NATIVE |
241 /* Handle for the dump file */ | 302 /* Handle for the dump file */ |
242 static HANDLE pdump_hFile = INVALID_HANDLE_VALUE; | 303 static HANDLE pdump_hFile = INVALID_HANDLE_VALUE; |
243 /* Handle for the file mapping object for the dump file */ | 304 /* Handle for the file mapping object for the dump file */ |
445 pdump_desc_table.list[pdump_desc_table.count].list.align = ALIGNOF (max_align_t); | 506 pdump_desc_table.list[pdump_desc_table.count].list.align = ALIGNOF (max_align_t); |
446 pdump_desc_table.list[pdump_desc_table.count].list.count = 0; | 507 pdump_desc_table.list[pdump_desc_table.count].list.count = 0; |
447 pdump_desc_table.list[pdump_desc_table.count].desc = desc; | 508 pdump_desc_table.list[pdump_desc_table.count].desc = desc; |
448 | 509 |
449 return &pdump_desc_table.list[pdump_desc_table.count++].list; | 510 return &pdump_desc_table.list[pdump_desc_table.count++].list; |
511 } | |
512 | |
513 static pdump_cv_ptr_info * | |
514 pdump_find_in_cv_ptr_dynarr(const void *object) | |
515 { | |
516 int i; | |
517 for (i = 0; i < Dynarr_length (pdump_cv_ptr); i++) | |
518 if (Dynarr_at (pdump_cv_ptr, i).object == object) | |
519 return Dynarr_atp (pdump_cv_ptr, i); | |
520 return 0; | |
450 } | 521 } |
451 | 522 |
452 static struct | 523 static struct |
453 { | 524 { |
454 struct lrecord_header *obj; | 525 struct lrecord_header *obj; |
606 case XD_BLOCK_PTR: | 677 case XD_BLOCK_PTR: |
607 { | 678 { |
608 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | 679 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
609 data); | 680 data); |
610 const struct sized_memory_description *sdesc = | 681 const struct sized_memory_description *sdesc = |
611 lispdesc_indirect_description (data, desc1->data2); | 682 lispdesc_indirect_description (data, desc1->data2.descr); |
612 const Rawbyte *dobj = *(const Rawbyte **)rdata; | 683 const Rawbyte *dobj = *(const Rawbyte **)rdata; |
613 if (dobj) | 684 if (dobj) |
614 pdump_register_block (dobj, sdesc->size, sdesc->description, | 685 pdump_register_block (dobj, sdesc->size, sdesc->description, |
615 count); | 686 count); |
616 break; | 687 break; |
618 case XD_BLOCK_ARRAY: | 689 case XD_BLOCK_ARRAY: |
619 { | 690 { |
620 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | 691 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
621 data); | 692 data); |
622 const struct sized_memory_description *sdesc = | 693 const struct sized_memory_description *sdesc = |
623 lispdesc_indirect_description (data, desc1->data2); | 694 lispdesc_indirect_description (data, desc1->data2.descr); |
624 | 695 |
625 pdump_register_block_contents (rdata, sdesc->size, | 696 pdump_register_block_contents (rdata, sdesc->size, |
626 sdesc->description, count); | 697 sdesc->description, count); |
627 break; | 698 break; |
628 } | 699 } |
630 case XD_UNION_DYNAMIC_SIZE: | 701 case XD_UNION_DYNAMIC_SIZE: |
631 desc1 = lispdesc_process_xd_union (desc1, desc, data); | 702 desc1 = lispdesc_process_xd_union (desc1, desc, data); |
632 if (desc1) | 703 if (desc1) |
633 goto union_switcheroo; | 704 goto union_switcheroo; |
634 break; | 705 break; |
706 case XD_OPAQUE_PTR_CONVERTIBLE: | |
707 { | |
708 pdump_cv_ptr_info info; | |
709 info.object = *(void **)rdata; | |
710 info.fcts = desc1->data2.funcs; | |
711 if (!pdump_find_in_cv_ptr_dynarr (info.object)) | |
712 { | |
713 info.fcts->convert(info.object, &info.data, &info.size); | |
714 Dynarr_add (pdump_cv_ptr, info); | |
715 } | |
716 break; | |
717 } | |
718 case XD_OPAQUE_DATA_CONVERTIBLE: | |
719 { | |
720 pdump_cv_data_info info; | |
721 info.object = data; | |
722 info.offset = offset; | |
723 info.fcts = desc1->data2.funcs; | |
724 | |
725 info.fcts->convert(rdata, &info.data, &info.size); | |
726 Dynarr_add (pdump_cv_data, info); | |
727 break; | |
728 } | |
635 | 729 |
636 default: | 730 default: |
637 pdump_unsupported_dump_type (desc1->type, 1); | 731 pdump_unsupported_dump_type (desc1->type, 1); |
638 } | 732 } |
639 } | 733 } |
723 pdump_add_block (pdump_get_block_list (desc), data, | 817 pdump_add_block (pdump_get_block_list (desc), data, |
724 lispdesc_block_size_1 (data, size, desc), count); | 818 lispdesc_block_size_1 (data, size, desc), count); |
725 pdump_register_block_contents (data, size, desc, count); | 819 pdump_register_block_contents (data, size, desc, count); |
726 } | 820 } |
727 } | 821 } |
822 | |
728 | 823 |
729 /* Store the already-calculated new pointer offsets for all pointers in the | 824 /* Store the already-calculated new pointer offsets for all pointers in the |
730 COUNT contiguous blocks of memory, each described by DESC and of size | 825 COUNT contiguous blocks of memory, each described by DESC and of size |
731 SIZE, whose original is located at ORIG_DATA and the modifiable copy at | 826 SIZE, whose original is located at ORIG_DATA and the modifiable copy at |
732 DATA. We examine the description to figure out where the pointers are, | 827 DATA. We examine the description to figure out where the pointers are, |
874 case XD_BLOCK_ARRAY: | 969 case XD_BLOCK_ARRAY: |
875 { | 970 { |
876 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, | 971 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
877 orig_data); | 972 orig_data); |
878 const struct sized_memory_description *sdesc = | 973 const struct sized_memory_description *sdesc = |
879 lispdesc_indirect_description (orig_data, desc1->data2); | 974 lispdesc_indirect_description (orig_data, desc1->data2.descr); |
880 | 975 |
881 pdump_store_new_pointer_offsets | 976 pdump_store_new_pointer_offsets |
882 (num, rdata, | 977 (num, rdata, |
883 ((Rawbyte *) rdata - (Rawbyte *) data) + | 978 ((Rawbyte *) rdata - (Rawbyte *) data) + |
884 (Rawbyte *) orig_data, | 979 (Rawbyte *) orig_data, |
891 case XD_UNION: | 986 case XD_UNION: |
892 case XD_UNION_DYNAMIC_SIZE: | 987 case XD_UNION_DYNAMIC_SIZE: |
893 desc1 = lispdesc_process_xd_union (desc1, desc, orig_data); | 988 desc1 = lispdesc_process_xd_union (desc1, desc, orig_data); |
894 if (desc1) | 989 if (desc1) |
895 goto union_switcheroo; | 990 goto union_switcheroo; |
991 break; | |
992 | |
993 case XD_OPAQUE_PTR_CONVERTIBLE: | |
994 *(EMACS_INT *)rdata = pdump_find_in_cv_ptr_dynarr (*(void **)rdata)->index; | |
995 break; | |
996 | |
997 case XD_OPAQUE_DATA_CONVERTIBLE: | |
998 /* in-object, nothing to do */ | |
896 break; | 999 break; |
897 | 1000 |
898 default: | 1001 default: |
899 pdump_unsupported_dump_type (desc1->type, 0); | 1002 pdump_unsupported_dump_type (desc1->type, 0); |
900 } | 1003 } |
1013 { | 1116 { |
1014 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, | 1117 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
1015 data); | 1118 data); |
1016 int j; | 1119 int j; |
1017 const struct sized_memory_description *sdesc = | 1120 const struct sized_memory_description *sdesc = |
1018 lispdesc_indirect_description (data, desc1->data2); | 1121 lispdesc_indirect_description (data, desc1->data2.descr); |
1019 Bytecount size = lispdesc_block_size (rdata, sdesc); | 1122 Bytecount size = lispdesc_block_size (rdata, sdesc); |
1020 | 1123 |
1021 /* Note: We are recursing over data in the block itself */ | 1124 /* Note: We are recursing over data in the block itself */ |
1022 for (j = 0; j < num; j++) | 1125 for (j = 0; j < num; j++) |
1023 pdump_reloc_one ((Rawbyte *) rdata + j * size, delta, | 1126 pdump_reloc_one ((Rawbyte *) rdata + j * size, delta, |
1030 desc1 = lispdesc_process_xd_union (desc1, desc, data); | 1133 desc1 = lispdesc_process_xd_union (desc1, desc, data); |
1031 if (desc1) | 1134 if (desc1) |
1032 goto union_switcheroo; | 1135 goto union_switcheroo; |
1033 break; | 1136 break; |
1034 | 1137 |
1138 case XD_OPAQUE_PTR_CONVERTIBLE: | |
1139 { | |
1140 pdump_cv_ptr_load_info *p = pdump_loaded_cv_ptr + *(EMACS_INT *)rdata; | |
1141 if (!p->adr) | |
1142 p->adr = desc1->data2.funcs->deconvert(0, pdump_start + | |
1143 p->save_offset, p->size); | |
1144 *(void **)rdata = p->adr; | |
1145 break; | |
1146 } | |
1147 | |
1148 case XD_OPAQUE_DATA_CONVERTIBLE: | |
1149 { | |
1150 EMACS_INT dest_offset = (Rawbyte *)rdata - pdump_start; | |
1151 pdump_cv_data_dump_info *p; | |
1152 | |
1153 for(p = pdump_loaded_cv_data; p->dest_offset != dest_offset; p++); | |
1154 | |
1155 desc1->data2.funcs->deconvert(rdata, pdump_start + p->save_offset, | |
1156 p->size); | |
1157 break; | |
1158 } | |
1159 | |
1035 default: | 1160 default: |
1036 pdump_unsupported_dump_type (desc1->type, 0); | 1161 pdump_unsupported_dump_type (desc1->type, 0); |
1037 } | 1162 } |
1038 } | 1163 } |
1039 } | 1164 } |
1047 if (size > max_size) | 1172 if (size > max_size) |
1048 max_size = size; | 1173 max_size = size; |
1049 cur_offset += size; | 1174 cur_offset += size; |
1050 } | 1175 } |
1051 | 1176 |
1177 /* Write out to global file descriptor PDUMP_OUT the result of an | |
1178 external element. It's just opaque data. */ | |
1179 | |
1180 static void | |
1181 pdump_dump_cv_data (pdump_cv_data_info *elt) | |
1182 { | |
1183 retry_fwrite (elt->data, elt->size, 1, pdump_out); | |
1184 } | |
1185 | |
1186 static void | |
1187 pdump_dump_cv_ptr (pdump_cv_ptr_info *elt) | |
1188 { | |
1189 retry_fwrite (elt->data, elt->size, 1, pdump_out); | |
1190 } | |
1191 | |
1192 static void | |
1193 pdump_allocate_offset_cv_data (pdump_cv_data_info *elt) | |
1194 { | |
1195 elt->save_offset = cur_offset; | |
1196 if (elt->size>max_size) | |
1197 max_size = elt->size; | |
1198 cur_offset += elt->size; | |
1199 } | |
1200 | |
1201 static void | |
1202 pdump_allocate_offset_cv_ptr (pdump_cv_ptr_info *elt) | |
1203 { | |
1204 elt->save_offset = cur_offset; | |
1205 if (elt->size>max_size) | |
1206 max_size = elt->size; | |
1207 cur_offset += elt->size; | |
1208 } | |
1209 | |
1052 /* Traverse through all the heap blocks, once the "register" stage of | 1210 /* Traverse through all the heap blocks, once the "register" stage of |
1053 dumping has finished. To compress space as much as possible, we | 1211 dumping has finished. To compress space as much as possible, we |
1054 logically sort all blocks by alignment, hitting all blocks with | 1212 logically sort all blocks by alignment, hitting all blocks with |
1055 alignment == the maximum (which may be 8 bytes, for doubles), then | 1213 alignment == the maximum (which may be 8 bytes, for doubles), then |
1056 all blocks with the next lower alignment (4 bytes), etc. | 1214 all blocks with the next lower alignment (4 bytes), etc. |
1079 in both stage 2 and 3. | 1237 in both stage 2 and 3. |
1080 */ | 1238 */ |
1081 | 1239 |
1082 static void | 1240 static void |
1083 pdump_scan_by_alignment (void (*f)(pdump_block_list_elt *, | 1241 pdump_scan_by_alignment (void (*f)(pdump_block_list_elt *, |
1084 const struct memory_description *)) | 1242 const struct memory_description *), |
1243 void (*g)(pdump_cv_data_info *), | |
1244 void (*h)(pdump_cv_ptr_info *)) | |
1085 { | 1245 { |
1086 int align; | 1246 int align; |
1087 | 1247 |
1088 for (align = ALIGNOF (max_align_t); align; align>>=1) | 1248 for (align = ALIGNOF (max_align_t); align; align>>=1) |
1089 { | 1249 { |
1104 } | 1264 } |
1105 | 1265 |
1106 for (elt = pdump_opaque_data_list.first; elt; elt = elt->next) | 1266 for (elt = pdump_opaque_data_list.first; elt; elt = elt->next) |
1107 if (pdump_size_to_align (elt->size) == align) | 1267 if (pdump_size_to_align (elt->size) == align) |
1108 f (elt, 0); | 1268 f (elt, 0); |
1109 } | 1269 |
1270 for (i=0; i < Dynarr_length (pdump_cv_data); i++) | |
1271 if (pdump_size_to_align (Dynarr_atp (pdump_cv_data, i)->size) == align) | |
1272 g (Dynarr_atp (pdump_cv_data, i)); | |
1273 | |
1274 for (i=0; i < Dynarr_length (pdump_cv_ptr); i++) | |
1275 if (pdump_size_to_align (Dynarr_atp (pdump_cv_ptr, i)->size) == align) | |
1276 h (Dynarr_atp (pdump_cv_ptr, i)); | |
1277 } | |
1278 } | |
1279 | |
1280 static void | |
1281 pdump_dump_cv_data_info (void) | |
1282 { | |
1283 int i; | |
1284 Elemcount count = Dynarr_length (pdump_cv_data); | |
1285 pdump_cv_data_dump_info *data = alloca_array (pdump_cv_data_dump_info, count); | |
1286 for (i = 0; i < count; i++) | |
1287 { | |
1288 data[i].dest_offset = Dynarr_at (pdump_cv_data, i).dest_offset; | |
1289 data[i].save_offset = Dynarr_at (pdump_cv_data, i).save_offset; | |
1290 data[i].size = Dynarr_at (pdump_cv_data, i).size; | |
1291 } | |
1292 | |
1293 PDUMP_ALIGN_OUTPUT (pdump_cv_data_dump_info); | |
1294 retry_fwrite (data, sizeof (pdump_cv_data_dump_info), count, pdump_out); | |
1110 } | 1295 } |
1111 | 1296 |
1112 /* Dump out the root block pointers, part of stage 3 (the "WRITE" stage) of | 1297 /* Dump out the root block pointers, part of stage 3 (the "WRITE" stage) of |
1113 dumping. For each pointer we dump out a structure containing the | 1298 dumping. For each pointer we dump out a structure containing the |
1114 location of the pointer and its value, replaced by the appropriate | 1299 location of the pointer and its value, replaced by the appropriate |
1115 offset into the dumped data. */ | 1300 offset into the dumped data. */ |
1301 | |
1302 static void | |
1303 pdump_dump_cv_ptr_info (void) | |
1304 { | |
1305 int i; | |
1306 Elemcount count = Dynarr_length (pdump_cv_ptr); | |
1307 pdump_cv_ptr_dump_info *data = alloca_array (pdump_cv_ptr_dump_info, count); | |
1308 for (i = 0; i < count; i++) | |
1309 { | |
1310 data[i].save_offset = Dynarr_at (pdump_cv_ptr, i).save_offset; | |
1311 data[i].size = Dynarr_at (pdump_cv_ptr, i).size; | |
1312 } | |
1313 | |
1314 PDUMP_ALIGN_OUTPUT (pdump_cv_ptr_dump_info); | |
1315 retry_fwrite (data, sizeof (pdump_cv_ptr_dump_info), count, pdump_out); | |
1316 } | |
1116 | 1317 |
1117 static void | 1318 static void |
1118 pdump_dump_root_block_ptrs (void) | 1319 pdump_dump_root_block_ptrs (void) |
1119 { | 1320 { |
1120 int i; | 1321 int i; |
1434 pdump_opaque_data_list.first = 0; | 1635 pdump_opaque_data_list.first = 0; |
1435 pdump_opaque_data_list.align = ALIGNOF (max_align_t); | 1636 pdump_opaque_data_list.align = ALIGNOF (max_align_t); |
1436 pdump_opaque_data_list.count = 0; | 1637 pdump_opaque_data_list.count = 0; |
1437 pdump_depth = 0; | 1638 pdump_depth = 0; |
1438 | 1639 |
1640 pdump_cv_data = Dynarr_new2 (pdump_cv_data_info_dynarr, pdump_cv_data_info); | |
1641 pdump_cv_ptr = Dynarr_new2 (pdump_cv_ptr_info_dynarr, pdump_cv_ptr_info); | |
1642 | |
1439 /* (I) The "register" stage: Note all heap memory blocks to be relocated | 1643 /* (I) The "register" stage: Note all heap memory blocks to be relocated |
1440 */ | 1644 */ |
1441 | 1645 |
1442 /* Try various roots of accessibility: */ | 1646 /* Try various roots of accessibility: */ |
1443 | 1647 |
1493 memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); | 1697 memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); |
1494 header.id = dump_id; | 1698 header.id = dump_id; |
1495 header.reloc_address = 0; | 1699 header.reloc_address = 0; |
1496 header.nb_root_block_ptrs = Dynarr_length (pdump_root_block_ptrs); | 1700 header.nb_root_block_ptrs = Dynarr_length (pdump_root_block_ptrs); |
1497 header.nb_root_blocks = Dynarr_length (pdump_root_blocks); | 1701 header.nb_root_blocks = Dynarr_length (pdump_root_blocks); |
1702 header.nb_cv_data = Dynarr_length (pdump_cv_data); | |
1703 header.nb_cv_ptr = Dynarr_length (pdump_cv_ptr); | |
1498 | 1704 |
1499 cur_offset = MAX_ALIGN_SIZE (sizeof (header)); | 1705 cur_offset = MAX_ALIGN_SIZE (sizeof (header)); |
1500 max_size = 0; | 1706 max_size = 0; |
1501 | 1707 |
1502 /* (2) Traverse all heap blocks and compute their offsets; keep track | 1708 /* (2) Traverse all heap blocks and compute their offsets; keep track |
1503 of maximum block size seen */ | 1709 of maximum block size seen */ |
1504 pdump_scan_by_alignment (pdump_allocate_offset); | 1710 pdump_scan_by_alignment (pdump_allocate_offset, |
1711 pdump_allocate_offset_cv_data, | |
1712 pdump_allocate_offset_cv_ptr); | |
1505 cur_offset = MAX_ALIGN_SIZE (cur_offset); | 1713 cur_offset = MAX_ALIGN_SIZE (cur_offset); |
1506 header.stab_offset = cur_offset; | 1714 header.stab_offset = cur_offset; |
1507 | 1715 |
1508 /* (3) Update maximum size based on root (data-segment) blocks */ | 1716 /* (3) Update maximum size based on root (data-segment) blocks */ |
1509 for (i = 0; i < Dynarr_length (pdump_root_blocks); i++) | 1717 for (i = 0; i < Dynarr_length (pdump_root_blocks); i++) |
1535 build_string (EMACS_PROGNAME ".dmp")); | 1743 build_string (EMACS_PROGNAME ".dmp")); |
1536 | 1744 |
1537 retry_fwrite (&header, sizeof (header), 1, pdump_out); | 1745 retry_fwrite (&header, sizeof (header), 1, pdump_out); |
1538 PDUMP_ALIGN_OUTPUT (max_align_t); | 1746 PDUMP_ALIGN_OUTPUT (max_align_t); |
1539 | 1747 |
1540 pdump_scan_by_alignment (pdump_dump_data); | 1748 for (i = 0; i < Dynarr_length (pdump_cv_data); i++) |
1749 { | |
1750 pdump_cv_data_info *elt = Dynarr_atp (pdump_cv_data, i); | |
1751 elt->dest_offset = | |
1752 pdump_get_block (elt->object)->save_offset + elt->offset; | |
1753 } | |
1754 | |
1755 for (i = 0; i < Dynarr_length (pdump_cv_ptr); i++) | |
1756 Dynarr_at (pdump_cv_ptr, i).index = i; | |
1757 | |
1758 pdump_scan_by_alignment (pdump_dump_data, pdump_dump_cv_data, pdump_dump_cv_ptr); | |
1759 | |
1760 for (i = 0; i < Dynarr_length (pdump_cv_data); i++) | |
1761 { | |
1762 pdump_cv_data_info *elt = Dynarr_atp (pdump_cv_data, i); | |
1763 if(elt->fcts->convert_free) | |
1764 elt->fcts->convert_free(elt->object, elt->data, elt->size); | |
1765 } | |
1766 | |
1767 for (i = 0; i < Dynarr_length (pdump_cv_ptr); i++) | |
1768 { | |
1769 pdump_cv_ptr_info *elt = Dynarr_atp (pdump_cv_ptr, i); | |
1770 if(elt->fcts->convert_free) | |
1771 elt->fcts->convert_free(elt->object, elt->data, elt->size); | |
1772 } | |
1541 | 1773 |
1542 fseek (pdump_out, header.stab_offset, SEEK_SET); | 1774 fseek (pdump_out, header.stab_offset, SEEK_SET); |
1543 | 1775 |
1776 pdump_dump_cv_data_info (); | |
1777 pdump_dump_cv_ptr_info (); | |
1544 pdump_dump_root_block_ptrs (); | 1778 pdump_dump_root_block_ptrs (); |
1545 pdump_dump_root_blocks (); | 1779 pdump_dump_root_blocks (); |
1546 pdump_dump_rtables (); | 1780 pdump_dump_rtables (); |
1547 pdump_dump_root_lisp_objects (); | 1781 pdump_dump_root_lisp_objects (); |
1548 | 1782 |
1581 | 1815 |
1582 pdump_end = pdump_start + pdump_length; | 1816 pdump_end = pdump_start + pdump_length; |
1583 | 1817 |
1584 delta = ((EMACS_INT) pdump_start) - header->reloc_address; | 1818 delta = ((EMACS_INT) pdump_start) - header->reloc_address; |
1585 p = pdump_start + header->stab_offset; | 1819 p = pdump_start + header->stab_offset; |
1820 | |
1821 /* Get the cv_data array */ | |
1822 p = (char *) ALIGN_PTR (p, pdump_cv_data_dump_info); | |
1823 pdump_loaded_cv_data = (pdump_cv_data_dump_info *)p; | |
1824 p += header->nb_cv_data*sizeof(pdump_cv_data_dump_info); | |
1825 | |
1826 /* Build the cv_ptr array */ | |
1827 p = (char *) ALIGN_PTR (p, pdump_cv_ptr_dump_info); | |
1828 pdump_loaded_cv_ptr = | |
1829 alloca_array (pdump_cv_ptr_load_info, header->nb_cv_ptr); | |
1830 for (i = 0; i < header->nb_cv_ptr; i++) | |
1831 { | |
1832 pdump_cv_ptr_dump_info info = PDUMP_READ (p, pdump_cv_ptr_dump_info); | |
1833 pdump_loaded_cv_ptr[i].save_offset = info.save_offset; | |
1834 pdump_loaded_cv_ptr[i].size = info.size; | |
1835 pdump_loaded_cv_ptr[i].adr = 0; | |
1836 } | |
1586 | 1837 |
1587 /* Put back the pdump_root_block_ptrs */ | 1838 /* Put back the pdump_root_block_ptrs */ |
1588 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_pointer); | 1839 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_pointer); |
1589 for (i = 0; i < header->nb_root_block_ptrs; i++) | 1840 for (i = 0; i < header->nb_root_block_ptrs; i++) |
1590 { | 1841 { |