Mercurial > hg > xemacs-beta
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 |