home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / utilslib / c / Unexec < prev   
Encoding:
Text File  |  1991-09-10  |  2.9 KB  |  110 lines

  1. /* Unexec for the Archimedes.
  2.  *
  3.  * This routine saves a "snapshot" of the running program, in a form
  4.  * suitable for later running as a RISC OS application. The whole of the
  5.  * executing image is saved, but NOT the heap or the stack, so that pointers
  6.  * to heap allocated space, or automatic variables, will be garbage when the
  7.  * process is restarted.
  8.  */
  9.  
  10. #include <assert.h>
  11. #include <stdio.h>
  12. #include "kernel.h"
  13. #include "unexec.h"
  14.  
  15. /* This lot are really addresses (void *), but we call them unsigned
  16.  * integers here (unlike in the "utils.h" header file), as that is how
  17.  * we will be using them. nasty, but it saves a lot of casts...
  18.  */
  19.  
  20. extern unsigned int _RO_Base;
  21. extern unsigned int _RO_Limit;
  22. extern unsigned int _RW_Base;
  23. extern unsigned int _RW_Limit;
  24. extern unsigned int _ZI_Base;
  25. extern unsigned int _ZI_Limit;
  26.  
  27. extern unsigned int _Stub_Entries_Base;
  28. extern unsigned int _Stub_Entries_Limit;
  29. extern unsigned int _Stub_Data_Base;
  30. extern unsigned int _Stub_Data_Limit;
  31.  
  32. void unexec (char *file)
  33. {
  34.     int fd;
  35.     int offset;
  36.     int length;
  37.     _kernel_osfile_block blk;
  38.  
  39.     /* Make sure the necessary assumptions are valid! */
  40.     assert(_RO_Limit == _RW_Base);
  41.     assert(_ZI_Base == _ZI_Limit);
  42.     assert(_RO_Base <= _RW_Limit);
  43.     assert(_RO_Base == 0x8080);
  44.  
  45.     blk.load = 0xFF8;
  46.     blk.exec = 0;
  47.     blk.start = 0x8000;
  48.     blk.end = _RW_Limit;
  49.     _kernel_osfile(10,file,&blk);
  50.  
  51.     /* *******************************************************
  52.      * The following code is HIGHLY dependent on the exact
  53.      * format of the shared C library stubs! It is probably
  54.      * not necessary, either! If in doubt, comment it out!
  55.      * Based on Shared C Library stubs 3.50 (supplied with
  56.      * Acorn C v3.0).
  57.      * It has been visually verified with stubs 3.75 (the
  58.      * version supplied with Desktop C v4.0), and appears
  59.      * to be OK with this, too.
  60.      * *******************************************************/
  61.  
  62.     /* Now open the dumped image to zap the C Library stubs data */
  63.     fd = _kernel_osfind(0xC7,file);
  64.  
  65.     /* If we can't open it for update, leave it as it is */
  66.     if (fd == 0)
  67.         return;
  68.  
  69.     /* Set Stub$$Entries to 0xE3A0F000 (repeated) */
  70.     offset = _Stub_Entries_Base - 0x8000;
  71.     length = (_Stub_Entries_Limit - _Stub_Entries_Base);
  72.  
  73.     /* Must be an exact number of words */
  74.     assert((length & 0x03) == 0);
  75.  
  76.     /* Go to the area start (give up if we cannot) */
  77.     if (_kernel_osargs(1,fd,offset) == _kernel_ERROR)
  78.         goto quit;
  79.  
  80.     while (length > 0)
  81.     {
  82.         _kernel_osbput(0x00,fd);
  83.         --length;
  84.         _kernel_osbput(0xF0,fd);
  85.         --length;
  86.         _kernel_osbput(0xA0,fd);
  87.         --length;
  88.         _kernel_osbput(0xE3,fd);
  89.         --length;
  90.     }
  91.  
  92.     /* Zero out Stub$$Data */
  93.     offset = _Stub_Data_Base - 0x8000;
  94.     length = (_Stub_Data_Limit - _Stub_Data_Base);
  95.  
  96.     /* Go to the area start (give up if we cannot) */
  97.     if (_kernel_osargs(1,fd,offset) == _kernel_ERROR)
  98.         goto quit;
  99.  
  100.     while (length > 0)
  101.     {
  102.         _kernel_osbput(0,fd);
  103.         --length;
  104.     }
  105.  
  106.     /* We are done. Close the file */
  107. quit:
  108.     _kernel_osfind(0,(char *)fd);
  109. }
  110.