X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fdumper.c;h=e0b4ad8c3a7221f725253f39d4145edab25a19b7;hp=4118809844860e44d6ff1bf2f422df0ba124a5d6;hb=6e8f204c9e1f490b2752de46c111744d1deb3ee0;hpb=0c693dc08f0794304711787b2eb47c144ea4bef1 diff --git a/src/dumper.c b/src/dumper.c index 4118809..e0b4ad8 100644 --- a/src/dumper.c +++ b/src/dumper.c @@ -1,5 +1,6 @@ /* Portable data dumper for XEmacs. Copyright (C) 1999-2000 Olivier Galibert + Copyright (C) 2001 Martin Buchholz This file is part of XEmacs. @@ -23,12 +24,12 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include "dump-id.h" #include "specifier.h" #include "elhash.h" #include "sysfile.h" #include "console-stream.h" #include "dumper.h" +#include "sysdep.h" #ifdef WIN32_NATIVE #include "nt.h" @@ -64,6 +65,18 @@ typedef struct Dynarr_declare (pdump_root_struct_ptr); } pdump_root_struct_ptr_dynarr; +typedef struct +{ + Lisp_Object *address; + Lisp_Object value; +} pdump_static_Lisp_Object; + +typedef struct +{ + char **address; /* char * for ease of doing relocation */ + char * value; +} pdump_static_pointer; + static pdump_opaque_dynarr *pdump_opaques; static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs; static Lisp_Object_ptr_dynarr *pdump_root_objects; @@ -116,6 +129,33 @@ dump_add_weak_object_chain (Lisp_Object *varaddress) } +inline static void +pdump_align_stream (FILE *stream, size_t alignment) +{ + long offset = ftell (stream); + long adjustment = ALIGN_SIZE (offset, alignment) - offset; + if (adjustment) + fseek (stream, adjustment, SEEK_CUR); +} + +#define PDUMP_ALIGN_OUTPUT(type) pdump_align_stream (pdump_out, ALIGNOF (type)) + +#define PDUMP_WRITE(type, object) \ +fwrite (&object, sizeof (object), 1, pdump_out); + +#define PDUMP_WRITE_ALIGNED(type, object) do { \ + PDUMP_ALIGN_OUTPUT (type); \ + PDUMP_WRITE (type, object); \ +} while (0) + +#define PDUMP_READ(ptr, type) \ +(((type *) (ptr = (char*) (((type *) ptr) + 1)))[-1]) + +#define PDUMP_READ_ALIGNED(ptr, type) \ +((ptr = (char *) ALIGN_PTR (ptr, ALIGNOF (type))), PDUMP_READ (ptr, type)) + + + typedef struct { const struct lrecord_description *desc; @@ -150,13 +190,14 @@ pdump_objects_unmark (void) /* The structure of the file - * - * 0 - header - * 256 - dumped objects - * stab_offset - nb_root_struct_ptrs*pair(void *, adr) for pointers to structures - * - nb_opaques*pair(void *, size) for raw bits to restore - * - relocation table - * - wired variable address/value couples with the count preceding the list + 0 - header + - dumped objects + stab_offset - nb_root_struct_ptrs*pair(void *, adr) + for pointers to structures + - nb_opaques*pair(void *, size) for raw bits to restore + - relocation table + - root lisp object address/value couples with the count + preceding the list */ @@ -173,82 +214,81 @@ typedef struct int nb_opaques; } pdump_header; -char *pdump_start, *pdump_end; +char *pdump_start; +char *pdump_end; static size_t pdump_length; #ifdef WIN32_NATIVE /* Handle for the dump file */ -HANDLE pdump_hFile = INVALID_HANDLE_VALUE; +static HANDLE pdump_hFile = INVALID_HANDLE_VALUE; /* Handle for the file mapping object for the dump file */ -HANDLE pdump_hMap = INVALID_HANDLE_VALUE; +static HANDLE pdump_hMap = INVALID_HANDLE_VALUE; #endif -void (*pdump_free) (void); +static void (*pdump_free) (void); -static const unsigned char pdump_align_table[256] = +static unsigned char pdump_align_table[] = { - 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 + 64, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1, + 16, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1, + 32, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1, + 16, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1 }; -typedef struct pdump_entry_list_elmt +static inline unsigned int +pdump_size_to_align (size_t size) +{ + return pdump_align_table[size % countof (pdump_align_table)]; +} + +typedef struct pdump_entry_list_elt { - struct pdump_entry_list_elmt *next; + struct pdump_entry_list_elt *next; const void *obj; size_t size; int count; - int is_lrecord; EMACS_INT save_offset; -} pdump_entry_list_elmt; +} pdump_entry_list_elt; typedef struct { - pdump_entry_list_elmt *first; + pdump_entry_list_elt *first; int align; int count; } pdump_entry_list; -typedef struct pdump_struct_list_elmt +typedef struct pdump_struct_list_elt { pdump_entry_list list; const struct struct_description *sdesc; -} pdump_struct_list_elmt; +} pdump_struct_list_elt; typedef struct { - pdump_struct_list_elmt *list; + pdump_struct_list_elt *list; int count; int size; } pdump_struct_list; -static pdump_entry_list pdump_object_table[256]; +static pdump_entry_list *pdump_object_table; static pdump_entry_list pdump_opaque_data_list; static pdump_struct_list pdump_struct_table; -static int pdump_alert_undump_object[256]; +static int *pdump_alert_undump_object; static unsigned long cur_offset; static size_t max_size; static int pdump_fd; static void *pdump_buf; +static FILE *pdump_out; +#ifdef UTF2000 +#define PDUMP_HASHSIZE 20000001 +#else #define PDUMP_HASHSIZE 200001 +#endif -static pdump_entry_list_elmt **pdump_hash; +static pdump_entry_list_elt **pdump_hash; /* Since most pointers are eight bytes aligned, the >>3 allows for a better hash */ static int @@ -257,11 +297,11 @@ pdump_make_hash (const void *obj) return ((unsigned long)(obj)>>3) % PDUMP_HASHSIZE; } -static pdump_entry_list_elmt * +static pdump_entry_list_elt * pdump_get_entry (const void *obj) { int pos = pdump_make_hash (obj); - pdump_entry_list_elmt *e; + pdump_entry_list_elt *e; assert (obj != 0); @@ -278,10 +318,10 @@ pdump_get_entry (const void *obj) } static void -pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, int count, int is_lrecord) +pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, + int count) { - pdump_entry_list_elmt *e; - int align; + pdump_entry_list_elt *e; int pos = pdump_make_hash (obj); while ((e = pdump_hash[pos]) != 0) @@ -294,24 +334,23 @@ pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, int count pos = 0; } - e = xnew (pdump_entry_list_elmt); + e = xnew (pdump_entry_list_elt); e->next = list->first; e->obj = obj; e->size = size; e->count = count; - e->is_lrecord = is_lrecord; list->first = e; list->count += count; pdump_hash[pos] = e; - align = pdump_align_table[size & 255]; - if (align < 2 && is_lrecord) - align = 2; + { + int align = pdump_size_to_align (size); - if (align < list->align) - list->align = align; + if (align < list->align) + list->align = align; + } } static pdump_entry_list * @@ -328,12 +367,12 @@ pdump_get_entry_list (const struct struct_description *sdesc) pdump_struct_table.size = 10; else pdump_struct_table.size = pdump_struct_table.size * 2; - pdump_struct_table.list = (pdump_struct_list_elmt *) + pdump_struct_table.list = (pdump_struct_list_elt *) xrealloc (pdump_struct_table.list, - pdump_struct_table.size * sizeof (pdump_struct_list_elmt)); + pdump_struct_table.size * sizeof (pdump_struct_list_elt)); } pdump_struct_table.list[pdump_struct_table.count].list.first = 0; - pdump_struct_table.list[pdump_struct_table.count].list.align = 8; + pdump_struct_table.list[pdump_struct_table.count].list.align = ALIGNOF (max_align_t); pdump_struct_table.list[pdump_struct_table.count].list.count = 0; pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc; @@ -357,7 +396,9 @@ pdump_backtrace (void) for (i=0;i 0) - pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0); + pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1); break; } case XD_LISP_OBJECT: @@ -501,7 +544,7 @@ pdump_register_sub (const void *data, const struct lrecord_description *desc, in default: stderr_out ("Unsupported dump type : %d\n", desc[pos].type); pdump_backtrace (); - abort (); + ABORT (); }; } } @@ -510,6 +553,7 @@ static void pdump_register_object (Lisp_Object obj) { struct lrecord_header *objh; + const struct lrecord_implementation *imp; if (!POINTER_TYPE_P (XTYPE (obj))) return; @@ -521,13 +565,15 @@ pdump_register_object (Lisp_Object obj) if (pdump_get_entry (objh)) return; - if (LHEADER_IMPLEMENTATION (objh)->description) + imp = LHEADER_IMPLEMENTATION (objh); + + if (imp->description) { int me = depth++; if (me>65536) { stderr_out ("Backtrace overflow, loop ?\n"); - abort (); + ABORT (); } backtrace[me].obj = objh; backtrace[me].position = 0; @@ -535,26 +581,25 @@ pdump_register_object (Lisp_Object obj) pdump_add_entry (pdump_object_table + objh->type, objh, - LHEADER_IMPLEMENTATION (objh)->static_size ? - LHEADER_IMPLEMENTATION (objh)->static_size : - LHEADER_IMPLEMENTATION (objh)->size_in_bytes_method (objh), - 1, + imp->static_size ? + imp->static_size : + imp->size_in_bytes_method (objh), 1); - pdump_register_sub (objh, - LHEADER_IMPLEMENTATION (objh)->description, - me); + pdump_register_sub (objh, imp->description, me); --depth; } else { pdump_alert_undump_object[objh->type]++; - stderr_out ("Undumpable object type : %s\n", LHEADER_IMPLEMENTATION (objh)->name); + stderr_out ("Undumpable object type : %s\n", imp->name); pdump_backtrace (); } } static void -pdump_register_struct (const void *data, const struct struct_description *sdesc, int count) +pdump_register_struct (const void *data, + const struct struct_description *sdesc, + int count) { if (data && !pdump_get_entry (data)) { @@ -563,17 +608,14 @@ pdump_register_struct (const void *data, const struct struct_description *sdesc, if (me>65536) { stderr_out ("Backtrace overflow, loop ?\n"); - abort (); + ABORT (); } backtrace[me].obj = 0; backtrace[me].position = 0; backtrace[me].offset = 0; pdump_add_entry (pdump_get_entry_list (sdesc), - data, - sdesc->size, - count, - 0); + data, sdesc->size, count); for (i=0; isize*i, @@ -585,14 +627,15 @@ pdump_register_struct (const void *data, const struct struct_description *sdesc, } static void -pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc) +pdump_dump_data (pdump_entry_list_elt *elt, + const struct lrecord_description *desc) { - size_t size = elmt->size; - int count = elmt->count; + size_t size = elt->size; + int count = elt->count; if (desc) { int pos, i; - memcpy (pdump_buf, elmt->obj, size*count); + memcpy (pdump_buf, elt->obj, size*count); for (i=0; iobj))->methods->extra_description; + desc = ((const Lisp_Specifier *)(elt->obj))->methods->extra_description; goto restart; case XD_SIZE_T: case XD_INT: @@ -615,7 +658,7 @@ pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description * { EMACS_INT val = desc[pos].data1; if (XD_IS_INDIRECT (val)) - val = pdump_get_indirect_count (val, desc, elmt->obj); + val = pdump_get_indirect_count (val, desc, elt->obj); *(int *)rdata = val; break; } @@ -631,15 +674,15 @@ pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description * case XD_LO_LINK: { Lisp_Object obj = *(Lisp_Object *)rdata; - pdump_entry_list_elmt *elmt1; + pdump_entry_list_elt *elt1; for (;;) { - elmt1 = pdump_get_entry (XRECORD_LHEADER (obj)); - if (elmt1) + elt1 = pdump_get_entry (XRECORD_LHEADER (obj)); + if (elt1) break; obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj))); } - *(EMACS_INT *)rdata = elmt1->save_offset; + *(EMACS_INT *)rdata = elt1->save_offset; break; } case XD_LISP_OBJECT: @@ -658,7 +701,7 @@ pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description * EMACS_INT num = desc[pos].data1; int j; if (XD_IS_INDIRECT (num)) - num = pdump_get_indirect_count (num, desc, elmt->obj); + num = pdump_get_indirect_count (num, desc, elt->obj); for (j=0; jobj, size*count); - if (elmt->is_lrecord && ((size*count) & 3)) - write (pdump_fd, "\0\0\0", 4-((size*count) & 3)); + fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out); } static void -pdump_reloc_one (void *data, EMACS_INT delta, const struct lrecord_description *desc) +pdump_reloc_one (void *data, EMACS_INT delta, + const struct lrecord_description *desc) { int pos; @@ -757,77 +799,65 @@ pdump_reloc_one (void *data, EMACS_INT delta, const struct lrecord_description * } default: stderr_out ("Unsupported dump type : %d\n", desc[pos].type); - abort (); + ABORT (); }; } } static void -pdump_allocate_offset (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc) +pdump_allocate_offset (pdump_entry_list_elt *elt, + const struct lrecord_description *desc) { - size_t size = (elmt->is_lrecord ? (elmt->size + 3) & ~3 : elmt->size)*elmt->count; - elmt->save_offset = cur_offset; + size_t size = elt->count * elt->size; + elt->save_offset = cur_offset; if (size>max_size) max_size = size; cur_offset += size; } static void -pdump_scan_by_alignment (void (*f)(pdump_entry_list_elmt *, const struct lrecord_description *)) +pdump_scan_by_alignment (void (*f)(pdump_entry_list_elt *, + const struct lrecord_description *)) { - int align, i; - const struct lrecord_description *idesc; - pdump_entry_list_elmt *elmt; - for (align=8; align>=0; align--) + int align; + + for (align = ALIGNOF (max_align_t); align; align>>=1) { + size_t i; + pdump_entry_list_elt *elt; + for (i=0; idescription; - while (elmt) - { - f (elmt, idesc); - elmt = elmt->next; - } - } + for (elt = pdump_object_table[i].first; elt; elt = elt->next) + f (elt, lrecord_implementations_table[i]->description); for (i=0; idescription; - while (elmt) - { - f (elmt, idesc); - elmt = elmt->next; - } - } - - elmt = pdump_opaque_data_list.first; - while (elmt) { - if (pdump_align_table[elmt->size & 255] == align) - f (elmt, 0); - elmt = elmt->next; + pdump_struct_list_elt list = pdump_struct_table.list[i]; + if (list.list.align == align) + for (elt = list.list.first; elt; elt = elt->next) + f (elt, list.sdesc->description); } + + for (elt = pdump_opaque_data_list.first; elt; elt = elt->next) + if (pdump_size_to_align (elt->size) == align) + f (elt, 0); } } static void -pdump_dump_from_root_struct_ptrs (void) +pdump_dump_root_struct_ptrs (void) { - int i; - for (i = 0; i < Dynarr_length (pdump_root_struct_ptrs); i++) + size_t i; + size_t count = Dynarr_length (pdump_root_struct_ptrs); + pdump_static_pointer *data = alloca_array (pdump_static_pointer, count); + for (i = 0; i < count; i++) { - EMACS_INT adr; - pdump_root_struct_ptr *info = Dynarr_atp (pdump_root_struct_ptrs, i); - write (pdump_fd, &info->ptraddress, sizeof (info->ptraddress)); - adr = pdump_get_entry (*(info->ptraddress))->save_offset; - write (pdump_fd, &adr, sizeof (adr)); + data[i].address = (char **) Dynarr_atp (pdump_root_struct_ptrs, i)->ptraddress; + data[i].value = (char *) pdump_get_entry (* data[i].address)->save_offset; } + PDUMP_ALIGN_OUTPUT (pdump_static_pointer); + fwrite (data, sizeof (pdump_static_pointer), count, pdump_out); } static void @@ -837,110 +867,126 @@ pdump_dump_opaques (void) for (i = 0; i < Dynarr_length (pdump_opaques); i++) { pdump_opaque *info = Dynarr_atp (pdump_opaques, i); - write (pdump_fd, info, sizeof (*info)); - write (pdump_fd, info->varaddress, info->size); + PDUMP_WRITE_ALIGNED (pdump_opaque, *info); + fwrite (info->varaddress, info->size, 1, pdump_out); } } static void pdump_dump_rtables (void) { - int i; - pdump_entry_list_elmt *elmt; + size_t i; + pdump_entry_list_elt *elt; pdump_reloc_table rt; for (i=0; idescription; rt.count = pdump_object_table[i].count; - write (pdump_fd, &rt, sizeof (rt)); - while (elmt) + PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); + while (elt) { - EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; - write (pdump_fd, &rdata, sizeof (rdata)); - elmt = elmt->next; + EMACS_INT rdata = pdump_get_entry (elt->obj)->save_offset; + PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); + elt = elt->next; } } rt.desc = 0; rt.count = 0; - write (pdump_fd, &rt, sizeof (rt)); + PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); for (i=0; idescription; rt.count = pdump_struct_table.list[i].list.count; - write (pdump_fd, &rt, sizeof (rt)); - while (elmt) + PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); + while (elt) { - EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset; + EMACS_INT rdata = pdump_get_entry (elt->obj)->save_offset; int j; - for (j=0; jcount; j++) + for (j=0; jcount; j++) { - write (pdump_fd, &rdata, sizeof (rdata)); - rdata += elmt->size; + PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); + rdata += elt->size; } - elmt = elmt->next; + elt = elt->next; } } rt.desc = 0; rt.count = 0; - write (pdump_fd, &rt, sizeof (rt)); + PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); } static void -pdump_dump_from_root_objects (void) +pdump_dump_root_objects (void) { - size_t count = Dynarr_length (pdump_root_objects) + Dynarr_length (pdump_weak_object_chains); - size_t i; + size_t count = (Dynarr_length (pdump_root_objects) + + Dynarr_length (pdump_weak_object_chains)); + EMACS_INT i; - write (pdump_fd, &count, sizeof (count)); + PDUMP_WRITE_ALIGNED (size_t, count); + PDUMP_ALIGN_OUTPUT (pdump_static_Lisp_Object); for (i=0; isave_offset); - write (pdump_fd, Dynarr_atp (pdump_root_objects, i), sizeof (Dynarr_atp (pdump_root_objects, i))); - write (pdump_fd, &obj, sizeof (obj)); + pdump_static_Lisp_Object obj; + obj.address = Dynarr_at (pdump_root_objects, i); + obj.value = * obj.address; + + if (POINTER_TYPE_P (XTYPE (obj.value))) + obj.value = wrap_object ((void *) pdump_get_entry (XRECORD_LHEADER (obj.value))->save_offset); + + PDUMP_WRITE (pdump_static_Lisp_Object, obj); } for (i=0; idescription; + desc = XRECORD_LHEADER_IMPLEMENTATION (obj.value)->description; for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) assert (desc[pos].type != XD_END); - obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj))); + obj.value = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj.value))); } - obj = wrap_object ((void *) elmt->save_offset); + obj.value = wrap_object ((void *) elt->save_offset); - write (pdump_fd, Dynarr_atp (pdump_weak_object_chains, i), sizeof (Lisp_Object *)); - write (pdump_fd, &obj, sizeof (obj)); + PDUMP_WRITE (pdump_static_Lisp_Object, obj); } } void pdump (void) { - int i; + size_t i; Lisp_Object t_console, t_device, t_frame; int none; - pdump_header hd; + pdump_header header; + + pdump_object_table = xnew_array (pdump_entry_list, lrecord_type_count); + pdump_alert_undump_object = xnew_array (int, lrecord_type_count); + + assert (ALIGNOF (max_align_t) <= pdump_align_table[0]); + + for (i = 0; i < countof (pdump_align_table); i++) + if (pdump_align_table[i] > ALIGNOF (max_align_t)) + pdump_align_table[i] = ALIGNOF (max_align_t); flush_all_buffer_local_cache (); @@ -949,17 +995,17 @@ pdump (void) t_frame = Vterminal_frame; Vterminal_frame = Qnil; t_device = Vterminal_device; Vterminal_device = Qnil; - dump_add_opaque (&lrecord_implementations_table, + dump_add_opaque ((void *) &lrecord_implementations_table, lrecord_type_count * sizeof (lrecord_implementations_table[0])); dump_add_opaque (&lrecord_markers, lrecord_type_count * sizeof (lrecord_markers[0])); - pdump_hash = xnew_array_and_zero (pdump_entry_list_elmt *, PDUMP_HASHSIZE); + pdump_hash = xnew_array_and_zero (pdump_entry_list_elt *, PDUMP_HASHSIZE); for (i=0; iid == dump_id); } +/*----------------------------------------------------------------------*/ +/* Reading the dump file */ +/*----------------------------------------------------------------------*/ static int pdump_load_finish (void) { @@ -1047,25 +1100,25 @@ pdump_load_finish (void) char *p; EMACS_INT delta; EMACS_INT count; + pdump_header *header = (pdump_header *)pdump_start; pdump_end = pdump_start + pdump_length; -#define PDUMP_READ(p, type) (p = (char*) (((type *) p) + 1), *((type *) p - 1)) - - delta = ((EMACS_INT)pdump_start) - ((pdump_header *)pdump_start)->reloc_address; - p = pdump_start + ((pdump_header *)pdump_start)->stab_offset; + delta = ((EMACS_INT)pdump_start) - header->reloc_address; + p = pdump_start + header->stab_offset; /* Put back the pdump_root_struct_ptrs */ - for (i=0; i<((pdump_header *)pdump_start)->nb_root_struct_ptrs; i++) + p = (char *) ALIGN_PTR (p, ALIGNOF (pdump_static_pointer)); + for (i=0; inb_root_struct_ptrs; i++) { - void **adr = PDUMP_READ (p, void **); - *adr = (void *) (PDUMP_READ (p, char *) + delta); + pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); + (* ptr.address) = ptr.value + delta; } /* Put back the pdump_opaques */ - for (i=0; i<((pdump_header *)pdump_start)->nb_opaques; i++) + for (i=0; inb_opaques; i++) { - pdump_opaque info = PDUMP_READ (p, pdump_opaque); + pdump_opaque info = PDUMP_READ_ALIGNED (p, pdump_opaque); memcpy (info.varaddress, p, info.size); p += info.size; } @@ -1075,31 +1128,33 @@ pdump_load_finish (void) count = 2; for (;;) { - pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table); + pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); + p = (char *) ALIGN_PTR (p, ALIGNOF (char *)); if (rt.desc) { + char **reloc = (char **)p; for (i=0; i < rt.count; i++) { - char *adr = delta + *(char **)p; - *(char **)p = adr; - pdump_reloc_one (adr, delta, rt.desc); - p += sizeof (char *); + reloc[i] += delta; + pdump_reloc_one (reloc[i], delta, rt.desc); } + p += rt.count * sizeof (char *); } else if (!(--count)) break; } /* Put the pdump_root_objects variables in place */ - for (i = PDUMP_READ (p, size_t); i; i--) + i = PDUMP_READ_ALIGNED (p, size_t); + p = (char *) ALIGN_PTR (p, ALIGNOF (pdump_static_Lisp_Object)); + while (i--) { - Lisp_Object *var = PDUMP_READ (p, Lisp_Object *); - Lisp_Object obj = PDUMP_READ (p, Lisp_Object); + pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); - if (POINTER_TYPE_P (XTYPE (obj))) - obj = wrap_object ((char *) XPNTR (obj) + delta); + if (POINTER_TYPE_P (XTYPE (obj.value))) + obj.value = wrap_object ((char *) XPNTR (obj.value) + delta); - *var = obj; + (* obj.address) = obj.value; } /* Final cleanups */ @@ -1107,7 +1162,8 @@ pdump_load_finish (void) p = pdump_rt_list; for (;;) { - pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table); + pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); + p = (char *) ALIGN_PTR (p, ALIGNOF (Lisp_Object)); if (!rt.desc) break; if (rt.desc == hash_table_description) @@ -1216,12 +1272,10 @@ pdump_resource_get (void) #else /* !WIN32_NATIVE */ -static void *pdump_mallocadr; - static void pdump_file_free (void) { - xfree (pdump_mallocadr); + xfree (pdump_start); } #ifdef HAVE_MMAP @@ -1249,6 +1303,11 @@ pdump_file_get (const char *path) lseek (fd, 0, SEEK_SET); #ifdef HAVE_MMAP +/* Unix 98 requires that sys/mman.h define MAP_FAILED, + but many earlier implementations don't. */ +# ifndef MAP_FAILED +# define MAP_FAILED ((void *) -1L) +# endif pdump_start = (char *) mmap (0, pdump_length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); if (pdump_start != (char *) MAP_FAILED) { @@ -1256,11 +1315,10 @@ pdump_file_get (const char *path) close (fd); return 1; } -#endif +#endif /* HAVE_MMAP */ - pdump_mallocadr = xmalloc (pdump_length+255); + pdump_start = xnew_array (char, pdump_length); pdump_free = pdump_file_free; - pdump_start = (char *)((255 + (unsigned long)pdump_mallocadr) & ~255); read (fd, pdump_start, pdump_length); close (fd); @@ -1272,9 +1330,8 @@ pdump_file_get (const char *path) static int pdump_file_try (char *exe_path) { - char *w; + char *w = exe_path + strlen (exe_path); - w = exe_path + strlen (exe_path); do { sprintf (w, "-%s-%08x.dmp", EMACS_VERSION, dump_id); @@ -1312,9 +1369,11 @@ pdump_file_try (char *exe_path) int pdump_load (const char *argv0) { - char exe_path[PATH_MAX]; + char exe_path[PATH_MAX], real_exe_path[PATH_MAX]; #ifdef WIN32_NATIVE GetModuleFileName (NULL, exe_path, PATH_MAX); + /* #### urk, needed for xrealpath() below */ + Vdirectory_sep_char = make_char ('\\'); #else /* !WIN32_NATIVE */ char *w; const char *dir, *p; @@ -1360,13 +1419,17 @@ pdump_load (const char *argv0) } strcpy (w, name); - /* ### #$%$#^$^@%$^#%@$ ! */ -#ifdef access -#undef access -#endif + /* Check that exe_path is executable and not a directory */ +#undef access /* avoid !@#$%^& encapsulated access */ +#undef stat /* avoid !@#$%^& encapsulated stat */ + { + struct stat statbuf; + if (access (exe_path, X_OK) == 0 + && stat (exe_path, &statbuf) == 0 + && ! S_ISDIR (statbuf.st_mode)) + break; + } - if (!access (exe_path, X_OK)) - break; if (!*p) { /* Oh well, let's have some kind of default */ @@ -1378,7 +1441,11 @@ pdump_load (const char *argv0) } #endif /* WIN32_NATIVE */ - if (pdump_file_try (exe_path)) + /* Save exe_path because pdump_file_try() modifies it */ + strcpy(real_exe_path, exe_path); + if (pdump_file_try (exe_path) + || (xrealpath(real_exe_path, real_exe_path) + && pdump_file_try (real_exe_path))) { pdump_load_finish (); return 1;