Mercurial > hg > xemacs-beta
comparison src/dumper.c @ 458:c33ae14dd6d0 r21-2-44
Import from CVS: tag r21-2-44
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:42:25 +0200 |
parents | e7ef97881643 |
children | 223736d75acb |
comparison
equal
deleted
inserted
replaced
457:4b9290a33024 | 458:c33ae14dd6d0 |
---|---|
1 /* Portable data dumper for XEmacs. | 1 /* Portable data dumper for XEmacs. |
2 Copyright (C) 1999-2000 Olivier Galibert | 2 Copyright (C) 1999-2000 Olivier Galibert |
3 Copyright (C) 2001 Martin Buchholz | |
3 | 4 |
4 This file is part of XEmacs. | 5 This file is part of XEmacs. |
5 | 6 |
6 XEmacs is free software; you can redistribute it and/or modify it | 7 XEmacs is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by the | 8 under the terms of the GNU General Public License as published by the |
62 typedef struct | 63 typedef struct |
63 { | 64 { |
64 Dynarr_declare (pdump_root_struct_ptr); | 65 Dynarr_declare (pdump_root_struct_ptr); |
65 } pdump_root_struct_ptr_dynarr; | 66 } pdump_root_struct_ptr_dynarr; |
66 | 67 |
68 typedef struct | |
69 { | |
70 Lisp_Object *address; | |
71 Lisp_Object value; | |
72 } pdump_static_Lisp_Object; | |
73 | |
74 typedef struct | |
75 { | |
76 char **address; /* char * for ease of doing relocation */ | |
77 char * value; | |
78 } pdump_static_pointer; | |
79 | |
67 static pdump_opaque_dynarr *pdump_opaques; | 80 static pdump_opaque_dynarr *pdump_opaques; |
68 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs; | 81 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs; |
69 static Lisp_Object_ptr_dynarr *pdump_root_objects; | 82 static Lisp_Object_ptr_dynarr *pdump_root_objects; |
70 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; | 83 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; |
71 | 84 |
112 { | 125 { |
113 if (pdump_weak_object_chains == NULL) | 126 if (pdump_weak_object_chains == NULL) |
114 pdump_weak_object_chains = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); | 127 pdump_weak_object_chains = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); |
115 Dynarr_add (pdump_weak_object_chains, varaddress); | 128 Dynarr_add (pdump_weak_object_chains, varaddress); |
116 } | 129 } |
130 | |
131 | |
132 inline static void | |
133 pdump_align_stream (FILE *stream, size_t alignment) | |
134 { | |
135 long offset = ftell (stream); | |
136 long adjustment = ALIGN_SIZE (offset, alignment) - offset; | |
137 if (adjustment) | |
138 fseek (stream, adjustment, SEEK_CUR); | |
139 } | |
140 | |
141 #define PDUMP_ALIGN_OUTPUT(type) pdump_align_stream (pdump_out, ALIGNOF (type)) | |
142 | |
143 #define PDUMP_WRITE(type, object) \ | |
144 fwrite (&object, sizeof (object), 1, pdump_out); | |
145 | |
146 #define PDUMP_WRITE_ALIGNED(type, object) do { \ | |
147 PDUMP_ALIGN_OUTPUT (type); \ | |
148 PDUMP_WRITE (type, object); \ | |
149 } while (0) | |
150 | |
151 #define PDUMP_READ(ptr, type) \ | |
152 (((type *) (ptr = (char*) (((type *) ptr) + 1)))[-1]) | |
153 | |
154 #define PDUMP_READ_ALIGNED(ptr, type) \ | |
155 ((ptr = (char *) ALIGN_PTR (ptr, ALIGNOF (type))), PDUMP_READ (ptr, type)) | |
156 | |
117 | 157 |
118 | 158 |
119 typedef struct | 159 typedef struct |
120 { | 160 { |
121 const struct lrecord_description *desc; | 161 const struct lrecord_description *desc; |
148 } | 188 } |
149 } | 189 } |
150 | 190 |
151 | 191 |
152 /* The structure of the file | 192 /* The structure of the file |
153 * | 193 0 - header |
154 * 0 - header | 194 - dumped objects |
155 * 256 - dumped objects | 195 stab_offset - nb_root_struct_ptrs*pair(void *, adr) |
156 * stab_offset - nb_root_struct_ptrs*pair(void *, adr) for pointers to structures | 196 for pointers to structures |
157 * - nb_opaques*pair(void *, size) for raw bits to restore | 197 - nb_opaques*pair(void *, size) for raw bits to restore |
158 * - relocation table | 198 - relocation table |
159 * - wired variable address/value couples with the count preceding the list | 199 - root lisp object address/value couples with the count |
200 preceding the list | |
160 */ | 201 */ |
161 | 202 |
162 | 203 |
163 #define PDUMP_SIGNATURE "XEmacsDP" | 204 #define PDUMP_SIGNATURE "XEmacsDP" |
164 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1) | 205 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1) |
171 EMACS_UINT reloc_address; | 212 EMACS_UINT reloc_address; |
172 int nb_root_struct_ptrs; | 213 int nb_root_struct_ptrs; |
173 int nb_opaques; | 214 int nb_opaques; |
174 } pdump_header; | 215 } pdump_header; |
175 | 216 |
176 char *pdump_start, *pdump_end; | 217 char *pdump_start; |
218 char *pdump_end; | |
177 static size_t pdump_length; | 219 static size_t pdump_length; |
178 | 220 |
179 #ifdef WIN32_NATIVE | 221 #ifdef WIN32_NATIVE |
180 /* Handle for the dump file */ | 222 /* Handle for the dump file */ |
181 HANDLE pdump_hFile = INVALID_HANDLE_VALUE; | 223 static HANDLE pdump_hFile = INVALID_HANDLE_VALUE; |
182 /* Handle for the file mapping object for the dump file */ | 224 /* Handle for the file mapping object for the dump file */ |
183 HANDLE pdump_hMap = INVALID_HANDLE_VALUE; | 225 static HANDLE pdump_hMap = INVALID_HANDLE_VALUE; |
184 #endif | 226 #endif |
185 | 227 |
186 void (*pdump_free) (void); | 228 static void (*pdump_free) (void); |
187 | 229 |
188 static const unsigned char pdump_align_table[256] = | 230 static const unsigned char pdump_align_table[256] = |
189 { | 231 { |
190 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, | 232 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, |
191 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, | 233 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, |
209 { | 251 { |
210 struct pdump_entry_list_elmt *next; | 252 struct pdump_entry_list_elmt *next; |
211 const void *obj; | 253 const void *obj; |
212 size_t size; | 254 size_t size; |
213 int count; | 255 int count; |
214 int is_lrecord; | |
215 EMACS_INT save_offset; | 256 EMACS_INT save_offset; |
216 } pdump_entry_list_elmt; | 257 } pdump_entry_list_elmt; |
217 | 258 |
218 typedef struct | 259 typedef struct |
219 { | 260 { |
243 | 284 |
244 static unsigned long cur_offset; | 285 static unsigned long cur_offset; |
245 static size_t max_size; | 286 static size_t max_size; |
246 static int pdump_fd; | 287 static int pdump_fd; |
247 static void *pdump_buf; | 288 static void *pdump_buf; |
289 static FILE *pdump_out; | |
248 | 290 |
249 #define PDUMP_HASHSIZE 200001 | 291 #define PDUMP_HASHSIZE 200001 |
250 | 292 |
251 static pdump_entry_list_elmt **pdump_hash; | 293 static pdump_entry_list_elmt **pdump_hash; |
252 | 294 |
276 } | 318 } |
277 return 0; | 319 return 0; |
278 } | 320 } |
279 | 321 |
280 static void | 322 static void |
281 pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, int count, int is_lrecord) | 323 pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, |
324 int count) | |
282 { | 325 { |
283 pdump_entry_list_elmt *e; | 326 pdump_entry_list_elmt *e; |
284 int align; | 327 int align; |
285 int pos = pdump_make_hash (obj); | 328 int pos = pdump_make_hash (obj); |
286 | 329 |
298 | 341 |
299 e->next = list->first; | 342 e->next = list->first; |
300 e->obj = obj; | 343 e->obj = obj; |
301 e->size = size; | 344 e->size = size; |
302 e->count = count; | 345 e->count = count; |
303 e->is_lrecord = is_lrecord; | |
304 list->first = e; | 346 list->first = e; |
305 | 347 |
306 list->count += count; | 348 list->count += count; |
307 pdump_hash[pos] = e; | 349 pdump_hash[pos] = e; |
308 | 350 |
309 align = pdump_align_table[size & 255]; | 351 align = pdump_align_table[size & 255]; |
310 if (align < 2 && is_lrecord) | |
311 align = 2; | |
312 | 352 |
313 if (align < list->align) | 353 if (align < list->align) |
314 list->align = align; | 354 list->align = align; |
315 } | 355 } |
316 | 356 |
355 int i; | 395 int i; |
356 stderr_out ("pdump backtrace :\n"); | 396 stderr_out ("pdump backtrace :\n"); |
357 for (i=0;i<depth;i++) | 397 for (i=0;i<depth;i++) |
358 { | 398 { |
359 if (!backtrace[i].obj) | 399 if (!backtrace[i].obj) |
360 stderr_out (" - ind. (%d, %d)\n", backtrace[i].position, backtrace[i].offset); | 400 stderr_out (" - ind. (%d, %d)\n", |
401 backtrace[i].position, | |
402 backtrace[i].offset); | |
361 else | 403 else |
362 { | 404 { |
363 stderr_out (" - %s (%d, %d)\n", | 405 stderr_out (" - %s (%d, %d)\n", |
364 LHEADER_IMPLEMENTATION (backtrace[i].obj)->name, | 406 LHEADER_IMPLEMENTATION (backtrace[i].obj)->name, |
365 backtrace[i].position, | 407 backtrace[i].position, |
366 backtrace[i].offset); | 408 backtrace[i].offset); |
367 } | 409 } |
368 } | 410 } |
369 } | 411 } |
370 | 412 |
371 static void pdump_register_object (Lisp_Object obj); | 413 static void pdump_register_object (Lisp_Object obj); |
372 static void pdump_register_struct (const void *data, const struct struct_description *sdesc, int count); | 414 static void pdump_register_struct (const void *data, |
415 const struct struct_description *sdesc, | |
416 int count); | |
373 | 417 |
374 static EMACS_INT | 418 static EMACS_INT |
375 pdump_get_indirect_count (EMACS_INT code, const struct lrecord_description *idesc, const void *idata) | 419 pdump_get_indirect_count (EMACS_INT code, |
420 const struct lrecord_description *idesc, | |
421 const void *idata) | |
376 { | 422 { |
377 EMACS_INT count; | 423 EMACS_INT count; |
378 const void *irdata; | 424 const void *irdata; |
379 | 425 |
380 int line = XD_INDIRECT_VAL (code); | 426 int line = XD_INDIRECT_VAL (code); |
394 break; | 440 break; |
395 case XD_BYTECOUNT: | 441 case XD_BYTECOUNT: |
396 count = *(Bytecount *)irdata; | 442 count = *(Bytecount *)irdata; |
397 break; | 443 break; |
398 default: | 444 default: |
399 stderr_out ("Unsupported count type : %d (line = %d, code=%ld)\n", idesc[line].type, line, (long)code); | 445 stderr_out ("Unsupported count type : %d (line = %d, code=%ld)\n", |
446 idesc[line].type, line, (long)code); | |
400 pdump_backtrace (); | 447 pdump_backtrace (); |
401 abort (); | 448 abort (); |
402 } | 449 } |
403 count += delta; | 450 count += delta; |
404 return count; | 451 return count; |
435 EMACS_INT count = desc[pos].data1; | 482 EMACS_INT count = desc[pos].data1; |
436 if (XD_IS_INDIRECT (count)) | 483 if (XD_IS_INDIRECT (count)) |
437 count = pdump_get_indirect_count (count, desc, data); | 484 count = pdump_get_indirect_count (count, desc, data); |
438 | 485 |
439 pdump_add_entry (&pdump_opaque_data_list, | 486 pdump_add_entry (&pdump_opaque_data_list, |
440 *(void **)rdata, | 487 *(void **)rdata, count, 1); |
441 count, | |
442 1, | |
443 0); | |
444 break; | 488 break; |
445 } | 489 } |
446 case XD_C_STRING: | 490 case XD_C_STRING: |
447 { | 491 { |
448 const char *str = *(const char **)rdata; | 492 const char *str = *(const char **)rdata; |
449 if (str) | 493 if (str) |
450 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0); | 494 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1); |
451 break; | 495 break; |
452 } | 496 } |
453 case XD_DOC_STRING: | 497 case XD_DOC_STRING: |
454 { | 498 { |
455 const char *str = *(const char **)rdata; | 499 const char *str = *(const char **)rdata; |
456 if ((EMACS_INT)str > 0) | 500 if ((EMACS_INT)str > 0) |
457 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0); | 501 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1); |
458 break; | 502 break; |
459 } | 503 } |
460 case XD_LISP_OBJECT: | 504 case XD_LISP_OBJECT: |
461 { | 505 { |
462 const Lisp_Object *pobj = (const Lisp_Object *)rdata; | 506 const Lisp_Object *pobj = (const Lisp_Object *)rdata; |
508 | 552 |
509 static void | 553 static void |
510 pdump_register_object (Lisp_Object obj) | 554 pdump_register_object (Lisp_Object obj) |
511 { | 555 { |
512 struct lrecord_header *objh; | 556 struct lrecord_header *objh; |
557 const struct lrecord_implementation *imp; | |
513 | 558 |
514 if (!POINTER_TYPE_P (XTYPE (obj))) | 559 if (!POINTER_TYPE_P (XTYPE (obj))) |
515 return; | 560 return; |
516 | 561 |
517 objh = XRECORD_LHEADER (obj); | 562 objh = XRECORD_LHEADER (obj); |
519 return; | 564 return; |
520 | 565 |
521 if (pdump_get_entry (objh)) | 566 if (pdump_get_entry (objh)) |
522 return; | 567 return; |
523 | 568 |
524 if (LHEADER_IMPLEMENTATION (objh)->description) | 569 imp = LHEADER_IMPLEMENTATION (objh); |
570 | |
571 if (imp->description) | |
525 { | 572 { |
526 int me = depth++; | 573 int me = depth++; |
527 if (me>65536) | 574 if (me>65536) |
528 { | 575 { |
529 stderr_out ("Backtrace overflow, loop ?\n"); | 576 stderr_out ("Backtrace overflow, loop ?\n"); |
533 backtrace[me].position = 0; | 580 backtrace[me].position = 0; |
534 backtrace[me].offset = 0; | 581 backtrace[me].offset = 0; |
535 | 582 |
536 pdump_add_entry (pdump_object_table + objh->type, | 583 pdump_add_entry (pdump_object_table + objh->type, |
537 objh, | 584 objh, |
538 LHEADER_IMPLEMENTATION (objh)->static_size ? | 585 imp->static_size ? |
539 LHEADER_IMPLEMENTATION (objh)->static_size : | 586 imp->static_size : |
540 LHEADER_IMPLEMENTATION (objh)->size_in_bytes_method (objh), | 587 imp->size_in_bytes_method (objh), |
541 1, | |
542 1); | 588 1); |
543 pdump_register_sub (objh, | 589 pdump_register_sub (objh, imp->description, me); |
544 LHEADER_IMPLEMENTATION (objh)->description, | |
545 me); | |
546 --depth; | 590 --depth; |
547 } | 591 } |
548 else | 592 else |
549 { | 593 { |
550 pdump_alert_undump_object[objh->type]++; | 594 pdump_alert_undump_object[objh->type]++; |
551 stderr_out ("Undumpable object type : %s\n", LHEADER_IMPLEMENTATION (objh)->name); | 595 stderr_out ("Undumpable object type : %s\n", imp->name); |
552 pdump_backtrace (); | 596 pdump_backtrace (); |
553 } | 597 } |
554 } | 598 } |
555 | 599 |
556 static void | 600 static void |
557 pdump_register_struct (const void *data, const struct struct_description *sdesc, int count) | 601 pdump_register_struct (const void *data, |
602 const struct struct_description *sdesc, | |
603 int count) | |
558 { | 604 { |
559 if (data && !pdump_get_entry (data)) | 605 if (data && !pdump_get_entry (data)) |
560 { | 606 { |
561 int me = depth++; | 607 int me = depth++; |
562 int i; | 608 int i; |
568 backtrace[me].obj = 0; | 614 backtrace[me].obj = 0; |
569 backtrace[me].position = 0; | 615 backtrace[me].position = 0; |
570 backtrace[me].offset = 0; | 616 backtrace[me].offset = 0; |
571 | 617 |
572 pdump_add_entry (pdump_get_entry_list (sdesc), | 618 pdump_add_entry (pdump_get_entry_list (sdesc), |
573 data, | 619 data, sdesc->size, count); |
574 sdesc->size, | |
575 count, | |
576 0); | |
577 for (i=0; i<count; i++) | 620 for (i=0; i<count; i++) |
578 { | 621 { |
579 pdump_register_sub (((char *)data) + sdesc->size*i, | 622 pdump_register_sub (((char *)data) + sdesc->size*i, |
580 sdesc->description, | 623 sdesc->description, |
581 me); | 624 me); |
583 --depth; | 626 --depth; |
584 } | 627 } |
585 } | 628 } |
586 | 629 |
587 static void | 630 static void |
588 pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc) | 631 pdump_dump_data (pdump_entry_list_elmt *elmt, |
632 const struct lrecord_description *desc) | |
589 { | 633 { |
590 size_t size = elmt->size; | 634 size_t size = elmt->size; |
591 int count = elmt->count; | 635 int count = elmt->count; |
592 if (desc) | 636 if (desc) |
593 { | 637 { |
677 break; | 721 break; |
678 } | 722 } |
679 default: | 723 default: |
680 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); | 724 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); |
681 abort (); | 725 abort (); |
682 }; | 726 } |
683 } | 727 } |
684 } | 728 } |
685 } | 729 } |
686 write (pdump_fd, desc ? pdump_buf : elmt->obj, size*count); | 730 fwrite (desc ? pdump_buf : elmt->obj, size, count, pdump_out); |
687 if (elmt->is_lrecord && ((size*count) & 3)) | 731 } |
688 write (pdump_fd, "\0\0\0", 4-((size*count) & 3)); | 732 |
689 } | 733 static void |
690 | 734 pdump_reloc_one (void *data, EMACS_INT delta, |
691 static void | 735 const struct lrecord_description *desc) |
692 pdump_reloc_one (void *data, EMACS_INT delta, const struct lrecord_description *desc) | |
693 { | 736 { |
694 int pos; | 737 int pos; |
695 | 738 |
696 restart: | 739 restart: |
697 for (pos = 0; desc[pos].type != XD_END; pos++) | 740 for (pos = 0; desc[pos].type != XD_END; pos++) |
761 }; | 804 }; |
762 } | 805 } |
763 } | 806 } |
764 | 807 |
765 static void | 808 static void |
766 pdump_allocate_offset (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc) | 809 pdump_allocate_offset (pdump_entry_list_elmt *elmt, |
767 { | 810 const struct lrecord_description *desc) |
768 size_t size = (elmt->is_lrecord ? (elmt->size + 3) & ~3 : elmt->size)*elmt->count; | 811 { |
812 size_t size = elmt->count * elmt->size; | |
769 elmt->save_offset = cur_offset; | 813 elmt->save_offset = cur_offset; |
770 if (size>max_size) | 814 if (size>max_size) |
771 max_size = size; | 815 max_size = size; |
772 cur_offset += size; | 816 cur_offset += size; |
773 } | 817 } |
774 | 818 |
775 static void | 819 static void |
776 pdump_scan_by_alignment (void (*f)(pdump_entry_list_elmt *, const struct lrecord_description *)) | 820 pdump_scan_by_alignment (void (*f)(pdump_entry_list_elmt *, |
821 const struct lrecord_description *)) | |
777 { | 822 { |
778 int align, i; | 823 int align, i; |
779 const struct lrecord_description *idesc; | 824 const struct lrecord_description *idesc; |
780 pdump_entry_list_elmt *elmt; | 825 pdump_entry_list_elmt *elmt; |
781 for (align=8; align>=0; align--) | 826 for (align=8; align>=0; align--) |
815 } | 860 } |
816 } | 861 } |
817 } | 862 } |
818 | 863 |
819 static void | 864 static void |
820 pdump_dump_from_root_struct_ptrs (void) | 865 pdump_dump_root_struct_ptrs (void) |
821 { | 866 { |
822 int i; | 867 int i; |
823 for (i = 0; i < Dynarr_length (pdump_root_struct_ptrs); i++) | 868 size_t count = Dynarr_length (pdump_root_struct_ptrs); |
824 { | 869 pdump_static_pointer *data = alloca_array (pdump_static_pointer, count); |
825 EMACS_INT adr; | 870 for (i = 0; i < count; i++) |
826 pdump_root_struct_ptr *info = Dynarr_atp (pdump_root_struct_ptrs, i); | 871 { |
827 write (pdump_fd, &info->ptraddress, sizeof (info->ptraddress)); | 872 data[i].address = (char **) Dynarr_atp (pdump_root_struct_ptrs, i)->ptraddress; |
828 adr = pdump_get_entry (*(info->ptraddress))->save_offset; | 873 data[i].value = (char *) pdump_get_entry (* data[i].address)->save_offset; |
829 write (pdump_fd, &adr, sizeof (adr)); | 874 } |
830 } | 875 PDUMP_ALIGN_OUTPUT (pdump_static_pointer); |
876 fwrite (data, sizeof (pdump_static_pointer), count, pdump_out); | |
831 } | 877 } |
832 | 878 |
833 static void | 879 static void |
834 pdump_dump_opaques (void) | 880 pdump_dump_opaques (void) |
835 { | 881 { |
836 int i; | 882 int i; |
837 for (i = 0; i < Dynarr_length (pdump_opaques); i++) | 883 for (i = 0; i < Dynarr_length (pdump_opaques); i++) |
838 { | 884 { |
839 pdump_opaque *info = Dynarr_atp (pdump_opaques, i); | 885 pdump_opaque *info = Dynarr_atp (pdump_opaques, i); |
840 write (pdump_fd, info, sizeof (*info)); | 886 PDUMP_WRITE_ALIGNED (pdump_opaque, *info); |
841 write (pdump_fd, info->varaddress, info->size); | 887 fwrite (info->varaddress, info->size, 1, pdump_out); |
842 } | 888 } |
843 } | 889 } |
844 | 890 |
845 static void | 891 static void |
846 pdump_dump_rtables (void) | 892 pdump_dump_rtables (void) |
854 elmt = pdump_object_table[i].first; | 900 elmt = pdump_object_table[i].first; |
855 if (!elmt) | 901 if (!elmt) |
856 continue; | 902 continue; |
857 rt.desc = lrecord_implementations_table[i]->description; | 903 rt.desc = lrecord_implementations_table[i]->description; |
858 rt.count = pdump_object_table[i].count; | 904 rt.count = pdump_object_table[i].count; |
859 write (pdump_fd, &rt, sizeof (rt)); | 905 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
860 while (elmt) | 906 while (elmt) |
861 { | 907 { |
862 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; | 908 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; |
863 write (pdump_fd, &rdata, sizeof (rdata)); | 909 PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); |
864 elmt = elmt->next; | 910 elmt = elmt->next; |
865 } | 911 } |
866 } | 912 } |
867 | 913 |
868 rt.desc = 0; | 914 rt.desc = 0; |
869 rt.count = 0; | 915 rt.count = 0; |
870 write (pdump_fd, &rt, sizeof (rt)); | 916 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
871 | 917 |
872 for (i=0; i<pdump_struct_table.count; i++) | 918 for (i=0; i<pdump_struct_table.count; i++) |
873 { | 919 { |
874 elmt = pdump_struct_table.list[i].list.first; | 920 elmt = pdump_struct_table.list[i].list.first; |
875 rt.desc = pdump_struct_table.list[i].sdesc->description; | 921 rt.desc = pdump_struct_table.list[i].sdesc->description; |
876 rt.count = pdump_struct_table.list[i].list.count; | 922 rt.count = pdump_struct_table.list[i].list.count; |
877 write (pdump_fd, &rt, sizeof (rt)); | 923 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
878 while (elmt) | 924 while (elmt) |
879 { | 925 { |
880 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; | 926 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; |
881 int j; | 927 int j; |
882 for (j=0; j<elmt->count; j++) | 928 for (j=0; j<elmt->count; j++) |
883 { | 929 { |
884 write (pdump_fd, &rdata, sizeof (rdata)); | 930 PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); |
885 rdata += elmt->size; | 931 rdata += elmt->size; |
886 } | 932 } |
887 elmt = elmt->next; | 933 elmt = elmt->next; |
888 } | 934 } |
889 } | 935 } |
890 rt.desc = 0; | 936 rt.desc = 0; |
891 rt.count = 0; | 937 rt.count = 0; |
892 write (pdump_fd, &rt, sizeof (rt)); | 938 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
893 } | 939 } |
894 | 940 |
895 static void | 941 static void |
896 pdump_dump_from_root_objects (void) | 942 pdump_dump_root_objects (void) |
897 { | 943 { |
898 size_t count = Dynarr_length (pdump_root_objects) + Dynarr_length (pdump_weak_object_chains); | 944 size_t count = (Dynarr_length (pdump_root_objects) + |
945 Dynarr_length (pdump_weak_object_chains)); | |
899 size_t i; | 946 size_t i; |
900 | 947 |
901 write (pdump_fd, &count, sizeof (count)); | 948 PDUMP_WRITE_ALIGNED (size_t, count); |
949 PDUMP_ALIGN_OUTPUT (pdump_static_Lisp_Object); | |
902 | 950 |
903 for (i=0; i<Dynarr_length (pdump_root_objects); i++) | 951 for (i=0; i<Dynarr_length (pdump_root_objects); i++) |
904 { | 952 { |
905 Lisp_Object obj = * Dynarr_at (pdump_root_objects, i); | 953 pdump_static_Lisp_Object obj; |
906 if (POINTER_TYPE_P (XTYPE (obj))) | 954 obj.address = Dynarr_at (pdump_root_objects, i); |
907 obj = wrap_object ((void *) pdump_get_entry (XRECORD_LHEADER (obj))->save_offset); | 955 obj.value = * obj.address; |
908 write (pdump_fd, Dynarr_atp (pdump_root_objects, i), sizeof (Dynarr_atp (pdump_root_objects, i))); | 956 |
909 write (pdump_fd, &obj, sizeof (obj)); | 957 if (POINTER_TYPE_P (XTYPE (obj.value))) |
958 obj.value = wrap_object ((void *) pdump_get_entry (XRECORD_LHEADER (obj.value))->save_offset); | |
959 | |
960 PDUMP_WRITE (pdump_static_Lisp_Object, obj); | |
910 } | 961 } |
911 | 962 |
912 for (i=0; i<Dynarr_length (pdump_weak_object_chains); i++) | 963 for (i=0; i<Dynarr_length (pdump_weak_object_chains); i++) |
913 { | 964 { |
914 Lisp_Object obj = * Dynarr_at (pdump_weak_object_chains, i); | |
915 pdump_entry_list_elmt *elmt; | 965 pdump_entry_list_elmt *elmt; |
916 | 966 pdump_static_Lisp_Object obj; |
967 | |
968 obj.address = Dynarr_at (pdump_weak_object_chains, i); | |
969 obj.value = * obj.address; | |
970 | |
917 for (;;) | 971 for (;;) |
918 { | 972 { |
919 const struct lrecord_description *desc; | 973 const struct lrecord_description *desc; |
920 int pos; | 974 int pos; |
921 elmt = pdump_get_entry (XRECORD_LHEADER (obj)); | 975 elmt = pdump_get_entry (XRECORD_LHEADER (obj.value)); |
922 if (elmt) | 976 if (elmt) |
923 break; | 977 break; |
924 desc = XRECORD_LHEADER_IMPLEMENTATION (obj)->description; | 978 desc = XRECORD_LHEADER_IMPLEMENTATION (obj.value)->description; |
925 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) | 979 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) |
926 assert (desc[pos].type != XD_END); | 980 assert (desc[pos].type != XD_END); |
927 | 981 |
928 obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj))); | 982 obj.value = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj.value))); |
929 } | 983 } |
930 obj = wrap_object ((void *) elmt->save_offset); | 984 obj.value = wrap_object ((void *) elmt->save_offset); |
931 | 985 |
932 write (pdump_fd, Dynarr_atp (pdump_weak_object_chains, i), sizeof (Lisp_Object *)); | 986 PDUMP_WRITE (pdump_static_Lisp_Object, obj); |
933 write (pdump_fd, &obj, sizeof (obj)); | |
934 } | 987 } |
935 } | 988 } |
936 | 989 |
937 void | 990 void |
938 pdump (void) | 991 pdump (void) |
939 { | 992 { |
940 int i; | 993 int i; |
941 Lisp_Object t_console, t_device, t_frame; | 994 Lisp_Object t_console, t_device, t_frame; |
942 int none; | 995 int none; |
943 pdump_header hd; | 996 pdump_header header; |
944 | 997 |
945 flush_all_buffer_local_cache (); | 998 flush_all_buffer_local_cache (); |
946 | 999 |
947 /* These appear in a DEFVAR_LISP, which does a staticpro() */ | 1000 /* These appear in a DEFVAR_LISP, which does a staticpro() */ |
948 t_console = Vterminal_console; Vterminal_console = Qnil; | 1001 t_console = Vterminal_console; Vterminal_console = Qnil; |
990 { | 1043 { |
991 pdump_root_struct_ptr info = Dynarr_at (pdump_root_struct_ptrs, i); | 1044 pdump_root_struct_ptr info = Dynarr_at (pdump_root_struct_ptrs, i); |
992 pdump_register_struct (*(info.ptraddress), info.desc, 1); | 1045 pdump_register_struct (*(info.ptraddress), info.desc, 1); |
993 } | 1046 } |
994 | 1047 |
995 memcpy (hd.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); | 1048 memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); |
996 hd.id = dump_id; | 1049 header.id = dump_id; |
997 hd.reloc_address = 0; | 1050 header.reloc_address = 0; |
998 hd.nb_root_struct_ptrs = Dynarr_length (pdump_root_struct_ptrs); | 1051 header.nb_root_struct_ptrs = Dynarr_length (pdump_root_struct_ptrs); |
999 hd.nb_opaques = Dynarr_length (pdump_opaques); | 1052 header.nb_opaques = Dynarr_length (pdump_opaques); |
1000 | 1053 |
1001 cur_offset = 256; | 1054 cur_offset = ALIGN_SIZE (sizeof (header), ALIGNOF (max_align_t)); |
1002 max_size = 0; | 1055 max_size = 0; |
1003 | 1056 |
1004 pdump_scan_by_alignment (pdump_allocate_offset); | 1057 pdump_scan_by_alignment (pdump_allocate_offset); |
1058 cur_offset = ALIGN_SIZE (cur_offset, ALIGNOF (max_align_t)); | |
1059 header.stab_offset = cur_offset; | |
1005 | 1060 |
1006 pdump_buf = xmalloc (max_size); | 1061 pdump_buf = xmalloc (max_size); |
1007 /* Avoid use of the `open' macro. We want the real function. */ | 1062 /* Avoid use of the `open' macro. We want the real function. */ |
1008 #undef open | 1063 #undef open |
1009 pdump_fd = open (EMACS_PROGNAME ".dmp", | 1064 pdump_fd = open (EMACS_PROGNAME ".dmp", |
1010 O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, 0666); | 1065 O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, 0666); |
1011 hd.stab_offset = (cur_offset + 3) & ~3; | 1066 pdump_out = fdopen (pdump_fd, "w"); |
1012 | 1067 |
1013 write (pdump_fd, &hd, sizeof (hd)); | 1068 fwrite (&header, sizeof (header), 1, pdump_out); |
1014 lseek (pdump_fd, 256, SEEK_SET); | 1069 PDUMP_ALIGN_OUTPUT (max_align_t); |
1015 | 1070 |
1016 pdump_scan_by_alignment (pdump_dump_data); | 1071 pdump_scan_by_alignment (pdump_dump_data); |
1017 | 1072 |
1018 lseek (pdump_fd, hd.stab_offset, SEEK_SET); | 1073 fseek (pdump_out, header.stab_offset, SEEK_SET); |
1019 | 1074 |
1020 pdump_dump_from_root_struct_ptrs (); | 1075 pdump_dump_root_struct_ptrs (); |
1021 pdump_dump_opaques (); | 1076 pdump_dump_opaques (); |
1022 pdump_dump_rtables (); | 1077 pdump_dump_rtables (); |
1023 pdump_dump_from_root_objects (); | 1078 pdump_dump_root_objects (); |
1024 | 1079 |
1080 fclose (pdump_out); | |
1025 close (pdump_fd); | 1081 close (pdump_fd); |
1082 | |
1026 free (pdump_buf); | 1083 free (pdump_buf); |
1027 | 1084 |
1028 free (pdump_hash); | 1085 free (pdump_hash); |
1029 | 1086 |
1030 Vterminal_console = t_console; | 1087 Vterminal_console = t_console; |
1038 return (!memcmp (((pdump_header *)pdump_start)->signature, | 1095 return (!memcmp (((pdump_header *)pdump_start)->signature, |
1039 PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN) | 1096 PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN) |
1040 && ((pdump_header *)pdump_start)->id == dump_id); | 1097 && ((pdump_header *)pdump_start)->id == dump_id); |
1041 } | 1098 } |
1042 | 1099 |
1100 /*----------------------------------------------------------------------*/ | |
1101 /* Reading the dump file */ | |
1102 /*----------------------------------------------------------------------*/ | |
1043 static int | 1103 static int |
1044 pdump_load_finish (void) | 1104 pdump_load_finish (void) |
1045 { | 1105 { |
1046 int i; | 1106 int i; |
1047 char *p; | 1107 char *p; |
1048 EMACS_INT delta; | 1108 EMACS_INT delta; |
1049 EMACS_INT count; | 1109 EMACS_INT count; |
1110 pdump_header *header = (pdump_header *)pdump_start; | |
1050 | 1111 |
1051 pdump_end = pdump_start + pdump_length; | 1112 pdump_end = pdump_start + pdump_length; |
1052 | 1113 |
1053 #define PDUMP_READ(p, type) (p = (char*) (((type *) p) + 1), *((type *) p - 1)) | 1114 delta = ((EMACS_INT)pdump_start) - header->reloc_address; |
1054 | 1115 p = pdump_start + header->stab_offset; |
1055 delta = ((EMACS_INT)pdump_start) - ((pdump_header *)pdump_start)->reloc_address; | |
1056 p = pdump_start + ((pdump_header *)pdump_start)->stab_offset; | |
1057 | 1116 |
1058 /* Put back the pdump_root_struct_ptrs */ | 1117 /* Put back the pdump_root_struct_ptrs */ |
1059 for (i=0; i<((pdump_header *)pdump_start)->nb_root_struct_ptrs; i++) | 1118 p = (char *) ALIGN_PTR (p, ALIGNOF (pdump_static_pointer)); |
1060 { | 1119 for (i=0; i<header->nb_root_struct_ptrs; i++) |
1061 void **adr = PDUMP_READ (p, void **); | 1120 { |
1062 *adr = (void *) (PDUMP_READ (p, char *) + delta); | 1121 pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); |
1122 (* ptr.address) = ptr.value + delta; | |
1063 } | 1123 } |
1064 | 1124 |
1065 /* Put back the pdump_opaques */ | 1125 /* Put back the pdump_opaques */ |
1066 for (i=0; i<((pdump_header *)pdump_start)->nb_opaques; i++) | 1126 for (i=0; i<header->nb_opaques; i++) |
1067 { | 1127 { |
1068 pdump_opaque info = PDUMP_READ (p, pdump_opaque); | 1128 pdump_opaque info = PDUMP_READ_ALIGNED (p, pdump_opaque); |
1069 memcpy (info.varaddress, p, info.size); | 1129 memcpy (info.varaddress, p, info.size); |
1070 p += info.size; | 1130 p += info.size; |
1071 } | 1131 } |
1072 | 1132 |
1073 /* Do the relocations */ | 1133 /* Do the relocations */ |
1074 pdump_rt_list = p; | 1134 pdump_rt_list = p; |
1075 count = 2; | 1135 count = 2; |
1076 for (;;) | 1136 for (;;) |
1077 { | 1137 { |
1078 pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table); | 1138 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); |
1139 p = (char *) ALIGN_PTR (p, ALIGNOF (char *)); | |
1079 if (rt.desc) | 1140 if (rt.desc) |
1080 { | 1141 { |
1142 char **reloc = (char **)p; | |
1081 for (i=0; i < rt.count; i++) | 1143 for (i=0; i < rt.count; i++) |
1082 { | 1144 { |
1083 char *adr = delta + *(char **)p; | 1145 reloc[i] += delta; |
1084 *(char **)p = adr; | 1146 pdump_reloc_one (reloc[i], delta, rt.desc); |
1085 pdump_reloc_one (adr, delta, rt.desc); | |
1086 p += sizeof (char *); | |
1087 } | 1147 } |
1148 p += rt.count * sizeof (char *); | |
1088 } else | 1149 } else |
1089 if (!(--count)) | 1150 if (!(--count)) |
1090 break; | 1151 break; |
1091 } | 1152 } |
1092 | 1153 |
1093 /* Put the pdump_root_objects variables in place */ | 1154 /* Put the pdump_root_objects variables in place */ |
1094 for (i = PDUMP_READ (p, size_t); i; i--) | 1155 i = PDUMP_READ_ALIGNED (p, size_t); |
1095 { | 1156 p = (char *) ALIGN_PTR (p, ALIGNOF (pdump_static_Lisp_Object)); |
1096 Lisp_Object *var = PDUMP_READ (p, Lisp_Object *); | 1157 while (i--) |
1097 Lisp_Object obj = PDUMP_READ (p, Lisp_Object); | 1158 { |
1098 | 1159 pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); |
1099 if (POINTER_TYPE_P (XTYPE (obj))) | 1160 |
1100 obj = wrap_object ((char *) XPNTR (obj) + delta); | 1161 if (POINTER_TYPE_P (XTYPE (obj.value))) |
1101 | 1162 obj.value = wrap_object ((char *) XPNTR (obj.value) + delta); |
1102 *var = obj; | 1163 |
1164 (* obj.address) = obj.value; | |
1103 } | 1165 } |
1104 | 1166 |
1105 /* Final cleanups */ | 1167 /* Final cleanups */ |
1106 /* reorganize hash tables */ | 1168 /* reorganize hash tables */ |
1107 p = pdump_rt_list; | 1169 p = pdump_rt_list; |
1108 for (;;) | 1170 for (;;) |
1109 { | 1171 { |
1110 pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table); | 1172 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); |
1173 p = (char *) ALIGN_PTR (p, ALIGNOF (Lisp_Object)); | |
1111 if (!rt.desc) | 1174 if (!rt.desc) |
1112 break; | 1175 break; |
1113 if (rt.desc == hash_table_description) | 1176 if (rt.desc == hash_table_description) |
1114 { | 1177 { |
1115 for (i=0; i < rt.count; i++) | 1178 for (i=0; i < rt.count; i++) |