home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / editors / mntemacs.zoo / utils / dumpfix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  5.5 KB  |  233 lines

  1. /* vi:set tabstop=3: */
  2. #include <stdio.h>
  3. #include <st-out.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <sgtty.h>
  7.  
  8. #define MAX_LISP_TYPE    25
  9. #define PTRBITS 0x00FFFFFFL
  10. #define FUZZY    1024    /* difference accepted if in range +- FUZZY */
  11.  
  12. extern long    _stksize = -1L;
  13.  
  14. int    no_questions = 0;
  15. int    overwrite = 0;
  16. int    no_warnings = 0;
  17.  
  18. unsigned char    *reloc_buffer;
  19.  
  20. void
  21. add_rel(int n, int i)
  22. {
  23.     reloc_buffer = (unsigned char *) realloc(reloc_buffer, i+1);
  24.     if(!reloc_buffer) {
  25.         fprintf(stderr, "Unable to allocate %d bytes\n", i+1);
  26.         exit(4);
  27.     }
  28.     reloc_buffer[i] = n;
  29. }
  30.  
  31. unsigned char    *copy_buffer;
  32.  
  33. void
  34. warning(int pos, int i, int j)
  35. {
  36.     if(!no_warnings) fprintf(stderr, "Unexpected difference @%d: %08X (basediff %08X)\tmemory: %06X\n", pos, i, j, &(copy_buffer[pos - A_TXTOFF(hdr)]));
  37. }
  38.  
  39. char    known_types[128];
  40.  
  41. int
  42. make_emacs(int file1, FILE *file2, int file3)
  43. {
  44.     struct aexec    hdr;
  45.     long    base1, base2;
  46.     int    i;
  47.     long    pos;
  48.     union {
  49.         long    i;
  50.         struct {
  51.             unsigned int    gc_bit:1;
  52.             unsigned int    type:7;
  53.             unsigned int    ptr:24;
  54.         } o;
  55.     }    val1, val2;
  56.     int    offset;
  57.     int    start_offset;
  58.     long    basediff;
  59.     int    diff;
  60.     int    fuzzy_relocs = 0;
  61.     int    swap_files = 0;
  62.     char    ch;
  63.  
  64.     printf("reading dump headers\n");
  65.     fseek(file2, 0, SEEK_SET);
  66.     fread(&hdr, sizeof(struct aexec), 1, file2);
  67.     if(hdr.a_magic != 0x4544) return(2);
  68.     base2 = hdr.a_AZero1;
  69.     lseek(file1, 0, SEEK_SET);
  70.     read(file1, &hdr, sizeof(struct aexec));
  71.     if(hdr.a_magic != 0x4544) return(1);
  72.     base1 = hdr.a_AZero1;
  73.     basediff = base1 - base2;
  74.     if(!basediff) {
  75.         fprintf(stderr, "Files must not have same basepage address\n");
  76.         exit(5);
  77.     }
  78.     if(basediff < 0) {
  79.         basediff = -basediff;
  80.         swap_files = 1;
  81.     }
  82.     base1 += 0x100;    /* sizeof(BASEPAGE) */
  83.     hdr.a_AZero1 = 0;
  84.     hdr.a_magic = 0x601A;
  85.     printf("writing corrected header\n");
  86.     printf("data start = %d\n", A_DATOFF(hdr));
  87.     lseek(file3, 0, SEEK_SET);
  88.     write(file3, &hdr, sizeof(struct aexec));
  89.     printf("reading text and data\n");
  90.     copy_buffer = (unsigned char *) malloc(A_STROFF(hdr) - A_TXTOFF(hdr));
  91.     read(file1, copy_buffer, A_STROFF(hdr) - A_TXTOFF(hdr));
  92.     printf("adding new relocation info for dumped data\n");
  93.     pos = A_TXTOFF(hdr);
  94.     start_offset = offset = 0;
  95.     i = -1;
  96.     while(pos < A_STROFF(hdr)) {
  97.         val1.i = *(long *)(&(copy_buffer[pos - A_TXTOFF(hdr)]));
  98.         fseek(file2, pos, SEEK_SET);
  99.         fread(&val2.i, sizeof(long), 1, file2);
  100.         diff = swap_files ? val2.i - val1.i : val1.i - val2.i;
  101.         if(diff == basediff) {
  102.         diff_ok:
  103.             known_types[val1.o.type] = 1;
  104.             if(!(i % 1000)) {
  105.                 printf("%4d %6d\r",i,pos);
  106.                 fflush(stdout);
  107.             }
  108.             val1.i -= base1;
  109.             *(long *)(&(copy_buffer[pos - A_TXTOFF(hdr)])) = val1.i;
  110.             if(!start_offset) start_offset = offset;
  111.             else {
  112.                 while(offset > 254) {
  113.                     add_rel(1,++i);
  114.                     offset -= 254;
  115.                 }
  116.                 add_rel(offset,++i);
  117.             }
  118.             offset = 4;
  119.             pos += 4;
  120.         } else if((diff < basediff + FUZZY) &&
  121.               (diff > basediff - FUZZY)) {
  122.             fuzzy_relocs++;
  123.             goto diff_ok;
  124.         } else {
  125.             if(diff && !no_questions) {
  126.                 if(diff & 0xFFFF0000L) {
  127.                     warning(pos,diff,basediff);
  128.                     if(!(val1.o.ptr & 1L) &&
  129.                        val1.o.type <= MAX_LISP_TYPE) {
  130.                         if(!overwrite || !no_warnings)
  131.                         printf(" val1 = %08X,  val2 = %08X,\n"
  132.                                "base1 = %08X, base2 = %08X,\n"
  133.                                " top1 = %08X relocate ? (y|n) "
  134.                         ,val1.i,val2.i
  135.                         ,base1,base2
  136.                         ,base1+A_STROFF(hdr)-sizeof(hdr)+0x100);
  137.                         fflush(stdout);
  138.                         if(val1.o.ptr >= base1 &&
  139.                            val1.o.ptr <= base1 +
  140.                                  A_STROFF(hdr) -
  141.                                  sizeof(hdr) +
  142.                                  0x100) {
  143.                             if(overwrite) {
  144.                                 if(!no_warnings) printf("Y\n");
  145.                                 fuzzy_relocs++;
  146.                                 goto diff_ok;
  147.                             }
  148.                             ch = getchar();
  149.                             printf("\n");
  150.                             if(ch == 'Y' || ch == 'y') {
  151.                                 fuzzy_relocs++;
  152.                                 goto diff_ok;
  153.                             }
  154.                             printf("... ignored\n");
  155.                          } else if(!overwrite || !no_warnings) {
  156.                             printf("N (outside of program)\n");
  157.                          }
  158.                     }
  159.                 }
  160.             }
  161.             offset += 2;
  162.             pos += 2;
  163.         }
  164.     }
  165.     add_rel(0,++i);
  166.     printf("last info was at position %d\n",pos);
  167.     printf("writing text and data\n");
  168.     write(file3, copy_buffer, A_STROFF(hdr) - A_TXTOFF(hdr));
  169.     free(copy_buffer);
  170.     write(file3, &start_offset, sizeof(long));
  171.     printf("writing %d bytes of relocation info", i+1);
  172.     if(fuzzy_relocs) printf(" (%d bytes guessed)", fuzzy_relocs);
  173.     printf("\n");
  174.     lseek(file3, A_STROFF(hdr) + sizeof(long), SEEK_SET);
  175.     write(file3, reloc_buffer, i+1);
  176.     free(reloc_buffer);
  177.     printf("Used tag-fields for pointers:\t");
  178.     for(i = 0; i < 127; i++) if(known_types[i]) printf("%3d ", i);
  179.     printf("\n");
  180.     return(0);
  181. }
  182.  
  183. void
  184. main(int argc, char *argv[])
  185. {
  186.     FILE    *file2;
  187.     int    file1, file3;
  188.     int    error;
  189.     struct sgttyb    sg;
  190.     char    *prg_name;
  191.  
  192.     gtty(0,&sg);
  193.     sg.sg_flags |= CBREAK;
  194.     stty(0,&sg);
  195.     printf("Relocation fix for emacs dump files\n");
  196.     prg_name = argv[0];
  197.     while(argc > 1 && argv[1][0] == '-') {
  198.         switch(argv[1][1]) {
  199.             case 'n' : no_questions = 1; break;
  200.             case 'o' : overwrite = 1; break;
  201.             case 'w' : no_warnings = 1; break;
  202.         }
  203.         argc--;
  204.         argv++;
  205.     }
  206.     if(argc < 4) {
  207.         fprintf(stderr, "Usage: %s [-n] [-o] [-w] dump1 dump2 executable\n", prg_name);
  208.         exit(3);
  209.     }
  210.     if(file1 = open(argv[1],0)) {
  211.         if(file2 = fopen(argv[2],"rb")) {
  212.             setvbuf(file2, NULL, _IOFBF, 10240);
  213.             if(file3 = creat(argv[3],0666)) {
  214.                 switch(error = make_emacs(file1,file2,file3)) {
  215.                     case 1 :
  216.                         fprintf(stderr,
  217.                             "%s: Not an emacs dump file",
  218.                             argv[1]);
  219.                     case 2 :
  220.                         fprintf(stderr,
  221.                             "%s: Not an emacs dump file",
  222.                             argv[2]);
  223.                         break;
  224.                 }
  225.                 close(file3);
  226.             } else perror(argv[3]);
  227.             fclose(file2);
  228.         } else perror(argv[2]);
  229.         close(file1);
  230.     } else perror(argv[1]);
  231.     exit(error);
  232. }
  233.