1 /* Portable data dumper for SXEmacs.
2 Copyright (C) 1999-2000 Olivier Galibert
3 Copyright (C) 2001 Martin Buchholz
5 This file is part of SXEmacs
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* Synched up with: Not in FSF. */
26 #include "specifier.h"
29 #include "ui/console-stream.h"
38 #include <sxe-paths.h>
50 Dynarr_declare(pdump_opaque);
51 } pdump_opaque_dynarr;
55 const struct struct_description *desc;
56 } pdump_root_struct_ptr;
59 Dynarr_declare(pdump_root_struct_ptr);
60 } pdump_root_struct_ptr_dynarr;
65 } pdump_static_Lisp_Object;
68 char **address; /* char * for ease of doing relocation */
70 } pdump_static_pointer;
72 static pdump_opaque_dynarr *pdump_opaques;
73 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs;
74 static Lisp_Object_ptr_dynarr *pdump_root_objects;
75 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains;
77 /* Mark SIZE bytes at non-heap address VARADDRESS for dumping as is,
78 without any bit-twiddling. */
79 void dump_add_opaque(void *varaddress, size_t size)
82 info.varaddress = varaddress;
84 if (pdump_opaques == NULL)
85 pdump_opaques = Dynarr_new(pdump_opaque);
86 Dynarr_add(pdump_opaques, info);
89 /* Mark the struct described by DESC and pointed to by the pointer at
90 non-heap address VARADDRESS for dumping.
91 All the objects reachable from this pointer will also be dumped. */
93 dump_add_root_struct_ptr(void *ptraddress,
94 const struct struct_description *desc)
96 pdump_root_struct_ptr info;
97 info.ptraddress = (void **)ptraddress;
99 if (pdump_root_struct_ptrs == NULL)
100 pdump_root_struct_ptrs = Dynarr_new(pdump_root_struct_ptr);
101 Dynarr_add(pdump_root_struct_ptrs, info);
104 /* Mark the Lisp_Object at non-heap address VARADDRESS for dumping.
105 All the objects reachable from this var will also be dumped. */
106 void dump_add_root_object(Lisp_Object * varaddress)
108 if (pdump_root_objects == NULL)
110 Dynarr_new2(Lisp_Object_ptr_dynarr, Lisp_Object *);
111 Dynarr_add(pdump_root_objects, varaddress);
114 /* Mark the list pointed to by the Lisp_Object at VARADDRESS for dumping. */
115 void dump_add_weak_object_chain(Lisp_Object * varaddress)
117 if (pdump_weak_object_chains == NULL)
118 pdump_weak_object_chains =
119 Dynarr_new2(Lisp_Object_ptr_dynarr, Lisp_Object *);
120 Dynarr_add(pdump_weak_object_chains, varaddress);
123 inline static void pdump_align_stream(FILE * stream, size_t alignment)
125 long offset = ftell(stream);
126 long adjustment = ALIGN_SIZE(offset, alignment) - offset;
128 fseek(stream, adjustment, SEEK_CUR);
131 #define PDUMP_ALIGN_OUTPUT(type) pdump_align_stream (pdump_out, ALIGNOF (type))
133 #define PDUMP_WRITE(type, object) \
134 fwrite (&object, sizeof (object), 1, pdump_out);
136 #define PDUMP_WRITE_ALIGNED(type, object) do { \
137 PDUMP_ALIGN_OUTPUT (type); \
138 PDUMP_WRITE (type, object); \
141 #define PDUMP_READ(ptr, type) \
142 (((type *) (ptr = (char*) (((type *) ptr) + 1)))[-1])
144 #define PDUMP_READ_ALIGNED(ptr, type) \
145 ((ptr = (char *) ALIGN_PTR (ptr, ALIGNOF (type))), PDUMP_READ (ptr, type))
148 const struct lrecord_description *desc;
152 static char *pdump_rt_list = 0;
154 void pdump_objects_unmark(void)
157 char *p = pdump_rt_list;
160 pdump_reloc_table *rt = (pdump_reloc_table *) p;
161 p += sizeof(pdump_reloc_table);
163 for (i = 0; i < rt->count; i++) {
164 struct lrecord_header *lh =
165 *(struct lrecord_header **)p;
166 if (!C_READONLY_RECORD_HEADER_P(lh))
167 UNMARK_RECORD_HEADER(lh);
168 p += sizeof(EMACS_INT);
175 /* The structure of the file
178 stab_offset - nb_root_struct_ptrs*pair(void *, adr)
179 for pointers to structures
180 - nb_opaques*pair(void *, size) for raw bits to restore
182 - root lisp object address/value couples with the count
186 #define PDUMP_SIGNATURE "SXEmacsDP"
187 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1)
190 char signature[PDUMP_SIGNATURE_LEN];
192 EMACS_UINT stab_offset;
193 EMACS_UINT reloc_address;
194 int nb_root_struct_ptrs;
200 static off_t pdump_length;
203 static void (*pdump_free) (void);
205 static unsigned char pdump_align_table[] = {
206 64, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1,
207 16, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1,
208 32, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1,
209 16, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1
212 static inline unsigned int pdump_size_to_align(size_t size)
214 return pdump_align_table[size % countof(pdump_align_table)];
217 typedef struct pdump_entry_list_elt {
218 struct pdump_entry_list_elt *next;
222 EMACS_INT save_offset;
223 } pdump_entry_list_elt;
226 pdump_entry_list_elt *first;
231 typedef struct pdump_struct_list_elt {
232 pdump_entry_list list;
233 const struct struct_description *sdesc;
234 } pdump_struct_list_elt;
237 pdump_struct_list_elt *list;
242 static pdump_entry_list *pdump_object_table;
243 static pdump_entry_list pdump_opaque_data_list;
244 static pdump_struct_list pdump_struct_table;
246 static int *pdump_alert_undump_object;