home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 375.lha / libtos / libtos.c < prev    next >
C/C++ Source or Header  |  1990-05-02  |  6KB  |  316 lines

  1.  
  2. /*
  3.  *  LIBTOS.C
  4.  *
  5.  *  This program takes two arguments, AMIGA.LIB, and an OUTPUT FILE,
  6.  *  and systematically converts all references to the variables below
  7.  *  from ABSOLUTE to A4-RELATIVE (Using Lattice's DATA-REL16 relocation
  8.  *  info and symbol extensions).
  9.  *
  10.  *  It converts absolute move's into an A4 relative move and a nop to
  11.  *  take up the extra word which is now no longer used.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16.  
  17. short SymLens[64];
  18.  
  19. char *FixSymbols[64] = {
  20.     "_MathBase",
  21.     "_ClistBase",
  22.     "_ConsoleDevice",
  23.     "_DiskfontBase",
  24.     "_DOSBase",
  25.     "_SysBase",
  26.     "_GfxBase",
  27.     "_IconBase",
  28.     "_IntuitionBase",
  29.     "_LayersBase",
  30.     "_MathBase",
  31.     "_PothoBase",
  32.     "_TimerBase",
  33.     "_TranslatorBase",
  34.     "_MathIeeeDoubBasBase",
  35.     "_MathTransBase",
  36.     "_ExpansionBase",
  37.     "_RomBootBase",
  38.     "_MathIeeeDoubTransBase",
  39.  
  40.     /*
  41.      *    1.4 stuff (doesn't effect anything if you
  42.      *           run on a 1.3 amiga.lib)
  43.      *
  44.      *    BETA BETA, developers should add to this
  45.      *    list as needed.
  46.      */
  47.  
  48.  
  49.     "_BattClockBase",
  50.     "_BattMemBase",
  51.     "_CxBase",
  52.     "_GadToolsBase",
  53.     "_KeymapBase",
  54.     "_MathIeeeSingBasBase",
  55.     "_MathIeeeSingTransBase",
  56.     "_PotgoBase",
  57.     "_UtilityBase",
  58.     "_WorkbenchBase",
  59.     NULL
  60. };
  61.  
  62. short DDebug;
  63. short Error;
  64.  
  65. typedef unsigned char ubyte;
  66. typedef unsigned short uword;
  67. typedef unsigned long ulong;
  68.  
  69. void InitSyms();
  70.  
  71. #define MAXHUNKS    32
  72.  
  73. main(ac, av)
  74. char *av[];
  75. {
  76.     FILE *fi;
  77.     FILE *fo;
  78.     short hunkno;
  79.     long *base;
  80.     long *scan;
  81.     long *bend;
  82.     long bytes;
  83.  
  84.     InitSyms();
  85.     if (ac < 3) {
  86.     puts("libtoslib amiga.lib samiga.lib");
  87.     exit(1);
  88.     }
  89.     if (ac > 3)
  90.     DDebug = 1;
  91.     fi = fopen(av[1], "r");
  92.     if (fi == NULL) {
  93.     printf("couldn't open %s\n", av[1]);
  94.     exit(1);
  95.     }
  96.     fseek(fi, 0L, 2);
  97.     bytes = ftell(fi);
  98.     fseek(fi, 0L, 0);
  99.     base = malloc(bytes);
  100.     if (base == NULL) {
  101.     puts("ran out of memory");
  102.     exit(1);
  103.     }
  104.     fread((char *)base, bytes, 1, fi);
  105.     fclose(fi);
  106.     bend = base + (bytes >> 2);
  107.  
  108.     for (scan = base; scan < bend;) {
  109.     ubyte *data;
  110.     long dlen;
  111.     short htype;
  112.  
  113.     hunkno = 0;
  114.     if (*scan != 0x3E7) {
  115.         printf("Expected hunk_unit, got %08lx\n", *scan);
  116.         exit(1);
  117.     }
  118.     scan += scan[1] + 2;
  119.  
  120.     /*
  121.      *  scan the object module
  122.      */
  123.  
  124.     data = NULL;
  125.     dlen = 0;
  126.     htype = 0;
  127.  
  128.     while (scan < bend && *scan != 0x3E7) {
  129.         ulong len;
  130.  
  131.         switch((uword)*scan) {
  132.         case 0x3E8:         /*    HUNK_NAME    */
  133.         scan += scan[1] + 2;
  134.         break;
  135.         case 0x3E9:         /*    HUNK_CODE    */
  136.         case 0x3EA:         /*    HUNK_DATA    */
  137.         data = (char *)(scan + 2);
  138.         dlen = scan[1] << 2;
  139.         if (*scan == 0x3EA)
  140.             htype = 1;
  141.         else
  142.             htype = 2;
  143.  
  144.         {
  145.             ++hunkno;
  146.         }
  147.         scan += scan[1] + 2;
  148.         break;
  149.         case 0x3EB:         /*    HUNK_BSS    */
  150.         htype = 0;
  151.         scan += 2;
  152.         break;
  153.         case 0x3EC:         /*    HUNK_RELOC32    */
  154.         case 0x3ED:         /*    HUNK_RELOC16-PC */
  155.         case 0x3EE:         /*    HUNK_RELOC8    */
  156.         case 0x3F8:         /*    HUNK_RELOC16-D    (special) */
  157.         ++scan;
  158.         while (*scan)
  159.             scan += *scan + 2;
  160.         ++scan;
  161.         break;
  162.         case 0x3EF:         /*    HUNK_EXT    */
  163.         case 0x3F0:         /*    HUNK_SYMBOL    */
  164.         ++scan;
  165.         while (len = *scan) {
  166.             ubyte type = len >> 24;
  167.             long *base = scan;
  168.  
  169.             len &= 0x00FFFFFF;
  170.             if (DDebug)
  171.             printf("extsym %3d %.*s\n", type, len*4, scan + 1);
  172.             scan += len + 1;
  173.  
  174.             switch(type) {
  175.             case 0:        /*    SYMB    */
  176.             case 1:        /*    DEF    */
  177.             case 2:        /*    ABS    */
  178.             case 3:        /*    RES    */
  179.             ++scan;     /*    skip value  */
  180.             break;
  181.             case 130:        /*    COMMON    */
  182.             ++scan;     /*    skip common size */
  183.             /* fall through */
  184.             case 129:        /*    REF32    */
  185.             if (type == 129 && htype == 2) {
  186.                 if (ScanRelocations(scan[0], scan + 1, data, dlen, base + 1, len*4))
  187.                 *base = (*base & 0x00FFFFFF) | (134 << 24);     /*  convert from ABS32 to DATA-REL16    */
  188.             }
  189.             case 131:        /*    REF16    */
  190.             case 132:        /*    REF8    */
  191.             case 134:        /*    REF16D    */
  192.                     /*    skip relocation info */
  193.             scan += scan[0] + 1;
  194.             break;
  195.             default:
  196.             printf("Symbol type %d unknown", type);
  197.             exit(1);
  198.             }
  199.         }
  200.         ++scan;     /*    skip 0 terminator */
  201.         break;
  202.         case 0x3F1:         /*    HUNK_DEBUG        */
  203.         scan += scan[1] + 2;
  204.         break;
  205.         case 0x3F2:         /*    HUNK_END        */
  206.         data = NULL;
  207.         dlen = 0;
  208.         ++hunkno;
  209.         ++scan;
  210.         break;
  211.         default:
  212.         printf("Unknown hunk type $%08lx", *scan);
  213.         exit(1);
  214.         }
  215.     }
  216.     }
  217.  
  218.     if (Error) {
  219.     puts("ERROR OCCURED, OUTPUT NOT WRITTEN");
  220.     return(1);
  221.     }
  222.  
  223.     fo = fopen(av[2], "w");
  224.     if (fo == NULL) {
  225.     printf("couldn't create %s\n", av[2]);
  226.     return(1);
  227.     }
  228.     fwrite((char *)base, bytes, 1, fo);
  229.     fclose(fo);
  230.     return(0);
  231. }
  232.  
  233. void
  234. InitSyms()
  235. {
  236.     short i;
  237.     for (i = 0; FixSymbols[i]; ++i) {
  238.     SymLens[i] = strlen(FixSymbols[i]);
  239.     }
  240. }
  241.  
  242. ScanRelocations(entries, scan, data, dlen, name, len)
  243. long entries;
  244. long *scan;
  245. char *data;
  246. long dlen;
  247. char *name;
  248. int len;
  249. {
  250.  
  251.     printf("Relocation: %2d relocations for symbol %-20.*s", entries, len, name);
  252.  
  253.     {
  254.     short i;
  255.     static char Buf[256];
  256.  
  257.     strncpy(Buf, name, len);
  258.     Buf[len] = 0;
  259.  
  260.     for (i = 0; SymLens[i]; ++i) {
  261.         if (strcmp(FixSymbols[i], Buf) == 0)
  262.         break;
  263.     }
  264.     if (SymLens[i] == 0) {
  265.         puts("(not modified)");
  266.         return(0);
  267.     }
  268.     }
  269.     puts("(modifying)");
  270.  
  271.     while (entries) {
  272.     long index = *scan;
  273.     uword *tscan;
  274.     uword opcode;
  275.  
  276.     if (index < 0 || index > dlen - 4) {
  277.         printf("relocation index out of range: %d/%d\n", index, dlen);
  278.         Error = 1;
  279.     }
  280.     tscan = (uword *)(data + index - 2);
  281.  
  282.     opcode = *tscan;
  283.     printf("\topcode %04x\n", opcode);
  284.  
  285.     /*
  286.      *  convert abs to off(A4)  0010 0000 0110 1100
  287.      */
  288.  
  289.     switch(opcode) {
  290.     case 0x2079:    /*  move.l  abslong,A0    */
  291.         tscan[0] = 0x206C;
  292.         tscan[1] = tscan[2];
  293.         tscan[2] = 0x4E71;
  294.         break;
  295.     case 0x2C79:    /*  move.l  abslong,A6    */
  296.         tscan[0] = 0x2C6C;
  297.         tscan[1] = tscan[2];
  298.         tscan[2] = 0x4E71;
  299.         break;
  300.     case 0xD1F9:    /*  adda.l  abslong,A0    */
  301.         tscan[0] = 0xD1EC;
  302.         tscan[1] = tscan[2];
  303.         tscan[2] = 0x4E71;
  304.         break;
  305.     default:
  306.         printf("\tWarning, opcode not understood, could not modify\n");
  307.         Error = 1;
  308.         break;
  309.     }
  310.     ++scan;
  311.     --entries;
  312.     }
  313.     return(1);
  314. }
  315.  
  316.