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++)