home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / text / emacsdif.lha / emacs-18.58 / src / amiga_dump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-16  |  22.5 KB  |  833 lines

  1. #include <exec/types.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <assert.h>
  5. #include "config.h"
  6. #include "lisp.h"
  7. #include "buffer.h"
  8. #include "regex.h"
  9. #include "amiga.h"
  10. #include "dispextern.h"
  11. #include "termchar.h"
  12.  
  13. #define RANGE(ptr, s, e) ((char *)ptr >= (char *)s && (char *)ptr < (char *)e)
  14. #define HUNK_POS (VALBITS - 3)
  15. #define HUNK_MASK (7 << HUNK_POS)
  16. #define HUNK_CODE (0 << HUNK_POS)
  17. #define HUNK_DATA (1 << HUNK_POS)
  18. #define HUNK_BSS (2 << HUNK_POS)
  19. #define HUNK_MALLOC (3 << HUNK_POS)
  20. #define HUNK_PURE (4 << HUNK_POS)
  21. #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
  22.  
  23. #ifdef PROBLEMS
  24. #define NPOINTERS 40000
  25.  
  26. void *far pointers[NPOINTERS];
  27. int far ptr_pos, far ptr_pos2;
  28. #endif
  29. void *far first_fn = first_function, *far last_fn = last_function;
  30.  
  31. extern int *pure, puresize;
  32. extern struct gcpro *gcprolist;
  33.  
  34. extern Lisp_Object *staticvec[];
  35. extern int staticidx;
  36. extern struct cons_block *cons_block;
  37. extern struct Lisp_Cons *cons_free_list;
  38. extern struct Lisp_Vector *all_vectors;
  39. extern struct symbol_block *symbol_block;
  40. extern struct Lisp_Symbol *symbol_free_list;
  41. extern struct marker_block *marker_block;
  42. extern struct Lisp_Marker *marker_free_list;
  43.  
  44. struct string_block_head
  45.   {
  46.     struct string_block_head *next, *prev;
  47.     int pos;
  48.   };
  49. extern struct string_block_head *current_string_block;
  50. extern struct string_block_head *first_string_block;
  51. extern struct string_block_head *large_string_blocks;
  52. extern char *kbd_macro_buffer, *read_buffer, *chars_wasted, *copybuf;
  53. extern struct minibuf_save_data *minibuf_save_vector;
  54. extern struct re_pattern_buffer searchbuf;
  55. extern int *ILcost, *DLcost, *ILncost, *DLncost;
  56. extern Lisp_Object MouseMap, global_map, Vglobal_map, Vesc_map, Vctl_x_map;
  57. extern Lisp_Object Qvariable_documentation, selected_window;
  58.  
  59. #ifdef PROBLEMS
  60. void check_region(char *start, char *end)
  61. {
  62.     long *ptr;
  63.  
  64.     /* Assumes that start is word aligned */
  65.     for (ptr = (long *)start; (char *)ptr < end; ptr = (long *)((long)ptr + 2))
  66.     {
  67.     if (ptr < (long *)staticvec || ptr >= (long *)&staticvec[200])
  68.     if (RANGE(*ptr, first_fn, last_fn) ||
  69.         RANGE(*ptr, &first_data, &last_data) ||
  70.         RANGE(*ptr, &first_bss, &last_bss) ||
  71.         RANGE(*ptr, pure, (char *)pure + puresize) ||
  72.         RANGE(*ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  73.         printf("WARNING: %lx (offset %lx)\n",
  74.            ptr, (char *)ptr - (char *)&first_data);
  75.     }
  76. }
  77.  
  78. void check_region2(char *start, char *end)
  79. {
  80.     long *ptr;
  81.  
  82.     /* Assumes that start is word aligned */
  83.     for (ptr = (long *)start; (char *)ptr < end; ptr = (long *)((long)ptr + 2))
  84.     {
  85.     if (RANGE(*ptr, first_fn, last_fn))
  86.         printf("WARNING: Code %lx (offset %lx)\n",
  87.            ptr, (char *)ptr - (char *)&first_data);
  88.     else
  89.     {
  90.         void *lp = (void *)(*ptr & VALMASK);
  91.  
  92.         if ((ptr < (long *)staticvec || ptr >= (long *)&staticvec[200]) &&
  93.         (RANGE(lp, first_fn, last_fn) ||
  94.          RANGE(lp, &first_data, &last_data) ||
  95.          RANGE(lp, &first_bss, &last_bss) ||
  96.          RANGE(lp, pure, (char *)pure + puresize) ||
  97.          RANGE(lp, malloc_hunk, malloc_hunk + malloc_hunk_size)))
  98.         {
  99.         int i;
  100.         for (i = 0; i < 200; i++)
  101.             if (staticvec[i] == ptr) break;
  102.  
  103.         if (staticvec[i] == ptr) break;
  104.         printf("WARNING: Lisp %lx (offset %lx), Type %d\n",
  105.                ptr, (char *)ptr - (char *)&first_data, XTYPE(*ptr));
  106.         }
  107.     }
  108.     }
  109. }
  110.  
  111. static void *s1, *s2, *s3, *s4;
  112. static void *e1, *e2, *e3, *e4;
  113.  
  114. void verify_ptr(char *start, char *end)
  115. {
  116.     long *ptr;
  117.  
  118.     /* Assumes that start is word aligned */
  119.     for (ptr = (long *)start; (char *)ptr < end; ptr = (long *)((long)ptr + 2))
  120.     {
  121.     void *lp = (void *)(*ptr & VALMASK);
  122.  
  123.     if (RANGE(lp, s1, e1))
  124.         printf("Pointer @ offset %x (from %x) to %x (hunk 1), offset %x (from %x)\n",
  125.            (char *)ptr - start, start, lp, (char *)lp - (char *)s1, s1);
  126.     if (RANGE(lp, s2, e2))
  127.         printf("Pointer @ offset %x (from %x) to %x (hunk 2), offset %x (from %x)\n",
  128.            (char *)ptr - start, start, lp, (char *)lp - (char *)s2, s2);
  129.     if (RANGE(lp, s3, e3))
  130.         printf("Pointer @ offset %x (from %x) to %x (hunk 3), offset %x (from %x)\n",
  131.            (char *)ptr - start, start, lp, (char *)lp - (char *)s3, s3);
  132.     if (RANGE(lp, s4, e4))
  133.         printf("Pointer @ offset %x (from %x) to %x (hunk 4), offset %x (from %x)\n",
  134.            (char *)ptr - start, start, lp, (char *)lp - (char *)s4, s4);
  135.     }
  136. }
  137.  
  138. void verify(void)
  139. {
  140.     printf("Start end of region 1 : "); scanf("%x %x", &s1, &e1);
  141.     printf("Start end of region 2 : "); scanf("%x %x", &s2, &e2);
  142.     printf("Start end of region 3 : "); scanf("%x %x", &s3, &e3);
  143.     printf("Start end of region 4 : "); scanf("%x %x", &s4, &e4);
  144.  
  145.     /*verify_ptr(first_fn, last_fn);*/
  146.     verify_ptr(&first_data, &last_bss);
  147.     verify_ptr(pure, (char *)pure + puresize);
  148.     verify_ptr(malloc_hunk, malloc_hunk + malloc_hunk_size);
  149. }
  150. #endif
  151.  
  152. void *hunk_pointer(void *ptr)
  153. {
  154.     if (!ptr) return ptr;
  155.  
  156.     if (RANGE(ptr, first_fn, last_fn))
  157.     return (void *)(HUNK_CODE | (char *)ptr - (char *)first_fn);
  158.     else if (RANGE(ptr, &first_data, &last_data))
  159.     return (void *)(HUNK_DATA | (char *)ptr - (char *)&first_data);
  160.     else if (RANGE(ptr, &first_bss, &last_bss))
  161.     return (void *)(HUNK_BSS | (char *)ptr - (char *)&first_bss);
  162.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  163.     return (void *)(HUNK_MALLOC | (char *)ptr - malloc_hunk);
  164.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  165.     return (void *)(HUNK_PURE | (char *)ptr - (char *)pure);
  166.     else {
  167.     printf("Bad pointer %lx\n", ptr);
  168.     exit(1);
  169.     }
  170. }
  171.  
  172.  
  173. Lisp_Object hunk_lispptr(Lisp_Object *objptr, Lisp_Object val)
  174. {
  175.     int type = val & ~VALMASK;
  176.     void *ptr = (void *)XPNTR(val);
  177.  
  178. #ifdef PROBLEMS
  179.     pointers[ptr_pos++] = objptr;
  180.     if (ptr_pos >= NPOINTERS)
  181.     {
  182.     printf("Too many pointers\n");
  183.     exit(20);
  184.     }
  185. #endif
  186.  
  187.     if (RANGE(ptr, first_fn, last_fn))
  188.     return type | HUNK_CODE | (char *)ptr - (char *)first_fn;
  189.     else if (RANGE(ptr, &first_data, &last_data))
  190.     return type | HUNK_DATA | (char *)ptr - (char *)&first_data;
  191.     else if (RANGE(ptr, &first_bss, &last_bss))
  192.     return type | HUNK_BSS | (char *)ptr - (char *)&first_bss;
  193.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  194.     return type | HUNK_PURE | (char *)ptr - (char *)pure;
  195.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  196.     return type | HUNK_MALLOC | (char *)ptr - malloc_hunk;
  197.     else {
  198.     printf("Bad pointer %lx\n", ptr);
  199.     exit(1);
  200.     }
  201. }
  202.  
  203. void patch_pointers ();
  204.  
  205. void patch_buffer (buf)
  206.      Lisp_Object buf;
  207. {
  208.   Lisp_Object tem;
  209.   register struct buffer *buffer = XBUFFER (buf);
  210.   register Lisp_Object *ptr;
  211.  
  212.   buffer->text.beg = hunk_pointer (buffer->text.beg);
  213.   patch_pointers (&buffer->markers);
  214.  
  215.   /* This is the buffer's markbit */
  216.   patch_pointers (&buffer->name);
  217.   XMARK (buffer->name);
  218.  
  219.   for (ptr = &buffer->name + 1;
  220.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  221.        ptr++)
  222.     patch_pointers (ptr);
  223. }
  224.  
  225. void patch_pointers (objptr)
  226.      Lisp_Object *objptr;
  227. {
  228.   register Lisp_Object obj;
  229.  
  230.   obj = *objptr;
  231.   XUNMARK (obj);
  232.  
  233.  
  234.  loop:
  235.  
  236.   switch (XGCTYPE (obj))
  237.     {
  238.     case Lisp_String:
  239.       *objptr = hunk_lispptr(objptr, *objptr);
  240.       break;
  241.  
  242.     case Lisp_Vector:
  243.     case Lisp_Window:
  244.     case Lisp_Process:
  245.     case Lisp_Window_Configuration:
  246.       *objptr = hunk_lispptr(objptr, *objptr);
  247.       {
  248.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  249.     register int size = ptr->size;
  250.     register int i;
  251.  
  252.     if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
  253.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  254.     for (i = 0; i < size; i++)     /* and then mark its elements */
  255.       patch_pointers (&ptr->contents[i]);
  256.       }
  257.       break;
  258.  
  259.     case Lisp_Symbol:
  260.       *objptr = hunk_lispptr(objptr, *objptr);
  261.       {
  262.     register struct Lisp_Symbol *ptr = XSYMBOL (obj);
  263.     struct Lisp_Symbol *ptrx;
  264.  
  265.     if (XMARKBIT (ptr->plist)) break;
  266.     XMARK (ptr->plist);
  267.     XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
  268.     patch_pointers (&ptr->name);
  269.     patch_pointers ((Lisp_Object *) &ptr->value);
  270.     patch_pointers (&ptr->function);
  271.     patch_pointers (&ptr->plist);
  272.     objptr = (Lisp_Object *)&ptr->next;
  273.     ptr = ptr->next;
  274.     if (ptr)
  275.       {
  276.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  277.         XSETSYMBOL (obj, ptrx);
  278.         goto loop;
  279.       }
  280.       }
  281.       break;
  282.  
  283.     case Lisp_Marker: {
  284.     struct Lisp_Marker *ptr = XMARKER (obj);
  285.  
  286.     *objptr = hunk_lispptr(objptr, *objptr);
  287.     if (XMARKBIT (ptr->chain)) break;
  288.     XMARK (ptr->chain);
  289.     ptr->buffer = hunk_pointer (ptr->buffer);
  290.     patch_pointers (&ptr->chain);
  291.     break;
  292.     }
  293.  
  294.     case Lisp_Cons:
  295.     case Lisp_Buffer_Local_Value:
  296.     case Lisp_Some_Buffer_Local_Value:
  297.       *objptr = hunk_lispptr(objptr, *objptr);
  298.       {
  299.     register struct Lisp_Cons *ptr = XCONS (obj);
  300.     if (XMARKBIT (ptr->car)) break;
  301.     XMARK (ptr->car);
  302.     patch_pointers (&ptr->car);
  303.     objptr = &ptr->cdr;
  304.     obj = ptr->cdr;
  305.     goto loop;
  306.       }
  307.  
  308.     case Lisp_Buffer:
  309.       *objptr = hunk_lispptr(objptr, *objptr);
  310.       if (!XMARKBIT (XBUFFER (obj)->name))
  311.     patch_buffer (obj);
  312.       break;
  313.  
  314.     case Lisp_Subr: {
  315.     struct Lisp_Subr *subr = XSUBR(obj);
  316.  
  317.     *objptr = hunk_lispptr(objptr, *objptr);
  318.     if (subr->min_args & 0x8000) break;
  319.     subr->min_args |= 0x8000;
  320.     subr->function = hunk_pointer(subr->function);
  321.     subr->symbol_name = hunk_pointer(subr->symbol_name);
  322.     subr->prompt = hunk_pointer(subr->prompt);
  323.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  324.         subr->doc = hunk_pointer(subr->doc);
  325.     break;
  326.     }
  327.  
  328.     case Lisp_Int:
  329.     case Lisp_Void:
  330.     case Lisp_Buffer_Objfwd: break;
  331.  
  332.     case Lisp_Intfwd:
  333.     case Lisp_Boolfwd:
  334.     case Lisp_Objfwd:
  335.     case Lisp_Internal_Stream:
  336.       *objptr = hunk_lispptr(objptr, *objptr);
  337.     /* Don't bother with Lisp_Buffer_Objfwd,
  338.        since all markable slots in current buffer marked anyway.  */
  339.     /* Don't need to do Lisp_Objfwd, since the places they point
  340.        are protected with staticpro.  */
  341.       break;
  342.  
  343.     default:
  344.       abort ();
  345.     }
  346. }
  347.  
  348. void patch_chain(void **ptr, int offset)
  349. {
  350.     while (*ptr)
  351.     {
  352.     void **next = (void **)((char *)*ptr + offset);
  353.  
  354.     *ptr = hunk_pointer(*ptr);
  355.     ptr = next;
  356.     }
  357. }
  358.  
  359. void patch(void)
  360. {
  361.     int i;
  362.     struct string_block_head *sptr;
  363.     struct buffer *bptr;
  364.     struct mem_header *mem;
  365.  
  366. #ifdef PROBLEMS
  367.     ptr_pos = 0;
  368.  
  369.     check_region2((char *)&first_data, (char *)&last_data);
  370.     check_region2((char *)&first_bss, (char *)&last_bss);
  371. #endif
  372.  
  373.     for (i = 0; i < staticidx; i++)
  374.     {
  375.     if (!XMARKBIT(*staticvec[i]))
  376.     {
  377.         patch_pointers(staticvec[i]);
  378.         XMARK(*staticvec[i]);
  379.     }
  380.     staticvec[i] = hunk_pointer(staticvec[i]);
  381.     }
  382.  
  383.     /* Patch all the pointers normally used before a dump ! */
  384.     patch_chain((void **)&cons_block, 0);
  385.     patch_chain((void **)&cons_free_list, 0);
  386.  
  387.     patch_chain((void **)&all_vectors, 4);
  388.  
  389.     patch_chain((void **)&symbol_block, 0);
  390.     patch_chain((void **)&symbol_free_list, 4);
  391.  
  392.     patch_chain((void **)&marker_block, 0);
  393.     patch_chain((void **)&marker_free_list, 4);
  394.  
  395.     /* Strings are lots of fun */
  396.     patch_chain((void **)&large_string_blocks, 0);
  397.     sptr = first_string_block;
  398.     while (sptr)
  399.     {
  400.     struct string_block *next = sptr->next;
  401.  
  402.     if (sptr->next) sptr->next = hunk_pointer(sptr->next);
  403.     if (sptr->prev) sptr->prev = hunk_pointer(sptr->prev);
  404.     sptr = next;
  405.     }
  406.     first_string_block = hunk_pointer(first_string_block);
  407.     current_string_block = hunk_pointer(current_string_block);
  408.  
  409.     /* More fun with buffers */
  410.     bptr = all_buffers;
  411.     if (bptr)
  412.     {
  413.     while (bptr->next)
  414.     {
  415.         struct buffer *next = bptr->next;
  416.  
  417.         bptr->next = hunk_pointer(bptr->next);
  418.         bptr = next;
  419.     }
  420.     }
  421.     all_buffers = hunk_pointer(all_buffers);
  422.     current_buffer = hunk_pointer(current_buffer);
  423.  
  424.     kbd_macro_buffer = hunk_pointer(kbd_macro_buffer);
  425.     minibuf_save_vector = hunk_pointer(minibuf_save_vector);
  426.     searchbuf.buffer = hunk_pointer(searchbuf.buffer);
  427.     searchbuf.fastmap = hunk_pointer(searchbuf.fastmap);
  428.     specpdl = hunk_pointer(specpdl);
  429.     read_buffer = hunk_pointer(read_buffer);
  430.  
  431.     MouseMap = hunk_lispptr(&MouseMap, MouseMap);
  432.     global_map = hunk_lispptr(&global_map, global_map);
  433.     Vglobal_map = hunk_lispptr(&Vglobal_map, Vglobal_map);
  434.     Vesc_map = hunk_lispptr(&Vesc_map, Vesc_map);
  435.     Vctl_x_map = hunk_lispptr(&Vctl_x_map, Vctl_x_map);
  436.  
  437.     Qvariable_documentation = hunk_lispptr(&Qvariable_documentation, Qvariable_documentation);
  438.     selected_window = hunk_lispptr(&selected_window, selected_window);
  439.  
  440.     mem = free_list;
  441.     free_list = hunk_pointer(free_list);
  442.     while (mem)
  443.     {
  444.     struct mem_header *next = mem->next;
  445.  
  446.     mem->prev = hunk_pointer(mem->prev);
  447.     mem->next = hunk_pointer(mem->next);
  448.     mem = next;
  449.     }
  450. }
  451.  
  452. dump(char *fn)
  453. {
  454.     int fd;
  455.     long size;
  456.  
  457.     fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC);
  458.     if (fd == -1) error("Dump failed to open %s.", fn);
  459.  
  460.     write(fd, (char *)&puresize, sizeof puresize);
  461.     write(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  462.     write(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  463.     write(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  464.     write(fd, (char *)pure, puresize);
  465.     write(fd, (char *)malloc_hunk, malloc_hunk_size);
  466.     write(fd, (char *)&staticidx, sizeof staticidx);
  467.     write(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  468.     size = (char *)last_fn - (char *)first_fn;
  469.     write(fd, (char *)&size, sizeof size);
  470.  
  471.     close(fd);
  472. }
  473.  
  474. void *make_pointer(void *ptr)
  475. {
  476.     int hunk = (long)ptr & HUNK_MASK;
  477.     int offset = (long)ptr & (VALMASK & ~HUNK_MASK);
  478.  
  479.     if (!ptr) return 0;
  480.  
  481.     if (hunk == HUNK_CODE) return (char *)first_fn + offset;
  482.     if (hunk == HUNK_DATA) return (char *)&first_data + offset;
  483.     if (hunk == HUNK_BSS) return (char *)&first_bss + offset;
  484.     if (hunk == HUNK_PURE) return (char *)pure + offset;
  485.     if (hunk == HUNK_MALLOC) return malloc_hunk + offset;
  486.     assert(0);
  487. }
  488.  
  489. Lisp_Object make_lispptr(Lisp_Object *objptr, Lisp_Object obj)
  490. {
  491.     long val = XUINT(obj);
  492.     int hunk = val & HUNK_MASK;
  493.     int offset = val & ~HUNK_MASK;
  494.     char *ptr;
  495.  
  496. #ifdef PROBLEMS
  497.     if (ptr_pos && pointers[ptr_pos2] != objptr)
  498.     {
  499.     printf("Discrepancy in %drd pointer: was %x, now is %x\n",
  500.            ptr_pos2, pointers[ptr_pos2], objptr);
  501.     }
  502.     ptr_pos2++;
  503. #endif
  504.     if (hunk == HUNK_CODE) ptr = (char *)first_fn + offset;
  505.     else if (hunk == HUNK_DATA) ptr = (char *)&first_data + offset;
  506.     else if (hunk == HUNK_BSS) ptr = (char *)&first_bss + offset;
  507.     else if (hunk == HUNK_PURE) ptr = (char *)pure + offset;
  508.     else if (hunk == HUNK_MALLOC) ptr = malloc_hunk + offset;
  509.     else assert(0);
  510.  
  511.     XSETPNTR(obj, (long)ptr);
  512.     return obj;
  513. }
  514.  
  515. void unpatch_pointers ();
  516.  
  517. void unpatch_buffer (buf)
  518.      Lisp_Object buf;
  519. {
  520.   Lisp_Object tem;
  521.   register struct buffer *buffer = XBUFFER (buf);
  522.   register Lisp_Object *ptr;
  523.  
  524.   buffer->text.beg = make_pointer (buffer->text.beg);
  525.   unpatch_pointers (&buffer->markers);
  526.  
  527.   /* This is the buffer's markbit */
  528.   XUNMARK (buffer->name);
  529.   unpatch_pointers (&buffer->name);
  530.  
  531.   for (ptr = &buffer->name + 1;
  532.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  533.        ptr++)
  534.     unpatch_pointers (ptr);
  535. }
  536.  
  537. void unpatch_pointers (objptr)
  538.      Lisp_Object *objptr;
  539. {
  540.   register Lisp_Object obj;
  541.  
  542.   obj = *objptr;
  543.   XUNMARK (obj);
  544.  
  545.  
  546.  loop:
  547.  
  548.   switch (XGCTYPE (obj))
  549.     {
  550.     case Lisp_String:
  551.       *objptr = make_lispptr(objptr, *objptr);
  552.       break;
  553.  
  554.     case Lisp_Vector:
  555.     case Lisp_Window:
  556.     case Lisp_Process:
  557.     case Lisp_Window_Configuration:
  558.       obj = *objptr = make_lispptr(objptr, *objptr);
  559.       {
  560.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  561.     register int size;
  562.     register int i;
  563.  
  564.     if (!(ptr->size & ARRAY_MARK_FLAG)) break;   /* Already unmarked */
  565.     size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
  566.     for (i = 0; i < size; i++)     /* and then unmark its elements */
  567.       unpatch_pointers (&ptr->contents[i]);
  568.       }
  569.       break;
  570.  
  571.     case Lisp_Symbol:
  572.       obj = *objptr = make_lispptr(objptr, *objptr);
  573.       {
  574.     register struct Lisp_Symbol *ptr = XSYMBOL (obj);
  575.     struct Lisp_Symbol *ptrx;
  576.  
  577.     if (!XMARKBIT (ptr->plist)) break;
  578.     XUNMARK (ptr->plist);
  579.     unpatch_pointers (&ptr->name);
  580.     ptr->name = XSTRING (*(Lisp_Object *)&ptr->name);
  581.     unpatch_pointers ((Lisp_Object *) &ptr->value);
  582.     unpatch_pointers (&ptr->function);
  583.     unpatch_pointers (&ptr->plist);
  584.     objptr = (Lisp_Object *)&ptr->next;
  585.     ptr = ptr->next;
  586.     if (ptr)
  587.       {
  588.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  589.         XSET (obj, Lisp_Symbol, ptrx);
  590.         goto loop;
  591.       }
  592.       }
  593.       break;
  594.  
  595.     case Lisp_Marker: {
  596.     struct Lisp_Marker *ptr;
  597.  
  598.     obj = *objptr = make_lispptr(objptr, *objptr);
  599.     ptr = XMARKER (obj);
  600.     if (!XMARKBIT (ptr->chain)) break;
  601.     XUNMARK (ptr->chain);
  602.     ptr->buffer = make_pointer (ptr->buffer);
  603.     unpatch_pointers (&ptr->chain);
  604.     break;
  605.     }
  606.  
  607.     case Lisp_Cons:
  608.     case Lisp_Buffer_Local_Value:
  609.     case Lisp_Some_Buffer_Local_Value:
  610.       obj = *objptr = make_lispptr(objptr, *objptr);
  611.       {
  612.     register struct Lisp_Cons *ptr = XCONS (obj);
  613.     if (!XMARKBIT (ptr->car)) break;
  614.     XUNMARK (ptr->car);
  615.     unpatch_pointers (&ptr->car);
  616.     objptr = &ptr->cdr;
  617.     obj = ptr->cdr;
  618.     goto loop;
  619.       }
  620.  
  621.     case Lisp_Buffer:
  622.       obj = *objptr = make_lispptr(objptr, *objptr);
  623.       if (XMARKBIT (XBUFFER (obj)->name))
  624.     unpatch_buffer (obj);
  625.       break;
  626.  
  627.     case Lisp_Subr: {
  628.     struct Lisp_Subr *subr;
  629.  
  630.     obj = *objptr = make_lispptr(objptr, *objptr);
  631.     subr = XSUBR(obj);
  632.     if (!(subr->min_args & 0x8000)) break;
  633.     subr->min_args &= ~0x8000;
  634.     subr->function = make_pointer(subr->function);
  635.     subr->symbol_name = make_pointer(subr->symbol_name);
  636.     subr->prompt = make_pointer(subr->prompt);
  637.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  638.         subr->doc = make_pointer(subr->doc);
  639.     break;
  640.     }
  641.  
  642.     case Lisp_Int:
  643.     case Lisp_Void:
  644.     case Lisp_Buffer_Objfwd: break;
  645.  
  646.     case Lisp_Intfwd:
  647.     case Lisp_Boolfwd:
  648.     case Lisp_Objfwd:
  649.     case Lisp_Internal_Stream:
  650.       *objptr = make_lispptr(objptr, *objptr);
  651.     /* Don't bother with Lisp_Buffer_Objfwd,
  652.        since all markable slots in current buffer marked anyway.  */
  653.     /* Don't need to do Lisp_Objfwd, since the places they point
  654.        are protected with staticpro.  */
  655.       break;
  656.  
  657.     default:
  658.       abort ();
  659.     }
  660. }
  661.  
  662. void unpatch_chain(void **ptr, int offset)
  663. {
  664.     while (*ptr)
  665.     {
  666.     *ptr = make_pointer(*ptr);
  667.     ptr = (void **)((char *)*ptr + offset);
  668.     }
  669. }
  670.  
  671. /* Reconstructs the addresses that were patched */
  672. void unpatch(void)
  673. {
  674.     int fd, i;
  675.     struct string_block_head *sptr;
  676.     struct buffer *bptr;
  677.     struct mem_header *mem;
  678.  
  679. #ifdef PROBLEMS
  680.     ptr_pos2 = 0;
  681. #endif
  682.  
  683.     for (i = 0; i < staticidx; i++)
  684.     {
  685.     staticvec[i] = make_pointer(staticvec[i]);
  686.     if (XMARKBIT(*staticvec[i]))
  687.     {
  688.         XUNMARK(*staticvec[i]);
  689.         unpatch_pointers(staticvec[i]);
  690.     }
  691.     }
  692.  
  693.     /* Unpatch all the pointers normally used before a dump ! */
  694.     unpatch_chain((void **)&cons_block, 0);
  695.     unpatch_chain((void **)&cons_free_list, 0);
  696.  
  697.     unpatch_chain((void **)&all_vectors, 4);
  698.  
  699.     unpatch_chain((void **)&symbol_block, 0);
  700.     unpatch_chain((void **)&symbol_free_list, 4);
  701.  
  702.     unpatch_chain((void **)&marker_block, 0);
  703.     unpatch_chain((void **)&marker_free_list, 4);
  704.  
  705.     /* Strings are lots of fun */
  706.     unpatch_chain((void **)&large_string_blocks, 0);
  707.     sptr = first_string_block = make_pointer(first_string_block);
  708.     current_string_block = make_pointer(current_string_block);
  709.     while (sptr)
  710.     {
  711.     if (sptr->next) sptr->next = make_pointer(sptr->next);
  712.     if (sptr->prev) sptr->prev = make_pointer(sptr->prev);
  713.     sptr = sptr->next;
  714.     }
  715.  
  716.     /* More fun with buffers */
  717.     bptr = all_buffers = make_pointer(all_buffers);
  718.     if (bptr)
  719.     {
  720.     while (bptr->next)
  721.     {
  722.         bptr->next = make_pointer(bptr->next);
  723.         bptr = bptr->next;
  724.     }
  725.     }
  726.     current_buffer = make_pointer(current_buffer);
  727.  
  728.     kbd_macro_buffer = make_pointer(kbd_macro_buffer);
  729.     minibuf_save_vector = make_pointer(minibuf_save_vector);
  730.     searchbuf.buffer = make_pointer(searchbuf.buffer);
  731.     searchbuf.fastmap = make_pointer(searchbuf.fastmap);
  732.     specpdl = make_pointer(specpdl);
  733.     read_buffer = make_pointer(read_buffer);
  734.  
  735.     MouseMap = make_lispptr(&MouseMap, MouseMap);
  736.     global_map = make_lispptr(&global_map, global_map);
  737.     Vglobal_map = make_lispptr(&Vglobal_map, Vglobal_map);
  738.     Vesc_map = make_lispptr(&Vesc_map, Vesc_map);
  739.     Vctl_x_map = make_lispptr(&Vctl_x_map, Vctl_x_map);
  740.  
  741.     Qvariable_documentation = make_lispptr(&Qvariable_documentation, Qvariable_documentation);
  742.     selected_window = make_lispptr(&selected_window, selected_window);
  743.  
  744.     free_list = make_pointer(free_list);
  745.     mem = free_list;
  746.     while (mem)
  747.     {
  748.     mem->prev = make_pointer(mem->prev);
  749.     mem->next = make_pointer(mem->next);
  750.     mem = mem->next;
  751.     }
  752. }
  753.  
  754. undump(char *fn)
  755. {
  756.   int fd;
  757.   long code_size;
  758.   char *_malloc_hunk;
  759.   int *_pure;
  760.  
  761.   fd = open(fn, O_RDONLY);
  762.   if (fd == -1) return 0;
  763.  
  764.   read(fd, (char *)&puresize, sizeof puresize);
  765.   read(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  766.   _pure = alloc_sys(puresize);
  767.   _malloc_hunk = alloc_sys(malloc_hunk_size + pre_alloc);
  768.   if (!_pure || !_malloc_hunk)
  769.     {
  770.       if (_malloc_hunk) free_sys(_malloc_hunk, malloc_hunk_size + pre_alloc);
  771.       if (_pure) free_sys(_pure, puresize);
  772.       printf("No memory.\n");
  773.       exit(20);
  774.     }
  775.   read(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  776.   read(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  777.   read(fd, (char *)_pure, puresize);
  778.   read(fd, (char *)_malloc_hunk, malloc_hunk_size);
  779.   read(fd, (char *)&staticidx, sizeof staticidx);
  780.   read(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  781.   if (read(fd, (char *)&code_size, sizeof code_size) != sizeof code_size ||
  782.       code_size != (char *)last_fn - (char *)first_fn)
  783.     {
  784.       FreeMem((struct mem_header *)_malloc_hunk - 1,
  785.               malloc_hunk_size + pre_alloc + sizeof(struct mem_header));
  786.       FreeMem((struct mem_header *)_pure - 1, puresize + sizeof(struct mem_header));
  787.       printf("%s isn't a dump file for this version of Emacs, aborting.\n", fn);
  788.       exit(20);
  789.     }
  790.   close(fd);
  791.   malloc_hunk = _malloc_hunk;
  792.   pure = _pure;
  793.   return 1;
  794. }
  795.  
  796. void map_out_data(char *fn)
  797. {
  798.     if (amiga_initialized) error("You can only dump once !");
  799.     Fgarbage_collect();
  800.  
  801.     patch();
  802.     dump(fn);
  803.     unpatch();
  804.     amiga_initialized = 1;
  805. }
  806.  
  807. void map_in_data(int load)
  808. {
  809.     if (load && undump("GNUEmacs:etc/EMACS-DATA"))
  810.     {
  811.     unpatch();
  812.     current_screen = new_screen = temp_screen = 0;
  813.     message_buf = 0;
  814.     chars_wasted = copybuf = 0;
  815.     DC_ICcost = 0;
  816.     ILcost = DLcost = ILncost = DLncost = 0;
  817.     initialized = amiga_initialized = 1;
  818.     }
  819.     else
  820.       {
  821.     malloc_hunk = alloc_sys(malloc_hunk_size + pre_alloc);
  822.     pure = alloc_sys(puresize);
  823.         if (!pure || !malloc_hunk)
  824.           {
  825.             if (malloc_hunk) free_sys(malloc_hunk, malloc_hunk_size + pre_alloc);
  826.             if (pure) free_sys(pure, puresize);
  827.             printf("No memory.\n");
  828.             exit(20);
  829.           }
  830.       }
  831.     amiga_undump_reinit();
  832. }
  833.