comparison src/dumper.c @ 452:3d3049ae1304 r21-2-41

Import from CVS: tag r21-2-41
author cvs
date Mon, 13 Aug 2007 11:40:21 +0200
parents 1ccc32a20af4
children e7ef97881643
comparison
equal deleted inserted replaced
451:8ad70c5cd5d7 452:3d3049ae1304
23 #include <config.h> 23 #include <config.h>
24 #include "lisp.h" 24 #include "lisp.h"
25 25
26 #include "dump-id.h" 26 #include "dump-id.h"
27 #include "specifier.h" 27 #include "specifier.h"
28 #include "alloc.h"
29 #include "elhash.h" 28 #include "elhash.h"
30 #include "sysfile.h" 29 #include "sysfile.h"
31 #include "console-stream.h" 30 #include "console-stream.h"
32 #include "dumper.h" 31 #include "dumper.h"
33 32
40 #endif 39 #endif
41 40
42 #ifndef SEPCHAR 41 #ifndef SEPCHAR
43 #define SEPCHAR ':' 42 #define SEPCHAR ':'
44 #endif 43 #endif
44
45 typedef struct
46 {
47 void *varaddress;
48 size_t size;
49 } pdump_opaque;
50
51 typedef struct
52 {
53 Dynarr_declare (pdump_opaque);
54 } pdump_opaque_dynarr;
55
56 typedef struct
57 {
58 void **ptraddress;
59 const struct struct_description *desc;
60 } pdump_root_struct_ptr;
61
62 typedef struct
63 {
64 Dynarr_declare (pdump_root_struct_ptr);
65 } pdump_root_struct_ptr_dynarr;
66
67 static pdump_opaque_dynarr *pdump_opaques;
68 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs;
69 static Lisp_Object_ptr_dynarr *pdump_root_objects;
70 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains;
71
72 /* Mark SIZE bytes at non-heap address VARADDRESS for dumping as is,
73 without any bit-twiddling. */
74 void
75 dump_add_opaque (void *varaddress, size_t size)
76 {
77 pdump_opaque info;
78 info.varaddress = varaddress;
79 info.size = size;
80 if (pdump_opaques == NULL)
81 pdump_opaques = Dynarr_new (pdump_opaque);
82 Dynarr_add (pdump_opaques, info);
83 }
84
85 /* Mark the struct described by DESC and pointed to by the pointer at
86 non-heap address VARADDRESS for dumping.
87 All the objects reachable from this pointer will also be dumped. */
88 void
89 dump_add_root_struct_ptr (void *ptraddress, const struct struct_description *desc)
90 {
91 pdump_root_struct_ptr info;
92 info.ptraddress = (void **) ptraddress;
93 info.desc = desc;
94 if (pdump_root_struct_ptrs == NULL)
95 pdump_root_struct_ptrs = Dynarr_new (pdump_root_struct_ptr);
96 Dynarr_add (pdump_root_struct_ptrs, info);
97 }
98
99 /* Mark the Lisp_Object at non-heap address VARADDRESS for dumping.
100 All the objects reachable from this var will also be dumped. */
101 void
102 dump_add_root_object (Lisp_Object *varaddress)
103 {
104 if (pdump_root_objects == NULL)
105 pdump_root_objects = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
106 Dynarr_add (pdump_root_objects, varaddress);
107 }
108
109 /* Mark the list pointed to by the Lisp_Object at VARADDRESS for dumping. */
110 void
111 dump_add_weak_object_chain (Lisp_Object *varaddress)
112 {
113 if (pdump_weak_object_chains == NULL)
114 pdump_weak_object_chains = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
115 Dynarr_add (pdump_weak_object_chains, varaddress);
116 }
117
45 118
46 typedef struct 119 typedef struct
47 { 120 {
48 const struct lrecord_description *desc; 121 const struct lrecord_description *desc;
49 int count; 122 int count;
78 151
79 /* The structure of the file 152 /* The structure of the file
80 * 153 *
81 * 0 - header 154 * 0 - header
82 * 256 - dumped objects 155 * 256 - dumped objects
83 * stab_offset - nb_staticpro*(Lisp_Object *) from staticvec 156 * stab_offset - nb_root_struct_ptrs*pair(void *, adr) for pointers to structures
84 * - nb_staticpro*(relocated Lisp_Object) pointed to by staticpro 157 * - nb_opaques*pair(void *, size) for raw bits to restore
85 * - nb_structdmp*pair(void *, adr) for pointers to structures
86 * - lrecord_implementations_table[]
87 * - relocation table 158 * - relocation table
88 * - wired variable address/value couples with the count preceding the list 159 * - wired variable address/value couples with the count preceding the list
89 */ 160 */
90 161
91 162
92 #define DUMP_SIGNATURE "XEmacsDP" 163 #define PDUMP_SIGNATURE "XEmacsDP"
93 #define DUMP_SIGNATURE_LEN (sizeof (DUMP_SIGNATURE) - 1) 164 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1)
94 165
95 typedef struct 166 typedef struct
96 { 167 {
97 char signature[DUMP_SIGNATURE_LEN]; 168 char signature[PDUMP_SIGNATURE_LEN];
98 unsigned int id; 169 unsigned int id;
99 EMACS_UINT stab_offset; 170 EMACS_UINT stab_offset;
100 EMACS_UINT reloc_address; 171 EMACS_UINT reloc_address;
101 int nb_staticpro; 172 int nb_root_struct_ptrs;
102 int nb_structdmp; 173 int nb_opaques;
103 int nb_opaquedmp; 174 } pdump_header;
104 } dump_header;
105 175
106 char *pdump_start, *pdump_end; 176 char *pdump_start, *pdump_end;
107 static size_t pdump_length; 177 static size_t pdump_length;
108 178
109 #ifdef WIN32_NATIVE 179 #ifdef WIN32_NATIVE
110 // Handle for the dump file 180 /* Handle for the dump file */
111 HANDLE pdump_hFile = INVALID_HANDLE_VALUE; 181 HANDLE pdump_hFile = INVALID_HANDLE_VALUE;
112 // Handle for the file mapping object for the dump file 182 /* Handle for the file mapping object for the dump file */
113 HANDLE pdump_hMap = INVALID_HANDLE_VALUE; 183 HANDLE pdump_hMap = INVALID_HANDLE_VALUE;
114 #endif 184 #endif
115 185
116 void (*pdump_free) (void); 186 void (*pdump_free) (void);
117 187
118 static const unsigned char align_table[256] = 188 static const unsigned char pdump_align_table[256] =
119 { 189 {
120 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 190 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
121 4, 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,
122 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 192 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
123 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 193 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
234 list->first = e; 304 list->first = e;
235 305
236 list->count += count; 306 list->count += count;
237 pdump_hash[pos] = e; 307 pdump_hash[pos] = e;
238 308
239 align = align_table[size & 255]; 309 align = pdump_align_table[size & 255];
240 if (align < 2 && is_lrecord) 310 if (align < 2 && is_lrecord)
241 align = 2; 311 align = 2;
242 312
243 if (align < list->align) 313 if (align < list->align)
244 list->align = align; 314 list->align = align;
277 int offset; 347 int offset;
278 } backtrace[65536]; 348 } backtrace[65536];
279 349
280 static int depth; 350 static int depth;
281 351
282 static void pdump_backtrace (void) 352 static void
353 pdump_backtrace (void)
283 { 354 {
284 int i; 355 int i;
285 stderr_out ("pdump backtrace :\n"); 356 stderr_out ("pdump backtrace :\n");
286 for (i=0;i<depth;i++) 357 for (i=0;i<depth;i++)
287 { 358 {
736 } 807 }
737 808
738 elmt = pdump_opaque_data_list.first; 809 elmt = pdump_opaque_data_list.first;
739 while (elmt) 810 while (elmt)
740 { 811 {
741 if (align_table[elmt->size & 255] == align) 812 if (pdump_align_table[elmt->size & 255] == align)
742 f (elmt, 0); 813 f (elmt, 0);
743 elmt = elmt->next; 814 elmt = elmt->next;
744 } 815 }
745 } 816 }
746 } 817 }
747 818
748 static void 819 static void
749 pdump_dump_staticvec (void) 820 pdump_dump_from_root_struct_ptrs (void)
750 { 821 {
751 EMACS_INT *reloc = xnew_array (EMACS_INT, staticidx);
752 int i; 822 int i;
753 write (pdump_fd, staticvec, staticidx*sizeof (Lisp_Object *)); 823 for (i = 0; i < Dynarr_length (pdump_root_struct_ptrs); i++)
754 824 {
755 for (i=0; i<staticidx; i++) 825 EMACS_INT adr;
756 { 826 pdump_root_struct_ptr *info = Dynarr_atp (pdump_root_struct_ptrs, i);
757 Lisp_Object obj = *staticvec[i]; 827 write (pdump_fd, &info->ptraddress, sizeof (info->ptraddress));
758 if (POINTER_TYPE_P (XTYPE (obj))) 828 adr = pdump_get_entry (*(info->ptraddress))->save_offset;
759 reloc[i] = pdump_get_entry (XRECORD_LHEADER (obj))->save_offset; 829 write (pdump_fd, &adr, sizeof (adr));
760 else 830 }
761 reloc[i] = *(EMACS_INT *)(staticvec[i]); 831 }
762 } 832
763 write (pdump_fd, reloc, staticidx*sizeof (Lisp_Object)); 833 static void
764 free (reloc); 834 pdump_dump_opaques (void)
765 }
766
767 static void
768 pdump_dump_structvec (void)
769 { 835 {
770 int i; 836 int i;
771 for (i=0; i<dumpstructidx; i++) 837 for (i = 0; i < Dynarr_length (pdump_opaques); i++)
772 { 838 {
773 EMACS_INT adr; 839 pdump_opaque *info = Dynarr_atp (pdump_opaques, i);
774 write (pdump_fd, &(dumpstructvec[i].data), sizeof (void *)); 840 write (pdump_fd, info, sizeof (*info));
775 adr = pdump_get_entry (*(void **)(dumpstructvec[i].data))->save_offset; 841 write (pdump_fd, info->varaddress, info->size);
776 write (pdump_fd, &adr, sizeof (adr)); 842 }
777 } 843 }
778 } 844
779 845 static void
780 static void 846 pdump_dump_rtables (void)
781 pdump_dump_opaquevec (void)
782 { 847 {
783 int i; 848 int i;
784 for (i=0; i<dumpopaqueidx; i++)
785 {
786 write (pdump_fd, &(dumpopaquevec[i]), sizeof (dumpopaquevec[i]));
787 write (pdump_fd, dumpopaquevec[i].data, dumpopaquevec[i].size);
788 }
789 }
790
791 static void
792 pdump_dump_itable (void)
793 {
794 write (pdump_fd, lrecord_implementations_table, lrecord_type_count*sizeof (lrecord_implementations_table[0]));
795 }
796
797 static void
798 pdump_dump_rtables (void)
799 {
800 int i, j;
801 pdump_entry_list_elmt *elmt; 849 pdump_entry_list_elmt *elmt;
802 pdump_reloc_table rt; 850 pdump_reloc_table rt;
803 851
804 for (i=0; i<lrecord_type_count; i++) 852 for (i=0; i<lrecord_type_count; i++)
805 { 853 {
828 rt.count = pdump_struct_table.list[i].list.count; 876 rt.count = pdump_struct_table.list[i].list.count;
829 write (pdump_fd, &rt, sizeof (rt)); 877 write (pdump_fd, &rt, sizeof (rt));
830 while (elmt) 878 while (elmt)
831 { 879 {
832 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; 880 EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset;
881 int j;
833 for (j=0; j<elmt->count; j++) 882 for (j=0; j<elmt->count; j++)
834 { 883 {
835 write (pdump_fd, &rdata, sizeof (rdata)); 884 write (pdump_fd, &rdata, sizeof (rdata));
836 rdata += elmt->size; 885 rdata += elmt->size;
837 } 886 }
842 rt.count = 0; 891 rt.count = 0;
843 write (pdump_fd, &rt, sizeof (rt)); 892 write (pdump_fd, &rt, sizeof (rt));
844 } 893 }
845 894
846 static void 895 static void
847 pdump_dump_wired (void) 896 pdump_dump_from_root_objects (void)
848 { 897 {
849 EMACS_INT count = pdump_wireidx + pdump_wireidx_list; 898 size_t count = Dynarr_length (pdump_root_objects) + Dynarr_length (pdump_weak_object_chains);
850 int i; 899 size_t i;
851 900
852 write (pdump_fd, &count, sizeof (count)); 901 write (pdump_fd, &count, sizeof (count));
853 902
854 for (i=0; i<pdump_wireidx; i++) 903 for (i=0; i<Dynarr_length (pdump_root_objects); i++)
855 { 904 {
856 EMACS_INT obj = pdump_get_entry (XRECORD_LHEADER (*(pdump_wirevec[i])))->save_offset; 905 Lisp_Object obj = * Dynarr_at (pdump_root_objects, i);
857 write (pdump_fd, &pdump_wirevec[i], sizeof (pdump_wirevec[i])); 906 if (POINTER_TYPE_P (XTYPE (obj)))
907 obj = wrap_object ((void *) pdump_get_entry (XRECORD_LHEADER (obj))->save_offset);
908 write (pdump_fd, Dynarr_atp (pdump_root_objects, i), sizeof (Dynarr_atp (pdump_root_objects, i)));
858 write (pdump_fd, &obj, sizeof (obj)); 909 write (pdump_fd, &obj, sizeof (obj));
859 } 910 }
860 911
861 for (i=0; i<pdump_wireidx_list; i++) 912 for (i=0; i<Dynarr_length (pdump_weak_object_chains); i++)
862 { 913 {
863 Lisp_Object obj = *(pdump_wirevec_list[i]); 914 Lisp_Object obj = * Dynarr_at (pdump_weak_object_chains, i);
864 pdump_entry_list_elmt *elmt; 915 pdump_entry_list_elmt *elmt;
865 EMACS_INT res;
866 916
867 for (;;) 917 for (;;)
868 { 918 {
869 const struct lrecord_description *desc; 919 const struct lrecord_description *desc;
870 int pos; 920 int pos;
875 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) 925 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++)
876 assert (desc[pos].type != XD_END); 926 assert (desc[pos].type != XD_END);
877 927
878 obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj))); 928 obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj)));
879 } 929 }
880 res = elmt->save_offset; 930 obj = wrap_object ((void *) elmt->save_offset);
881 931
882 write (pdump_fd, &pdump_wirevec_list[i], sizeof (pdump_wirevec_list[i])); 932 write (pdump_fd, Dynarr_atp (pdump_weak_object_chains, i), sizeof (Lisp_Object *));
883 write (pdump_fd, &res, sizeof (res)); 933 write (pdump_fd, &obj, sizeof (obj));
884 } 934 }
885 } 935 }
886 936
887 void 937 void
888 pdump (void) 938 pdump (void)
889 { 939 {
890 int i; 940 int i;
891 Lisp_Object t_console, t_device, t_frame; 941 Lisp_Object t_console, t_device, t_frame;
892 int none; 942 int none;
893 dump_header hd; 943 pdump_header hd;
894 944
895 flush_all_buffer_local_cache (); 945 flush_all_buffer_local_cache ();
896 946
897 /* These appear in a DEFVAR_LISP, which does a staticpro() */ 947 /* These appear in a DEFVAR_LISP, which does a staticpro() */
898 t_console = Vterminal_console; 948 t_console = Vterminal_console; Vterminal_console = Qnil;
899 t_frame = Vterminal_frame; 949 t_frame = Vterminal_frame; Vterminal_frame = Qnil;
900 t_device = Vterminal_device; 950 t_device = Vterminal_device; Vterminal_device = Qnil;
901 951
902 Vterminal_console = Qnil; 952 dump_add_opaque (&lrecord_implementations_table,
903 Vterminal_frame = Qnil; 953 lrecord_type_count * sizeof (lrecord_implementations_table[0]));
904 Vterminal_device = Qnil; 954 dump_add_opaque (&lrecord_markers,
955 lrecord_type_count * sizeof (lrecord_markers[0]));
905 956
906 pdump_hash = xnew_array_and_zero (pdump_entry_list_elmt *, PDUMP_HASHSIZE); 957 pdump_hash = xnew_array_and_zero (pdump_entry_list_elmt *, PDUMP_HASHSIZE);
907 958
908 for (i=0; i<lrecord_type_count; i++) 959 for (i=0; i<lrecord_type_count; i++)
909 { 960 {
918 pdump_opaque_data_list.first = 0; 969 pdump_opaque_data_list.first = 0;
919 pdump_opaque_data_list.align = 8; 970 pdump_opaque_data_list.align = 8;
920 pdump_opaque_data_list.count = 0; 971 pdump_opaque_data_list.count = 0;
921 depth = 0; 972 depth = 0;
922 973
923 for (i=0; i<staticidx; i++) 974 for (i=0; i<Dynarr_length (pdump_root_objects); i++)
924 pdump_register_object (*staticvec[i]); 975 pdump_register_object (* Dynarr_at (pdump_root_objects, i));
925 for (i=0; i<pdump_wireidx; i++)
926 pdump_register_object (*pdump_wirevec[i]);
927 976
928 none = 1; 977 none = 1;
929 for (i=0; i<lrecord_type_count; i++) 978 for (i=0; i<lrecord_type_count; i++)
930 if (pdump_alert_undump_object[i]) 979 if (pdump_alert_undump_object[i])
931 { 980 {
935 printf (" - %s (%d)\n", lrecord_implementations_table[i]->name, pdump_alert_undump_object[i]); 984 printf (" - %s (%d)\n", lrecord_implementations_table[i]->name, pdump_alert_undump_object[i]);
936 } 985 }
937 if (!none) 986 if (!none)
938 return; 987 return;
939 988
940 for (i=0; i<dumpstructidx; i++) 989 for (i=0; i<Dynarr_length (pdump_root_struct_ptrs); i++)
941 pdump_register_struct (*(void **)(dumpstructvec[i].data), dumpstructvec[i].desc, 1); 990 {
942 991 pdump_root_struct_ptr info = Dynarr_at (pdump_root_struct_ptrs, i);
943 memcpy (hd.signature, DUMP_SIGNATURE, DUMP_SIGNATURE_LEN); 992 pdump_register_struct (*(info.ptraddress), info.desc, 1);
993 }
994
995 memcpy (hd.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN);
944 hd.id = dump_id; 996 hd.id = dump_id;
945 hd.reloc_address = 0; 997 hd.reloc_address = 0;
946 hd.nb_staticpro = staticidx; 998 hd.nb_root_struct_ptrs = Dynarr_length (pdump_root_struct_ptrs);
947 hd.nb_structdmp = dumpstructidx; 999 hd.nb_opaques = Dynarr_length (pdump_opaques);
948 hd.nb_opaquedmp = dumpopaqueidx;
949 1000
950 cur_offset = 256; 1001 cur_offset = 256;
951 max_size = 0; 1002 max_size = 0;
952 1003
953 pdump_scan_by_alignment (pdump_allocate_offset); 1004 pdump_scan_by_alignment (pdump_allocate_offset);
964 1015
965 pdump_scan_by_alignment (pdump_dump_data); 1016 pdump_scan_by_alignment (pdump_dump_data);
966 1017
967 lseek (pdump_fd, hd.stab_offset, SEEK_SET); 1018 lseek (pdump_fd, hd.stab_offset, SEEK_SET);
968 1019
969 pdump_dump_staticvec (); 1020 pdump_dump_from_root_struct_ptrs ();
970 pdump_dump_structvec (); 1021 pdump_dump_opaques ();
971 pdump_dump_opaquevec ();
972 pdump_dump_itable ();
973 pdump_dump_rtables (); 1022 pdump_dump_rtables ();
974 pdump_dump_wired (); 1023 pdump_dump_from_root_objects ();
975 1024
976 close (pdump_fd); 1025 close (pdump_fd);
977 free (pdump_buf); 1026 free (pdump_buf);
978 1027
979 free (pdump_hash); 1028 free (pdump_hash);
981 Vterminal_console = t_console; 1030 Vterminal_console = t_console;
982 Vterminal_frame = t_frame; 1031 Vterminal_frame = t_frame;
983 Vterminal_device = t_device; 1032 Vterminal_device = t_device;
984 } 1033 }
985 1034
986 static int pdump_load_check (void) 1035 static int
987 { 1036 pdump_load_check (void)
988 return (!memcmp (((dump_header *)pdump_start)->signature, DUMP_SIGNATURE, DUMP_SIGNATURE_LEN) 1037 {
989 && ((dump_header *)pdump_start)->id == dump_id); 1038 return (!memcmp (((pdump_header *)pdump_start)->signature,
990 } 1039 PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN)
991 1040 && ((pdump_header *)pdump_start)->id == dump_id);
992 static int pdump_load_finish (void) 1041 }
1042
1043 static int
1044 pdump_load_finish (void)
993 { 1045 {
994 int i; 1046 int i;
995 char *p; 1047 char *p;
996 EMACS_INT delta; 1048 EMACS_INT delta;
997 EMACS_INT count; 1049 EMACS_INT count;
998 1050
999 pdump_end = pdump_start + pdump_length; 1051 pdump_end = pdump_start + pdump_length;
1000 1052
1001 #define PDUMP_READ(p, type) (p = (char*) (((type *) p) + 1), *((type *) p - 1)) 1053 #define PDUMP_READ(p, type) (p = (char*) (((type *) p) + 1), *((type *) p - 1))
1002 1054
1003 staticidx = ((dump_header *)(pdump_start))->nb_staticpro; 1055 delta = ((EMACS_INT)pdump_start) - ((pdump_header *)pdump_start)->reloc_address;
1004 delta = ((EMACS_INT)pdump_start) - ((dump_header *)pdump_start)->reloc_address; 1056 p = pdump_start + ((pdump_header *)pdump_start)->stab_offset;
1005 p = pdump_start + ((dump_header *)pdump_start)->stab_offset; 1057
1006 1058 /* Put back the pdump_root_struct_ptrs */
1007 /* Put back the staticvec in place */ 1059 for (i=0; i<((pdump_header *)pdump_start)->nb_root_struct_ptrs; i++)
1008 memcpy (staticvec, p, staticidx*sizeof (Lisp_Object *));
1009 p += staticidx*sizeof (Lisp_Object *);
1010 for (i=0; i<staticidx; i++)
1011 {
1012 Lisp_Object obj = PDUMP_READ (p, Lisp_Object);
1013 if (POINTER_TYPE_P (XTYPE (obj)))
1014 XSETOBJ (obj, (char *) XPNTR (obj) + delta);
1015 *staticvec[i] = obj;
1016 }
1017
1018 /* Put back the dumpstructs */
1019 for (i=0; i<((dump_header *)pdump_start)->nb_structdmp; i++)
1020 { 1060 {
1021 void **adr = PDUMP_READ (p, void **); 1061 void **adr = PDUMP_READ (p, void **);
1022 *adr = (void *) (PDUMP_READ (p, char *) + delta); 1062 *adr = (void *) (PDUMP_READ (p, char *) + delta);
1023 } 1063 }
1024 1064
1025 /* Put back the opaques */ 1065 /* Put back the pdump_opaques */
1026 for (i=0; i<((dump_header *)pdump_start)->nb_opaquedmp; i++) 1066 for (i=0; i<((pdump_header *)pdump_start)->nb_opaques; i++)
1027 { 1067 {
1028 struct pdump_dumpopaqueinfo di = PDUMP_READ (p, struct pdump_dumpopaqueinfo); 1068 pdump_opaque info = PDUMP_READ (p, pdump_opaque);
1029 memcpy (di.data, p, di.size); 1069 memcpy (info.varaddress, p, info.size);
1030 p += di.size; 1070 p += info.size;
1031 } 1071 }
1032
1033 /* Put back the lrecord_implementations_table */
1034 /* The (void *) cast is there to make Ben happy. */
1035 memcpy ((void *) lrecord_implementations_table, p, lrecord_type_count*sizeof (lrecord_implementations_table[0]));
1036 p += lrecord_type_count*sizeof (lrecord_implementations_table[0]);
1037
1038 /* Reinitialize lrecord_markers from lrecord_implementations_table */
1039 for (i=0; i < lrecord_type_count; i++)
1040 if (lrecord_implementations_table[i])
1041 lrecord_markers[i] = lrecord_implementations_table[i]->marker;
1042 1072
1043 /* Do the relocations */ 1073 /* Do the relocations */
1044 pdump_rt_list = p; 1074 pdump_rt_list = p;
1045 count = 2; 1075 count = 2;
1046 for (;;) 1076 for (;;)
1058 } else 1088 } else
1059 if (!(--count)) 1089 if (!(--count))
1060 break; 1090 break;
1061 } 1091 }
1062 1092
1063 /* Put the pdump_wire variables in place */ 1093 /* Put the pdump_root_objects variables in place */
1064 count = PDUMP_READ (p, EMACS_INT); 1094 for (i = PDUMP_READ (p, size_t); i; i--)
1065
1066 for (i=0; i<count; i++)
1067 { 1095 {
1068 Lisp_Object *var = PDUMP_READ (p, Lisp_Object *); 1096 Lisp_Object *var = PDUMP_READ (p, Lisp_Object *);
1069 Lisp_Object obj = PDUMP_READ (p, Lisp_Object); 1097 Lisp_Object obj = PDUMP_READ (p, Lisp_Object);
1070 1098
1071 if (POINTER_TYPE_P (XTYPE (obj))) 1099 if (POINTER_TYPE_P (XTYPE (obj)))
1072 XSETOBJ (obj, (char *) XPNTR (obj) + delta); 1100 obj = wrap_object ((char *) XPNTR (obj) + delta);
1073 1101
1074 *var = obj; 1102 *var = obj;
1075 } 1103 }
1076 1104
1077 /* Final cleanups */ 1105 /* Final cleanups */
1094 return 1; 1122 return 1;
1095 } 1123 }
1096 1124
1097 #ifdef WIN32_NATIVE 1125 #ifdef WIN32_NATIVE
1098 /* Free the mapped file if we decide we don't want it after all */ 1126 /* Free the mapped file if we decide we don't want it after all */
1099 static void pdump_file_unmap(void) 1127 static void
1128 pdump_file_unmap (void)
1100 { 1129 {
1101 UnmapViewOfFile (pdump_start); 1130 UnmapViewOfFile (pdump_start);
1102 CloseHandle (pdump_hFile); 1131 CloseHandle (pdump_hFile);
1103 CloseHandle (pdump_hMap); 1132 CloseHandle (pdump_hMap);
1104 } 1133 }
1105 1134
1106 static int pdump_file_get(const char *path) 1135 static int
1136 pdump_file_get (const char *path)
1107 { 1137 {
1108 1138
1109 pdump_hFile = CreateFile (path, 1139 pdump_hFile = CreateFile (path,
1110 GENERIC_READ + GENERIC_WRITE, /* Required for copy on write */ 1140 GENERIC_READ + GENERIC_WRITE, /* Required for copy on write */
1111 0, /* Not shared */ 1141 0, /* Not shared */
1125 NULL); /* Unnamed */ 1155 NULL); /* Unnamed */
1126 if (pdump_hMap == INVALID_HANDLE_VALUE) 1156 if (pdump_hMap == INVALID_HANDLE_VALUE)
1127 return 0; 1157 return 0;
1128 1158
1129 pdump_start = MapViewOfFile (pdump_hMap, 1159 pdump_start = MapViewOfFile (pdump_hMap,
1130 FILE_MAP_COPY, /* Copy on write */ 1160 FILE_MAP_COPY, /* Copy on write */
1131 0, /* Start at zero */ 1161 0, /* Start at zero */
1132 0, 1162 0,
1133 0); /* Map all of it */ 1163 0); /* Map all of it */
1134 pdump_free = pdump_file_unmap; 1164 pdump_free = pdump_file_unmap;
1135 return 1; 1165 return 1;
1138 /* pdump_resource_free is called (via the pdump_free pointer) to release 1168 /* pdump_resource_free is called (via the pdump_free pointer) to release
1139 any resources allocated by pdump_resource_get. Since the Windows API 1169 any resources allocated by pdump_resource_get. Since the Windows API
1140 specs specifically state that you don't need to (and shouldn't) free the 1170 specs specifically state that you don't need to (and shouldn't) free the
1141 resources allocated by FindResource, LoadResource, and LockResource this 1171 resources allocated by FindResource, LoadResource, and LockResource this
1142 routine does nothing. */ 1172 routine does nothing. */
1143 static void pdump_resource_free (void) 1173 static void
1144 { 1174 pdump_resource_free (void)
1145 } 1175 {
1146 1176 }
1147 static int pdump_resource_get (void) 1177
1148 { 1178 static int
1149 HRSRC hRes; /* Handle to dump resource */ 1179 pdump_resource_get (void)
1150 HRSRC hResLoad; /* Handle to loaded dump resource */ 1180 {
1181 HRSRC hRes; /* Handle to dump resource */
1182 HRSRC hResLoad; /* Handle to loaded dump resource */
1151 1183
1152 /* See Q126630 which describes how Windows NT and 95 trap writes to 1184 /* See Q126630 which describes how Windows NT and 95 trap writes to
1153 resource sections and duplicate the page to allow the write to proceed. 1185 resource sections and duplicate the page to allow the write to proceed.
1154 It also describes how to make the resource section read/write (and hence 1186 It also describes how to make the resource section read/write (and hence
1155 private to each process). Doing this avoids the exceptions and related 1187 private to each process). Doing this avoids the exceptions and related
1171 if (pdump_start == NULL) 1203 if (pdump_start == NULL)
1172 return 0; 1204 return 0;
1173 1205
1174 pdump_free = pdump_resource_free; 1206 pdump_free = pdump_resource_free;
1175 pdump_length = SizeofResource (NULL, hRes); 1207 pdump_length = SizeofResource (NULL, hRes);
1176 if (pdump_length <= sizeof(dump_header)) 1208 if (pdump_length <= sizeof (pdump_header))
1177 { 1209 {
1178 pdump_start = 0; 1210 pdump_start = 0;
1179 return 0; 1211 return 0;
1180 } 1212 }
1181 1213
1184 1216
1185 #else /* !WIN32_NATIVE */ 1217 #else /* !WIN32_NATIVE */
1186 1218
1187 static void *pdump_mallocadr; 1219 static void *pdump_mallocadr;
1188 1220
1189 static void pdump_file_free(void) 1221 static void
1222 pdump_file_free (void)
1190 { 1223 {
1191 xfree (pdump_mallocadr); 1224 xfree (pdump_mallocadr);
1192 } 1225 }
1193 1226
1194 #ifdef HAVE_MMAP 1227 #ifdef HAVE_MMAP
1195 static void pdump_file_unmap(void) 1228 static void
1229 pdump_file_unmap (void)
1196 { 1230 {
1197 munmap (pdump_start, pdump_length); 1231 munmap (pdump_start, pdump_length);
1198 } 1232 }
1199 #endif 1233 #endif
1200 1234
1201 static int pdump_file_get(const char *path) 1235 static int
1236 pdump_file_get (const char *path)
1202 { 1237 {
1203 int fd = open (path, O_RDONLY | OPEN_BINARY); 1238 int fd = open (path, O_RDONLY | OPEN_BINARY);
1204 if (fd<0) 1239 if (fd<0)
1205 return 0; 1240 return 0;
1206 1241
1207 pdump_length = lseek (fd, 0, SEEK_END); 1242 pdump_length = lseek (fd, 0, SEEK_END);
1208 if (pdump_length < sizeof (dump_header)) 1243 if (pdump_length < sizeof (pdump_header))
1209 { 1244 {
1210 close (fd); 1245 close (fd);
1211 return 0; 1246 return 0;
1212 } 1247 }
1213 1248
1214 lseek (fd, 0, SEEK_SET); 1249 lseek (fd, 0, SEEK_SET);
1215 1250
1216 #ifdef HAVE_MMAP 1251 #ifdef HAVE_MMAP
1217 pdump_start = (char *) mmap (0, pdump_length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); 1252 pdump_start = (char *) mmap (0, pdump_length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
1218 if (pdump_start != MAP_FAILED) 1253 if (pdump_start != (char *) MAP_FAILED)
1219 { 1254 {
1220 pdump_free = pdump_file_unmap; 1255 pdump_free = pdump_file_unmap;
1221 close (fd); 1256 close (fd);
1222 return 1; 1257 return 1;
1223 } 1258 }
1224 #endif 1259 #endif
1225 1260
1226 pdump_mallocadr = xmalloc(pdump_length+255); 1261 pdump_mallocadr = xmalloc (pdump_length+255);
1227 pdump_free = pdump_file_free; 1262 pdump_free = pdump_file_free;
1228 pdump_start = (char *)((255 + (unsigned long)pdump_mallocadr) & ~255); 1263 pdump_start = (char *)((255 + (unsigned long)pdump_mallocadr) & ~255);
1229 read (fd, pdump_start, pdump_length); 1264 read (fd, pdump_start, pdump_length);
1230 1265
1231 close (fd); 1266 close (fd);
1232 return 1; 1267 return 1;
1233 } 1268 }
1234 #endif /* !WIN32_NATIVE */ 1269 #endif /* !WIN32_NATIVE */
1235 1270
1236 1271
1237 static int pdump_file_try(char *exe_path) 1272 static int
1273 pdump_file_try (char *exe_path)
1238 { 1274 {
1239 char *w; 1275 char *w;
1240 1276
1241 w = exe_path + strlen(exe_path); 1277 w = exe_path + strlen (exe_path);
1242 do 1278 do
1243 { 1279 {
1244 sprintf (w, "-%s-%08x.dmp", EMACS_VERSION, dump_id); 1280 sprintf (w, "-%s-%08x.dmp", EMACS_VERSION, dump_id);
1245 if (pdump_file_get (exe_path)) 1281 if (pdump_file_get (exe_path))
1246 { 1282 {
1247 if (pdump_load_check ()) 1283 if (pdump_load_check ())
1248 return 1; 1284 return 1;
1249 pdump_free(); 1285 pdump_free ();
1250 } 1286 }
1251 1287
1252 sprintf (w, "-%08x.dmp", dump_id); 1288 sprintf (w, "-%08x.dmp", dump_id);
1253 if (pdump_file_get (exe_path)) 1289 if (pdump_file_get (exe_path))
1254 { 1290 {
1255 if (pdump_load_check ()) 1291 if (pdump_load_check ())
1256 return 1; 1292 return 1;
1257 pdump_free(); 1293 pdump_free ();
1258 } 1294 }
1259 1295
1260 sprintf (w, ".dmp"); 1296 sprintf (w, ".dmp");
1261 if (pdump_file_get (exe_path)) 1297 if (pdump_file_get (exe_path))
1262 { 1298 {
1263 if (pdump_load_check ()) 1299 if (pdump_load_check ())
1264 return 1; 1300 return 1;
1265 pdump_free(); 1301 pdump_free ();
1266 } 1302 }
1267 1303
1268 do 1304 do
1269 w--; 1305 w--;
1270 while (w>exe_path && !IS_DIRECTORY_SEP (*w) && (*w != '-') && (*w != '.')); 1306 while (w>exe_path && !IS_DIRECTORY_SEP (*w) && (*w != '-') && (*w != '.'));
1271 } 1307 }
1272 while (w>exe_path && !IS_DIRECTORY_SEP (*w)); 1308 while (w>exe_path && !IS_DIRECTORY_SEP (*w));
1273 return 0; 1309 return 0;
1274 } 1310 }
1275 1311
1276 int pdump_load(const char *argv0) 1312 int
1313 pdump_load (const char *argv0)
1277 { 1314 {
1278 char exe_path[PATH_MAX]; 1315 char exe_path[PATH_MAX];
1279 #ifdef WIN32_NATIVE 1316 #ifdef WIN32_NATIVE
1280 GetModuleFileName (NULL, exe_path, PATH_MAX); 1317 GetModuleFileName (NULL, exe_path, PATH_MAX);
1281 #else /* !WIN32_NATIVE */ 1318 #else /* !WIN32_NATIVE */
1284 1321
1285 dir = argv0; 1322 dir = argv0;
1286 if (dir[0] == '-') 1323 if (dir[0] == '-')
1287 { 1324 {
1288 /* XEmacs as a login shell, oh goody! */ 1325 /* XEmacs as a login shell, oh goody! */
1289 dir = getenv("SHELL"); 1326 dir = getenv ("SHELL");
1290 } 1327 }
1291 1328
1292 p = dir + strlen(dir); 1329 p = dir + strlen (dir);
1293 while (p != dir && !IS_ANY_SEP (p[-1])) p--; 1330 while (p != dir && !IS_ANY_SEP (p[-1])) p--;
1294 1331
1295 if (p != dir) 1332 if (p != dir)
1296 { 1333 {
1297 /* invocation-name includes a directory component -- presumably it 1334 /* invocation-name includes a directory component -- presumably it
1319 } 1356 }
1320 if (!IS_DIRECTORY_SEP (w[-1])) 1357 if (!IS_DIRECTORY_SEP (w[-1]))
1321 { 1358 {
1322 *w++ = '/'; 1359 *w++ = '/';
1323 } 1360 }
1324 strcpy(w, name); 1361 strcpy (w, name);
1325 1362
1326 /* ### #$%$#^$^@%$^#%@$ ! */ 1363 /* ### #$%$#^$^@%$^#%@$ ! */
1327 #ifdef access 1364 #ifdef access
1328 #undef access 1365 #undef access
1329 #endif 1366 #endif