home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / linker.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  51.1 KB  |  1,962 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains the Harvest C linker.  It is designed to be functionally
  35.  * compatible with the MPW linker.  THIS FILE SHOULD BE IMPORTANT IN THE PORT
  36.  * OF GCC.
  37.  * 
  38.  * 
  39.  * 
  40.  */
  41.  
  42.  
  43. #include "conditcomp.h"
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include "structs.h"
  47.  
  48. #include "linkstruct.h"
  49. #include "CHarvestApp.h"
  50. #include "CHarvestDoc.h"
  51. #include "CHarvestOptions.h"
  52. #include "CErrorLog.h"
  53.  
  54. extern CHarvestApp *gApplication;
  55. extern CHarvestDoc *gProject;
  56. extern    CErrorLog    *gErrs;
  57.  
  58. #ifdef HDEBUG
  59. FILE *dumpFile;
  60. #endif
  61.  
  62. FILE *fopenMAC(char *name,short vRefNum,long dirID,char *mode);
  63.  
  64. /* 
  65.     patchkinds
  66.     
  67.     CODE->CODE     1
  68.     CODE->DATA    2
  69.     DATA->CODE    3
  70.     DATA->DATA    4
  71. */
  72.  
  73. #pragma segment LinkerSeg
  74.  
  75. int                             LinkErrorCount;
  76.  
  77. void
  78. LinkerError(char *errstr)
  79. {
  80.     gErrs->Hprintf("%s",errstr);
  81.     LinkErrorCount++;
  82. }
  83.  
  84. void
  85. LinkerErrorSYM(char *errstr, char *name)
  86. {
  87.     char                            err[128];
  88.     strcpy(err, errstr);
  89.     strcat(err, (name));
  90.     LinkerError(err);
  91. }
  92.  
  93. unsigned int
  94. fgetw(FILE * thef)
  95. {
  96.     unsigned int                             wd;
  97.     wd = getc(thef);
  98.     wd = (wd << 8) | getc(thef);
  99.     return wd;
  100. }
  101.  
  102. unsigned long
  103. fgetl(FILE * thef)
  104. {
  105.     unsigned long                   lg;
  106.     lg = fgetw(thef);
  107.     lg = (lg << 16) | fgetw(thef);
  108.     return lg;
  109. }
  110.  
  111. #define STARTMODSIZE 50000
  112.  
  113. void
  114. ZeroBytes(char P__H * buf,  long bufsize)
  115. /* Zero out a range of memory */
  116. {
  117.     register  long          ndx = 0;
  118.     while (ndx < bufsize)
  119.     Via(buf)[ndx++] = 0;
  120. }
  121.  
  122. LinkerFileVia_t
  123. ReadObjectFile(char *fname, short volrefnum, long dirID)
  124. /*
  125.  * Reads an object file, creating data structures which are returned. Returns
  126.  * NULL on file not found
  127.  */
  128. {
  129.     LinkerFileVia_t                 result = NULL;
  130.     FILE *               thef;
  131.     ModuleVia_t                     CurrentCodeModule = NULL;
  132.     ModuleVia_t                     CurrentDataModule = NULL;
  133.     int                             c;
  134.     int                    c2;
  135.     int                             done = 0;
  136.     int                             recordcount = 0;
  137.     long                            val;
  138.     long                            len;
  139.     OSErr                           bad;
  140.     long                            sz;
  141.     long                            startoffset;
  142.     long                            repcount;
  143.     long                            offset;
  144.     long                            endoffset;
  145.     long                            ndx;
  146.     char                            tempname[256];
  147.     char                            mesg[256];
  148.     DictionaryVia_t                 newdict;
  149.     FSSpec                          filespec;
  150.     ReferenceVia_t                  newref;
  151.     ModuleVia_t                     newmod;
  152.     int                             ID;
  153.  
  154. #ifdef HDEBUG
  155.     fprintf(dumpFile,"Reading object file: %s\n",fname);
  156. #endif
  157.     
  158.     CurrentCodeModule = NULL;
  159.     CurrentDataModule = NULL;
  160.     result = Ealloc(sizeof(LinkerFile_t));
  161.     Via(result)->ModuleList = NULL;
  162.     Via(result)->DictionaryList = NULL;
  163.     Via(result)->isNESTED = 0;
  164.     Via(result)->version = 0;
  165.     Via(result)->next = NULL;
  166.     strcpy(Via(result)->name, fname);
  167.     bad = FindOMFFile(fname, volrefnum, dirID, &filespec);
  168.     if (bad)
  169.     return NULL;
  170.     thef = fopenMAC((char *) filespec.name, filespec.vRefNum, filespec.parID, "rb");
  171.     while (!done) {
  172.     /* done will be set true when we find endoffile */
  173.     recordcount++;
  174.     gApplication->SpinCursor();
  175.     c = getc(thef);
  176.     if (c == EOF)
  177.         done = 1;
  178.     else
  179.         switch (c) {
  180.         case MPWRec_Pad:
  181.         break;
  182.         case MPWRec_First:
  183.         c = getc(thef);
  184.         Via(result)->version = fgetw(thef);
  185.         if (c & 1)
  186.             Via(result)->isNESTED = 1;
  187.         break;
  188.         case MPWRec_Last:
  189.         c = getc(thef);
  190.         if (c)
  191.             LinkerError("Bad Last record");
  192.         break;
  193.         case MPWRec_Comment:
  194.         c = getc(thef);
  195.         sz = fgetw(thef);
  196.         sz -= 4;
  197.         while (sz--)
  198.             getc(thef);
  199.         break;
  200.         case MPWRec_Dictionary:
  201.         c = getc(thef);    /* flags */
  202.         sz = fgetw(thef);
  203.         ID = fgetw(thef);
  204.         sz -= 6;
  205.         while (sz > 0) {
  206.             val = getc(thef);    /* length of next string */
  207.             sz--;
  208.             ndx = 0;
  209.             len = val;
  210.             while (val--) {
  211.             tempname[ndx++] = getc(thef);
  212.             sz--;
  213.             }
  214.             tempname[ndx] = 0;
  215.             newdict = Ealloc(sizeof(Dictionary_t) + strlen(tempname) + 1);
  216.             strcpy(Via(newdict)->name, tempname);
  217.             Via(newdict)->ID = ID++;
  218. #ifdef HDEBUG
  219.             fprintf(dumpFile,"Dictionary: %s\t\t%d\n",tempname,Via(newdict)->ID);
  220. #endif
  221.             Via(newdict)->next = Via(result)->DictionaryList;
  222.             Via(result)->DictionaryList = newdict;
  223.         }
  224.         break;
  225.         case MPWRec_Module:
  226.         newmod = Ealloc(sizeof(Module_t));
  227.         #ifdef OLDMEM
  228.         HLock((Handle) newmod);
  229.         #endif
  230.         Via(newmod)->Bytes = NULL;
  231.         Via(newmod)->sizeBytes = 0;
  232.         Via(newmod)->file = result;
  233.         Via(newmod)->ReferenceList = NULL;
  234.         Via(newmod)->Entries = NULL;
  235.         val = getc(thef);    /* flags */
  236.         Via(newmod)->isACTIVE = (val & 128);
  237.         Via(newmod)->isMAIN = (val & 16);
  238.         Via(newmod)->isEXTERN = (val & 8);
  239.         Via(newmod)->isENTRY = NULL;
  240.         Via(newmod)->offset = 0;
  241.         Via(newmod)->isCODE = !(val & 1);
  242.         Via(newmod)->externref = 0;
  243.         Via(newmod)->ID = fgetw(thef);
  244.         if (Via(newmod)->isCODE) {
  245.             Via(newmod)->segment = fgetw(thef);
  246.             Via(newmod)->modulesize = 0;
  247.             CurrentCodeModule = newmod;
  248.         } else {
  249.             Via(newmod)->modulesize = fgetw(thef);
  250.             Via(newmod)->segment = 0;
  251.             CurrentDataModule = newmod;
  252.         }
  253. #ifdef HDEBUG
  254.         fprintf(dumpFile,"Module %d\n",Via(newmod)->ID);
  255. #endif
  256.         Via(newmod)->segmentoffset = 0;
  257.         Via(newmod)->A5offset = 0;
  258.         Via(newmod)->next = Via(result)->ModuleList;
  259.         Via(result)->ModuleList = newmod;
  260.         #ifdef OLDMEM
  261.         HUnlock((Handle) newmod);
  262.         #endif
  263.         break;
  264.         case MPWRec_Entry_Point:
  265.         newmod = Ealloc(sizeof(Module_t));
  266.         Via(newmod)->Bytes = NULL;
  267.         Via(newmod)->sizeBytes = 0;
  268.         Via(newmod)->file = result;
  269.         Via(newmod)->ReferenceList = NULL;
  270.         Via(newmod)->Entries = NULL;
  271.         #ifdef OLDMEM
  272.         HLock((Handle) newmod);
  273.         #endif
  274.         val = getc(thef);
  275.         ID = fgetw(thef);
  276.         offset = fgetl(thef);
  277.         Via(newmod)->ID = ID;
  278.         Via(newmod)->offset = offset;
  279.         Via(newmod)->modulesize = 0;
  280.         Via(newmod)->isEXTERN = (val & 8);
  281.         Via(newmod)->isMAIN = (val & 16);
  282.         Via(newmod)->isCODE = !(val & 1);
  283.         Via(newmod)->segmentoffset = 0;
  284.         Via(newmod)->externref = 0;
  285.         Via(newmod)->A5offset = 0;
  286.         if (val & 1) {
  287.             Via(newmod)->next = Via(CurrentDataModule)->Entries;
  288.             Via(CurrentDataModule)->Entries = newmod;
  289.             Via(newmod)->segment = Via(CurrentDataModule)->segment;
  290.             Via(newmod)->isENTRY = CurrentDataModule;
  291.         } else {
  292.             Via(newmod)->next = Via(CurrentCodeModule)->Entries;
  293.             Via(CurrentCodeModule)->Entries = newmod;
  294.             Via(newmod)->segment = Via(CurrentCodeModule)->segment;
  295.             Via(newmod)->isENTRY = CurrentCodeModule;
  296.         }
  297.         #ifdef OLDMEM
  298.         HUnlock((Handle) newmod);
  299.         #endif
  300.         break;
  301.         case MPWRec_Size:
  302.         val = getc(thef);
  303.         sz = fgetl(thef);
  304.         if (val & 1) {
  305.             if (sz > Via(CurrentDataModule)->modulesize)
  306.             Via(CurrentDataModule)->modulesize = sz;
  307.         } else {
  308.             if (sz > Via(CurrentCodeModule)->modulesize)
  309.             Via(CurrentCodeModule)->modulesize = sz;
  310.         }
  311.         break;
  312.         case MPWRec_Contents:
  313.         val = getc(thef);
  314.         if (val & 1) {
  315. #ifdef HDEBUG
  316.             fprintf(dumpFile,"Data Contents:\n");
  317. #endif
  318.             newmod = CurrentDataModule;
  319.         }
  320.         else {
  321. #ifdef HDEBUG
  322.             fprintf(dumpFile,"Code Contents:\n");
  323. #endif
  324.             newmod = CurrentCodeModule;
  325.         }
  326.         sz = fgetw(thef);
  327.         sz -= 4;
  328.         offset = 0;
  329.         if (val & 8) {
  330.             sz -= 4;
  331.             offset = fgetl(thef);
  332.         }
  333.         repcount = 1;
  334.         if (val & 16) {
  335.             sz -= 2;
  336.             repcount = fgetw(thef);
  337.         }
  338. #ifdef HDEBUG
  339.         fprintf(dumpFile,"Contents:sz %d offset %ld repcount %d\n",sz,offset,repcount);
  340. #endif
  341.         if (Via(newmod)->Bytes) {
  342. #ifdef HDEBUG
  343.             fprintf(dumpFile,"Contents:Bytes already exists\n");
  344. #endif
  345.                 if (((sz * repcount) + offset) > Via(newmod)->sizeBytes) {
  346.             #ifdef OLDMEM
  347.                 SetHandleSize((Handle) Via(newmod)->Bytes, (sz * repcount) + offset + 10);
  348.             #else
  349.             {
  350.                 char *newBytes;
  351.                 newBytes = (char *) icemalloc((sz * repcount) + offset + 10);
  352.                 memcpy(newBytes,Via(newmod)->Bytes,Via(newmod)->sizeBytes);
  353.                 Via(newmod)->sizeBytes = ((sz * repcount) + offset + 10);
  354.                 icefree(Via(newmod)->Bytes);
  355.                 Via(newmod)->Bytes = newBytes;
  356.             }
  357.             #endif
  358.                 if (MemError()) {
  359.                     LinkerError("Unable to allocate memory for second contents record");
  360.                     return NULL;
  361.                 }
  362.             }
  363.         } else {
  364.             Via(newmod)->Bytes = Ealloc((sz * repcount) + offset + 10);
  365.             Via(newmod)->sizeBytes = ((sz * repcount) + offset + 10);
  366.         }
  367.         {
  368.             int count = 0;
  369.             startoffset = offset;
  370. #ifdef HDEBUG
  371.             fprintf(dumpFile,"Contents values: \n");
  372. #endif
  373.             while (sz--) {
  374.                 c = getc(thef);
  375.                 count++;
  376.                 if (!(val & 1)) {
  377. #ifdef HDEBUG
  378.                     fprintf(dumpFile," %X",c);
  379.                     if (count==8) {fprintf(dumpFile,"\n");count = 0;}
  380. #endif
  381.                 }
  382.                 Via(Via(newmod)->Bytes)[offset++] = c;
  383.             }
  384. #ifdef HDEBUG
  385.                 fprintf(dumpFile,"\n");
  386.                 if (!(val & 1) && newmod->ID == 529) {
  387.                    char buf[256];
  388.                 sprintf(buf,"Hex dump of contents:");
  389.                 hex_dump(dumpFile,buf,newmod->Bytes,newmod->sizeBytes);
  390.                 Debugger();
  391.                 }
  392. #endif
  393.         }
  394.         endoffset = offset;
  395.         while (--repcount) {
  396. #ifdef HDEBUG
  397.             if (!(val & 1)) fprintf(dumpFile,"Repeating\n");
  398. #endif
  399.                 ndx = startoffset;
  400.                 while (ndx < endoffset) {
  401.                  Via(Via(newmod)->Bytes)[offset++] = Via(Via(newmod)->Bytes)[ndx++];
  402.                 }
  403.         }
  404.         if (Via(newmod)->modulesize < offset)
  405.             Via(newmod)->modulesize = offset;
  406.         break;
  407.         case MPWRec_Reference:
  408.         val = getc(thef);
  409.         sz = fgetw(thef);
  410.         newref = Ealloc(sizeof(Reference_t));
  411.         #ifdef OLDMEM
  412.         HLock((Handle) newref);
  413.         #endif
  414.         Via(newref)->isCOMPUTED = 0;
  415.         Via(newref)->ID = fgetw(thef);
  416.         Via(newref)->isA5REL = (val & 128);
  417.         if (val & 16)
  418.             Via(newref)->patchsize = 16;
  419.         else
  420.             Via(newref)->patchsize = 32;
  421.         Via(newref)->WhichModule = NULL;
  422.         Via(newref)->OtherModule = NULL;
  423.         sz -= 6;
  424.         if (val & 8)
  425.             Via(newref)->RefCount = sz / 4;
  426.         else
  427.             Via(newref)->RefCount = sz / 2;
  428.         Via(newref)->Offsets = Ealloc(sizeof(long) * Via(newref)->RefCount + 1);
  429.         ndx = 0;
  430.         while (ndx < Via(newref)->RefCount) {
  431.             if (val & 8)
  432.             Via(Via(newref)->Offsets)[ndx] = fgetl(thef);
  433.             else
  434.             Via(Via(newref)->Offsets)[ndx] = fgetw(thef);
  435. #ifdef HDEBUG
  436.                 fprintf(dumpFile,"Reference to %x size %d offset %x\n",
  437.                 Via(newref)->ID,Via(newref)->patchsize,Via(Via(newref)->Offsets)[ndx]);
  438. #endif
  439.             ndx++;
  440.         }
  441.         if (val & 1)
  442.             newmod = CurrentDataModule;
  443.         else
  444.             newmod = CurrentCodeModule;
  445.         Via(newref)->next = Via(newmod)->ReferenceList;
  446.         Via(newmod)->ReferenceList = newref;
  447.         #ifdef OLDMEM
  448.         HUnlock((Handle) newref);
  449.         #endif
  450.         break;
  451.         case MPWRec_Computed_Reference:
  452.         val = getc(thef);
  453.         sz = fgetw(thef);
  454.         newref = Ealloc(sizeof(Reference_t));
  455.         #ifdef OLDMEM
  456.         HLock((Handle) newref);
  457.         #endif
  458.         Via(newref)->isCOMPUTED = 1;
  459.         Via(newref)->ID = fgetw(thef);
  460.         Via(newref)->ID2 = fgetw(thef);
  461.         if (val & 16)
  462.             Via(newref)->patchsize = 16;
  463.         else if (val & 32)
  464.             Via(newref)->patchsize = 8;
  465.         else
  466.             Via(newref)->patchsize = 32;
  467.         Via(newref)->WhichModule = NULL;
  468.         Via(newref)->OtherModule = NULL;
  469.         sz -= 8;
  470.         if (val & 8)
  471.             Via(newref)->RefCount = sz / 4;
  472.         else
  473.             Via(newref)->RefCount = sz / 2;
  474.         Via(newref)->Offsets = Ealloc(sizeof(long) * Via(newref)->RefCount + 1);
  475.         ndx = 0;
  476.         while (ndx < Via(newref)->RefCount) {
  477.             if (val & 8)
  478.             Via(Via(newref)->Offsets)[ndx] = fgetl(thef);
  479.             else
  480.             Via(Via(newref)->Offsets)[ndx] = fgetw(thef);
  481.             ndx++;
  482.         }
  483.         if (val & 1)
  484.             newmod = CurrentDataModule;
  485.         else
  486.             newmod = CurrentCodeModule;
  487.         Via(newref)->next = Via(newmod)->ReferenceList;
  488.         Via(newmod)->ReferenceList = newref;
  489.         #ifdef OLDMEM
  490.         HUnlock((Handle) newref);
  491.         #endif
  492.         break;
  493.         default:
  494.         LinkerError("Unrecognized record type");
  495.         break;
  496.         }
  497.     }
  498.     fclose(thef);
  499. #ifdef HDEBUG
  500.     fprintf(dumpFile,"Done reading %s (%d records)\n",fname,recordcount);
  501. #endif
  502.     return result;
  503. }
  504.  
  505. ModuleVia_t
  506. FindModuleID(unsigned short ID, LinkerFileVia_t file)
  507. /*
  508.  * Given the data structures for a single OBJ file, search for a Module with
  509.  * the given ID.
  510.  */
  511. {
  512.     ModuleVia_t                     cur = NULL;
  513.     ModuleVia_t                     ecur;
  514.     if (file)
  515.     cur = Via(file)->ModuleList;
  516.     while (cur) {
  517.     if (Via(cur)->ID == ID)
  518.         return cur;
  519.     ecur = Via(cur)->Entries;
  520.     while (ecur) {
  521.         if (Via(ecur)->ID == ID) {
  522.         return ecur;
  523.         }
  524.         ecur = Via(ecur)->next;
  525.     }
  526.     cur = Via(cur)->next;
  527.     }
  528.     return NULL;
  529. }
  530.  
  531. DictionaryVia_t
  532. FindStrName(char *name, LinkerFileVia_t file)
  533. /*
  534.  * Given the data structures for a single OBJ file, search for a Dictionary
  535.  * entry with the given name.
  536.  */
  537. {
  538.     DictionaryVia_t                 cur;
  539.     cur = Via(file)->DictionaryList;
  540.     while (cur) {
  541.     if (!strcmp((name), (Via(cur)->name)))
  542.         return cur;
  543.     cur = Via(cur)->next;
  544.     }
  545.     return NULL;
  546. }
  547.  
  548. ModuleVia_t
  549. FindNameAll(char *name, LinkerFileVia_t file)
  550. /* Given a name, search all files for a module with that name */
  551. {
  552.     DictionaryVia_t                 cur;
  553.     ModuleVia_t                     mod;
  554.     while (file) {
  555.     cur = Via(file)->DictionaryList;
  556.     while (cur) {
  557.         if (!strcmp((name), (Via(cur)->name))) {
  558.         mod = FindModuleID(Via(cur)->ID, file);
  559.         if (mod)
  560.             return mod;
  561.         }
  562.         cur = Via(cur)->next;
  563.     }
  564.     file = Via(file)->next;
  565.     }
  566.     return NULL;
  567. }
  568.  
  569. DictionaryVia_t
  570. FindIDName(unsigned short ID, LinkerFileVia_t file)
  571. /*
  572.  * Given the data structures for a single OBJ file, search for a Dictionary
  573.  * entry with the given ID.
  574.  */
  575. {
  576.     DictionaryVia_t                 cur = NULL;
  577.     if (file)
  578.     cur = Via(file)->DictionaryList;
  579.     while (cur) {
  580.     if (Via(cur)->ID == ID)
  581.         return cur;
  582.     cur = Via(cur)->next;
  583.     }
  584.     return NULL;
  585. }
  586.  
  587. ModuleVia_t
  588. FindModuleExternal(unsigned short ID, LinkerFileVia_t localfile, DictionaryVia_t * dict,
  589.            LinkerFileVia_t * foundfile, LinkerFileVia_t allfiles)
  590. /*
  591.  * Given a single OBJ file and an ID within that file, look up the name for
  592.  * that ID.  Then, search all other files (given the file list), for a Module
  593.  * with that name.  Return the module found.
  594.  */
  595. {
  596.     ModuleVia_t                     result = NULL;
  597.     DictionaryVia_t                 namerec;
  598.     namerec = FindIDName(ID, localfile);
  599.     if (namerec) {
  600.     DictionaryVia_t                 testname;
  601.     LinkerFileVia_t                 curfile;
  602.     curfile = allfiles;
  603. #ifdef OLDMEM
  604.     HLock((Handle) namerec);
  605. #endif
  606.     while (curfile) {
  607.         if (curfile != localfile) {
  608.         testname = FindStrName(Via(namerec)->name, curfile);
  609.         if (testname) {
  610.             result = FindModuleID(Via(testname)->ID, curfile);
  611.             if (result) {
  612.             if (Via(result)->isEXTERN) {
  613.                 *dict = testname;
  614.                 *foundfile = curfile;
  615.                 return result;
  616.             }
  617.             else {
  618.                 result = NULL;
  619.             }
  620.             }
  621.         }
  622.         }
  623.         curfile = Via(curfile)->next;
  624.     }
  625. #ifdef OLDMEM
  626.     HUnlock((Handle) namerec);
  627. #endif
  628.     }
  629.     return result;
  630. }
  631.  
  632. int
  633. ResolveAllReferences(LinkerFileVia_t files)
  634. /* Resolves all references, returns the number of unresolved */
  635. {
  636.     int                             unresolved = 0;
  637.     LinkerFileVia_t                 curfile = files;
  638.     LinkerFileVia_t                 otherfile = NULL;
  639.     DictionaryVia_t                 modname = NULL;
  640.     ModuleVia_t                     curmod;
  641.     ModuleVia_t                     doubdef;
  642.     ReferenceVia_t                  curref;
  643.     char                            err[256];
  644.  
  645.     while (curfile) {
  646. #ifdef HDEBUG
  647.         fprintf(dumpFile,"Resolving references for %s\n",curfile->name);
  648. #endif
  649.     curmod = Via(curfile)->ModuleList;
  650.     while (curmod) {
  651.         ModuleVia_t                     referenced = NULL;
  652.         gApplication->SpinCursor();
  653.         /* First, we check for double definitions. */
  654.         modname = NULL;
  655.         otherfile = NULL;
  656.         doubdef = FindModuleExternal(Via(curmod)->ID, curfile, &modname, &otherfile, files);
  657.         if (doubdef && modname) {
  658.         DictionaryVia_t                 dict;
  659.         if (doubdef->isEXTERN && curmod->isEXTERN) {
  660.             dict = FindIDName(Via(curmod)->ID, curfile);
  661.             #ifdef OLDMEM
  662.             HLock((Handle) modname);
  663.             HLock((Handle) otherfile);
  664.             HLock((Handle) curfile);
  665.             HLock((Handle) dict);
  666.             #endif
  667.             sprintf(err, "# Doubly defined : %s(%d) in %s found as %s(%d) in file %s",
  668.                 Via(dict)->name, Via(dict)->ID,
  669.                 Via(curfile)->name, Via(modname)->name, Via(modname)->ID, Via(otherfile)->name);
  670.             #ifdef OLDMEM
  671.             HUnlock((Handle) dict);
  672.             HUnlock((Handle) modname);
  673.             HUnlock((Handle) otherfile);
  674.             HUnlock((Handle) curfile);
  675.             #endif
  676.             LinkerError(err);
  677.         }
  678.         }
  679.         curref = Via(curmod)->ReferenceList;
  680.         while (curref) {
  681.         if (referenced = FindModuleID(Via(curref)->ID, curfile)) {
  682. #ifdef HDEBUG
  683.             fprintf(dumpFile,"Reference to %d found within file\n",Via(curref)->ID);
  684. #endif
  685.             Via(referenced)->isACTIVE = 1;
  686.             if (Via(curmod)->isCODE) {
  687.             if (Via(referenced)->isCODE) {
  688.                 Via(curref)->patchkind = 1;
  689.             } else {
  690.                 Via(curref)->patchkind = 2;
  691.             }
  692.             } else {
  693.             if (Via(referenced)->isCODE) {
  694.                 Via(curref)->patchkind = 3;
  695.             } else {
  696.                 Via(curref)->patchkind = 4;
  697.             }
  698.             }
  699.             if (Via(referenced)->isENTRY) {
  700.             Via(Via(referenced)->isENTRY)->isACTIVE = 1;
  701.             }
  702.             Via(curref)->WhichModule = referenced;
  703.         } else if (referenced =
  704.                FindModuleExternal(Via(curref)->ID, curfile, &modname, &otherfile, files)) {
  705. #ifdef HDEBUG
  706.             fprintf(dumpFile,"Reference to %s(%d) found in %s as %d\n",
  707.                 modname->name,Via(curref)->ID,otherfile->name,referenced->ID);
  708. #endif
  709.             Via(referenced)->externref = 1;
  710.             if (Via(curmod)->isCODE) {
  711.             if (Via(referenced)->isCODE) {
  712.                 Via(curref)->patchkind = 1;
  713.             } else {
  714.                 Via(curref)->patchkind = 2;
  715.             }
  716.             } else {
  717.             if (Via(referenced)->isCODE) {
  718.                 Via(curref)->patchkind = 3;
  719.             } else {
  720.                 Via(curref)->patchkind = 4;
  721.             }
  722.             }
  723.             if (Via(referenced)->isENTRY) {
  724.             Via(Via(referenced)->isENTRY)->isACTIVE = 1;
  725.             }
  726.             Via(referenced)->isACTIVE = 1;
  727.             Via(curref)->WhichModule = referenced;
  728.         } else {
  729.             DictionaryVia_t                 dict;
  730.             dict = FindIDName(Via(curref)->ID, curfile);
  731.             if (dict) {
  732.             #ifdef OLDMEM
  733.             HLock((Handle) dict);
  734.         #endif
  735.             sprintf(err, "# Unresolved : %s, referenced in %s",
  736.                 Via(dict)->name,
  737.                 Via(curfile)->name);
  738.             LinkerError(err);
  739.             #ifdef OLDMEM
  740.             HUnlock((Handle) dict);
  741.             #endif
  742.             }
  743.             unresolved++;
  744.             Via(curref)->WhichModule = NULL;
  745.         }
  746.         if (Via(curref)->isCOMPUTED) {
  747.             if (referenced = FindModuleID(Via(curref)->ID2, curfile)) {
  748.             Via(referenced)->isACTIVE = 1;
  749.             Via(curref)->OtherModule = referenced;
  750.             if (Via(referenced)->isENTRY) {
  751.                 Via(Via(referenced)->isENTRY)->isACTIVE = 1;
  752.             }
  753.             } else if (referenced =
  754.                    FindModuleExternal(Via(curref)->ID2, curfile, &modname, &otherfile, files)) {
  755.             Via(referenced)->isACTIVE = 1;
  756.             if (Via(referenced)->isENTRY) {
  757.                 Via(Via(referenced)->isENTRY)->isACTIVE = 1;
  758.             }
  759.             Via(referenced)->externref = 1;
  760.             Via(curref)->OtherModule = referenced;
  761.             } else {
  762.             DictionaryVia_t                 dict;
  763.             dict = FindIDName(Via(curref)->ID2, curfile);
  764.             if (dict) {
  765.             #ifdef OLDMEM
  766.                 HLock((Handle) dict);
  767.                 #endif
  768.                 sprintf(err, "# Unresolved : %s, referenced in %s",
  769.                     Via(dict)->name,
  770.                     Via(curfile)->name);
  771.                 LinkerError(err);
  772.                 #ifdef OLDMEM
  773.                 HUnlock((Handle) dict);
  774.                 #endif
  775.             }
  776.             unresolved++;
  777.             Via(curref)->OtherModule = NULL;
  778.             }
  779.         }
  780.         curref = Via(curref)->next;
  781.         }
  782.         curmod = Via(curmod)->next;
  783.     }
  784.     curfile = Via(curfile)->next;
  785.     }
  786.     return unresolved;
  787. }
  788.  
  789. #define STARTINGDATAOFFSET (-128)
  790. #define A5TOJT 32
  791. #define MAINOFFSET (A5TOJT)
  792. #define JTENTRYSIZE 8
  793. #define STARTINGJTOFFSET (MAINOFFSET+JTENTRYSIZE)
  794. /*
  795.  * The 32 is the distance from A5 to the jumptable.  The 8 is the length of
  796.  * one jump table entry, since the first one is reserved for MAIN.
  797.  */
  798.  
  799. long                            JTEntries = 1;
  800. long                            DataBlockSize = 0;
  801. long                            NextCodeOffset = STARTINGJTOFFSET;
  802. long                            NextDataOffset = STARTINGDATAOFFSET;
  803.  
  804. SegmentVia_t                    SegmentList = NULL;
  805.  
  806. SegmentVia_t
  807. FindSegmentID(unsigned short ID)
  808. /*
  809.  * Given an ID for a segment, search the global segment list for a segment
  810.  * with that ID.
  811.  */
  812. {
  813.     SegmentVia_t                    cur;
  814.     cur = SegmentList;
  815.     while (cur) {
  816.     if (Via(cur)->ID == ID)
  817.         return cur;
  818.     cur = Via(cur)->next;
  819.     }
  820.     return NULL;
  821. }
  822.  
  823. SegmentVia_t
  824. FindSegmentName(char *name)
  825. {
  826.     SegmentVia_t                    cur;
  827.     cur = SegmentList;
  828.     while (cur) {
  829.     #ifdef OLDMEM
  830.     HLock((Handle) Via(cur)->name);
  831.     #endif
  832.     if (!strcmp(name, Via(Via(cur)->name))) {
  833.         #ifdef OLDMEM
  834.         HUnlock((Handle) Via(cur)->name);
  835.         #endif
  836.         return cur;
  837.     }
  838.     #ifdef OLDMEM
  839.     HUnlock((Handle) Via(cur)->name);
  840.     #endif
  841.     cur = Via(cur)->next;
  842.     }
  843.     return NULL;
  844. }
  845.  
  846. unsigned short                  NextSegID;
  847.  
  848. SegmentVia_t
  849. AddSegment(char *name, LinkerFileVia_t file)
  850. /*
  851.  * Given an ID for a segment, add a new segment to the global segment list
  852.  * with that ID.
  853.  */
  854. {
  855.     SegmentVia_t                    raw;
  856.     char                            nm[64];
  857.     raw = Ealloc(sizeof(Segment_t));
  858.     Via(raw)->ID = NextSegID++;
  859.     Via(raw)->name = Ealloc(strlen(name) + 1);
  860.     #ifdef OLDMEM
  861.     HLock((Handle) Via(raw)->name);
  862.     #endif
  863.     strcpy(Via(Via(raw)->name), name);
  864.     #ifdef OLDMEM
  865.     HUnlock((Handle) Via(raw)->name);
  866.     #endif
  867.  
  868.     Via(raw)->ModuleList = NULL;
  869.     Via(raw)->firstJT = 0;
  870.     Via(raw)->countJT = 0;
  871.     Via(raw)->CurrentSize = 0;
  872.     Via(raw)->next = SegmentList;
  873.     SegmentList = raw;
  874.     return raw;
  875. }
  876.  
  877. DATAZone_t                      theDATA;
  878. Segment_t                       theJT;
  879.  
  880. void
  881. AddToDATA(ModuleVia_t themod)
  882. /* Given a module, add it to the DATA block */
  883. {
  884.     ModulePackageVia_t              modp;
  885.  
  886.     if (Via(themod)->isACTIVE) {
  887.     modp = Ealloc(sizeof(ModulePackage_t));
  888.     Via(modp)->next = theDATA.ModuleList;
  889.     Via(modp)->themod = themod;
  890.     theDATA.ModuleList = modp;
  891.     theDATA.count++;
  892.     theDATA.CurrentSize += Via(themod)->modulesize;
  893.     if ((Via(themod)->modulesize) % 2)
  894.         theDATA.CurrentSize++;
  895.     }
  896. }
  897.  
  898.  char                  *
  899. AddImage(ModulePackageVia_t modp,  char *buf)
  900. {
  901.     int                             ndx;
  902.     if (modp) {
  903.     if (Via(modp)->next) {
  904.         buf = AddImage(Via(modp)->next, buf);
  905.     }
  906.     if (Via(Via(modp)->themod)->isACTIVE) {
  907.         if (((unsigned long) buf) % 2)
  908.         buf++;
  909.         ndx = 0;
  910.         while (ndx < Via(Via(modp)->themod)->modulesize) {
  911.         *buf++ = Via(Via(Via(modp)->themod)->Bytes)[ndx++];
  912.         }
  913.     }
  914.     }
  915.     return buf;
  916. }
  917.  
  918.  char                  *
  919. AddDataImage(ModulePackageVia_t modp,  char *buf)
  920. {
  921.     int                             ndx;
  922.     if (modp) {
  923.     if (Via(modp)->next) {
  924.         buf = AddDataImage(Via(modp)->next, buf);
  925.     }
  926.     if (Via(Via(modp)->themod)->isACTIVE) {
  927.         ndx = 0;
  928.         while (ndx < Via(Via(modp)->themod)->modulesize) {
  929.         *buf++ = Via(Via(Via(modp)->themod)->Bytes)[ndx++];
  930.         }
  931.     }
  932.     }
  933.     return buf;
  934. }
  935.  
  936. Block_t
  937. ImageDATA(void)
  938. {
  939.     EString_t                        result;
  940.     Block_t                         theb;
  941.     ModulePackageVia_t              cur;
  942.     ReferenceVia_t                  curref;
  943.     int                             ndx3;
  944.     ModuleVia_t                     curmod;
  945.     char                            msg[256];
  946.     unsigned long                   lastoff, nextbyte;
  947.     unsigned long                   thisoff;
  948.     unsigned long                   delta;
  949.     unsigned long                   relocs;
  950.     unsigned long                   ndx;
  951.  
  952.     result = (EString_t) Ealloc(theDATA.CurrentSize + theDATA.count * 10 + 4096);
  953.  
  954.     theb.mem = ( EString_t) result;
  955.  
  956.     lastoff = 0;
  957.     nextbyte = 32;
  958.     cur = theDATA.ModuleList;
  959.     while (cur) {
  960.     curmod = Via(cur)->themod;
  961.     if (Via(curmod)->isACTIVE) {
  962.         if (Via(curmod)->Bytes) {
  963.         thisoff = Via(curmod)->A5offset - Via(Via(theDATA.ModuleList)->themod)->A5offset;
  964.         delta = thisoff - lastoff;
  965.         lastoff = thisoff + Via(curmod)->modulesize;
  966.         Via(result)[nextbyte++] = 0;
  967.         Via(result)[nextbyte++] = 224;
  968.         Via(result)[nextbyte++] = Via(curmod)->modulesize >> 24;
  969.         Via(result)[nextbyte++] = Via(curmod)->modulesize >> 16;
  970.         Via(result)[nextbyte++] = Via(curmod)->modulesize >> 8;
  971.         Via(result)[nextbyte++] = Via(curmod)->modulesize;
  972.         Via(result)[nextbyte++] = 224;
  973.         Via(result)[nextbyte++] = delta >> 24;
  974.         Via(result)[nextbyte++] = delta >> 16;
  975.         Via(result)[nextbyte++] = delta >> 8;
  976.         Via(result)[nextbyte++] = delta;
  977.         ndx = 0;
  978.         while (ndx < Via(curmod)->modulesize) {
  979.             Via(result)[nextbyte++] = Via(Via(curmod)->Bytes)[ndx++];
  980.         }
  981.         }
  982.     }
  983.     cur = Via(cur)->next;
  984.     }
  985.     Via(result)[nextbyte++] = 0x20;
  986.     Via(result)[nextbyte++] = 0x00;
  987.  
  988.     relocs = nextbyte;
  989.  
  990.     lastoff = 0;
  991.     cur = theDATA.ModuleList;
  992.     while (cur) {
  993.     curmod = Via(cur)->themod;
  994.     if (Via(curmod)->isACTIVE) {
  995.         if (Via(curmod)->ReferenceList) {
  996.         curref = Via(curmod)->ReferenceList;
  997.         while (curref) {
  998.             if (!Via(curref)->isA5REL) {
  999.             ndx3 = 0;
  1000.             while (ndx3 < Via(curref)->RefCount) {
  1001.                 thisoff = Via(curmod)->A5offset - Via(Via(theDATA.ModuleList)->themod)->A5offset +
  1002.                 Via(Via(curref)->Offsets)[ndx3];
  1003.                 delta = thisoff - lastoff;
  1004.                 lastoff = thisoff;
  1005.                 delta = (delta >> 1) | 0x80000000;
  1006.                 Via(result)[nextbyte++] = 0;
  1007.                 Via(result)[nextbyte++] = (delta >> 24);
  1008.                 Via(result)[nextbyte++] = (delta >> 16);
  1009.                 Via(result)[nextbyte++] = (delta >> 8);
  1010.                 Via(result)[nextbyte++] = (delta);
  1011.                 ndx3++;
  1012.             }
  1013.             }
  1014.             curref = Via(curref)->next;
  1015.         }
  1016.         }
  1017.     }
  1018.     cur = Via(cur)->next;
  1019.     }
  1020.     Via(result)[nextbyte++] = 0x00;
  1021.     Via(result)[nextbyte++] = 0x00;
  1022.     theb.size = nextbyte;
  1023.  
  1024.     Via(result)[0] = (-NextDataOffset) >> 24;
  1025.     Via(result)[1] = (-NextDataOffset) >> 16;
  1026.     Via(result)[2] = (-NextDataOffset) >> 8;
  1027.     Via(result)[3] = (-NextDataOffset);
  1028.  
  1029.     Via(result)[4] = 0;
  1030.     Via(result)[5] = 1;
  1031.  
  1032.     Via(result)[6] = 0;
  1033.     Via(result)[7] = 0;
  1034.  
  1035.     Via(result)[8] = 0;
  1036.     Via(result)[9] = 0;
  1037.     Via(result)[10] = 0;
  1038.     Via(result)[11] = 32;
  1039.  
  1040.     Via(result)[12] = relocs >> 24;
  1041.     Via(result)[13] = relocs >> 16;
  1042.     Via(result)[14] = relocs >> 8;
  1043.     Via(result)[15] = relocs;
  1044.  
  1045.     Via(result)[16] = 0;
  1046.     Via(result)[17] = 0;
  1047.     Via(result)[18] = 0;
  1048.     Via(result)[19] = 0;
  1049.  
  1050.     return theb;
  1051. }
  1052.  
  1053. void
  1054. SetFirstJT(SegmentVia_t seg)
  1055. {
  1056.     long                            offset = 9999999;
  1057.     ModulePackageVia_t              modp;
  1058.     modp = Via(seg)->ModuleList;
  1059.     while (modp) {
  1060.     if (Via(Via(modp)->themod)->A5offset < offset) {
  1061.         offset = Via(Via(modp)->themod)->A5offset;
  1062.     }
  1063.     modp = Via(modp)->next;
  1064.     }
  1065.     Via(seg)->firstJT = offset - 2 - MAINOFFSET;
  1066. }
  1067.  
  1068. Block_t
  1069. ImageCODE(SegmentVia_t seg)
  1070. {
  1071.     EString_t                        result;
  1072.     Block_t                         theb;
  1073.     unsigned long                   sz;
  1074.     SetFirstJT(seg);
  1075.     sz = Via(seg)->CurrentSize + 4;
  1076.     if (sz % 2)
  1077.     sz++;
  1078.     result = ( EString_t) Ealloc(sz);
  1079.     theb.mem = result;
  1080.     theb.size = Via(seg)->CurrentSize + 4;
  1081.     #ifdef OLDMEM
  1082.     HLock((Handle) result);
  1083.     #endif
  1084.     AddImage(Via(seg)->ModuleList, Via(result) + 4);
  1085.     Via(result)[0] = Via(seg)->firstJT >> 8;
  1086.     Via(result)[1] = Via(seg)->firstJT;
  1087.     Via(result)[2] = Via(seg)->countJT >> 8;
  1088.     Via(result)[3] = Via(seg)->countJT;
  1089.     #ifdef OLDMEM
  1090.     HUnlock((Handle) result);
  1091.     #endif
  1092.     return theb;
  1093. }
  1094.  
  1095. SegmentVia_t
  1096. GetSeg(int SegID, LinkerFileVia_t file)
  1097. {
  1098.     DictionaryVia_t                 segname;
  1099.     char                            nm[64];
  1100.     segname = FindIDName(SegID, file);
  1101.     if (segname) {
  1102.     strcpy(nm, Via(segname)->name);
  1103.     } else {
  1104.     strcpy(nm, "%?Anon");
  1105.     }
  1106.     return FindSegmentName(nm);
  1107. }
  1108.  
  1109. void
  1110. AddToSegment(unsigned short SegID, ModuleVia_t themod, LinkerFileVia_t file)
  1111. {
  1112.     SegmentVia_t                    theseg;
  1113.     ModulePackageVia_t              modp;
  1114.     DictionaryVia_t                 segname;
  1115.     DictionaryVia_t                 modname;
  1116.     char                            nm[64];
  1117.     char                            msg[256];
  1118.  
  1119.     if (!Via(themod)->isACTIVE)
  1120.     return;
  1121.     segname = FindIDName(SegID, file);
  1122.     if (segname) {
  1123.     strcpy(nm, Via(segname)->name);
  1124.     } else {
  1125.     strcpy(nm, "%?Anon");
  1126.     }
  1127.     theseg = FindSegmentName(nm);
  1128.     if (!theseg) {
  1129.     theseg = AddSegment(nm, file);
  1130.     }
  1131.     if (Via(theseg)->CurrentSize % 2)
  1132.     Via(theseg)->CurrentSize++;
  1133.     modp = Ealloc(sizeof(ModulePackage_t));
  1134.     Via(modp)->next = Via(theseg)->ModuleList;
  1135.     Via(modp)->themod = themod;
  1136.     Via(theseg)->ModuleList = modp;
  1137.     Via(themod)->segmentoffset = Via(theseg)->CurrentSize;
  1138.     Via(theseg)->CurrentSize += Via(themod)->modulesize;
  1139. }
  1140.  
  1141. ModuleVia_t                     MAINmodule = NULL;
  1142.  
  1143. char                            recerr[128];
  1144.  
  1145. void
  1146. AssignModules(ModuleVia_t curmod, LinkerFileVia_t curfile)
  1147. {
  1148.     ModuleVia_t                     curmod2;
  1149.     DictionaryVia_t                 dict;
  1150.     if (!curmod) return;
  1151.     if (Via(curmod)->next) {
  1152.     AssignModules(Via(curmod)->next, curfile);
  1153.     }
  1154.     if (Via(curmod)->isACTIVE) {
  1155.     if (Via(curmod)->isCODE) {
  1156.         /* Add this routine to its segment. */
  1157.         AddToSegment(Via(curmod)->segment, curmod, curfile);
  1158.     } else {        /* isDATA */
  1159.         if ((Via(curmod)->modulesize) % 2)
  1160.         Via(curmod)->modulesize++;
  1161.         NextDataOffset -= Via(curmod)->modulesize;
  1162.         if (!Via(curmod)->modulesize) {
  1163.         dict = FindIDName(Via(curmod)->ID, curfile);
  1164.         if (dict) {
  1165.         #ifdef OLDMEM
  1166.             HLock((Handle) dict);
  1167.             #endif
  1168.             sprintf(recerr, "# Zero sized data module : %s in %s",
  1169.                 Via(dict)->name,
  1170.                 Via(curfile)->name);
  1171.             LinkerError(recerr);
  1172.             #ifdef OLDMEM
  1173.             HUnlock((Handle) dict);
  1174.             #endif
  1175.         }
  1176.         }
  1177.         Via(curmod)->A5offset = NextDataOffset;
  1178.         AddToDATA(curmod);
  1179.     }
  1180.     if (Via(curmod)->Entries) {
  1181.         curmod2 = Via(curmod)->Entries;
  1182.         while (curmod2) {
  1183.         Via(curmod2)->segmentoffset = Via(curmod)->segmentoffset + Via(curmod2)->offset;
  1184.         if (!Via(curmod2)->isCODE) {
  1185. #ifdef Undefined
  1186.             NextDataOffset -= Via(curmod2)->modulesize;
  1187.             Via(curmod2)->A5offset = NextDataOffset;
  1188. #else
  1189.             Via(curmod2)->A5offset = Via(curmod)->A5offset + Via(curmod2)->offset;
  1190. #endif
  1191.         }
  1192.         curmod2 = Via(curmod2)->next;
  1193.         }
  1194.     }
  1195.     }
  1196. }
  1197.  
  1198. void
  1199. AssignA5Offsets(SegmentVia_t curseg)
  1200. {
  1201.     ModulePackageVia_t              modp;
  1202.     ModuleVia_t                     curmod;
  1203.     ModuleVia_t                     curmod2;
  1204.     modp = Via(curseg)->ModuleList;
  1205.     while (modp) {
  1206.     curmod = Via(modp)->themod;
  1207.     if (Via(curmod)->isACTIVE) {
  1208.         if (Via(curmod)->isMAIN) {
  1209.         Via(curmod)->A5offset = MAINOFFSET + 2;
  1210.         } else {
  1211.         Via(curmod)->A5offset = NextCodeOffset + 2;
  1212.         Via(curseg)->countJT++;
  1213.         JTEntries++;
  1214.         NextCodeOffset += JTENTRYSIZE;
  1215.         }
  1216.         if (Via(curmod)->Entries) {
  1217.         curmod2 = Via(curmod)->Entries;
  1218.         while (curmod2) {
  1219.             if (Via(curmod2)->isMAIN) {
  1220.             Via(curmod2)->A5offset = MAINOFFSET + 2;
  1221.             } else {
  1222.             Via(curmod2)->A5offset = NextCodeOffset + 2;
  1223.             Via(curseg)->countJT++;
  1224.             JTEntries++;
  1225.             NextCodeOffset += JTENTRYSIZE;
  1226.             }
  1227.             curmod2 = Via(curmod2)->next;
  1228.         }
  1229.         }
  1230.     }
  1231.     modp = Via(modp)->next;
  1232.     }
  1233. }
  1234.  
  1235. void
  1236. AssignMPWOffsets(LinkerFileVia_t files)
  1237. {
  1238.     LinkerFileVia_t                 curfile = files;
  1239.     ModuleVia_t                     curmod;
  1240.     ModuleVia_t                     curmod2;
  1241.     SegmentVia_t                    theseg;
  1242.     SegmentVia_t                    curseg;
  1243.     ModulePackageVia_t              modp;
  1244.     DictionaryVia_t                 segname;
  1245.     DictionaryVia_t                 modname;
  1246.     char                            nm[64];
  1247.     char                            msg[256];
  1248.  
  1249.     if (!MAINmodule) {
  1250.     MAINmodule = FindNameAll("%__MAIN", files);
  1251.     if (MAINmodule) {
  1252.         Via(MAINmodule)->A5offset = MAINOFFSET + 2;
  1253.         Via(MAINmodule)->isACTIVE = 1;
  1254.         Via(MAINmodule)->isMAIN = 1;
  1255.         if (Via(MAINmodule)->isENTRY) {
  1256.         Via(Via(MAINmodule)->isENTRY)->isACTIVE = 1;
  1257.         }
  1258.     }
  1259.     MAINmodule = NULL;
  1260.     }
  1261.     while (curfile) {
  1262.         curmod = Via(curfile)->ModuleList;
  1263.         AssignModules(curmod, curfile);
  1264.         curfile = Via(curfile)->next;
  1265.     }
  1266.     if (!MAINmodule) {
  1267.     MAINmodule = FindNameAll("%__MAIN", files);
  1268.     if (MAINmodule) {
  1269.         Via(MAINmodule)->A5offset = MAINOFFSET + 2;
  1270.         Via(MAINmodule)->isACTIVE = 1;
  1271.         Via(MAINmodule)->isMAIN = 1;
  1272.         if (Via(MAINmodule)->isENTRY) {
  1273.             Via(Via(MAINmodule)->isENTRY)->isACTIVE = 1;
  1274.         }
  1275.     }
  1276.     }
  1277.     if (!MAINmodule) {
  1278.         LinkerError("No main module");
  1279.     }
  1280.     /*
  1281.      * We need to find the main module, find out what segment it is in, and
  1282.      * make that segment # 1, and assign all its MPW offsets first
  1283.      */
  1284.  
  1285.     segname = NULL;
  1286.     if (MAINmodule)
  1287.            segname = FindIDName(Via(MAINmodule)->segment, Via(MAINmodule)->file);
  1288.     if (segname) {
  1289.         strcpy(nm, Via(segname)->name);
  1290.     } else {
  1291.         strcpy(nm, "%?Anon");
  1292.     }
  1293.     theseg = FindSegmentName(nm);
  1294.     if (theseg) {
  1295.         Via(theseg)->ID = 1;
  1296.         AssignA5Offsets(theseg);
  1297.         Via(theseg)->countJT++;
  1298.         curseg = SegmentList;
  1299.         while (curseg) {
  1300.             if (curseg != theseg) {
  1301.                 AssignA5Offsets(curseg);
  1302.             }
  1303.             curseg = Via(curseg)->next;
  1304.         }
  1305.     }
  1306. }
  1307.  
  1308. Block_t
  1309. ConcatImage(Block_t a, Block_t b, LinkerFileVia_t files)
  1310. {
  1311.     Block_t                         theb;
  1312.     EString_t                        result;
  1313.     long                            ndx1, ndx2;
  1314.     ModuleVia_t                     a5init3;
  1315.     unsigned long                   datainit;
  1316.     int                             asz;
  1317.  
  1318.     a5init3 = FindNameAll("_A5Init3", files);
  1319.     datainit = Via(a5init3)->segmentoffset + 4;
  1320.     asz = a.size + b.size;
  1321.     while (asz % 4)
  1322.     asz++;
  1323.  
  1324.     result = Ealloc(asz + 8);
  1325.     theb.mem = result;
  1326.     theb.size = asz + 8;
  1327.     ndx1 = 0;
  1328.     ndx2 = 0;
  1329.     while (ndx2 < a.size) {
  1330.     Via(result)[ndx1++] = Via(a.mem)[ndx2++];
  1331.     }
  1332.     ndx1 = datainit;
  1333.     ndx2 = 0;
  1334.     while (ndx2 < b.size) {
  1335.     Via(result)[ndx1++] = Via(b.mem)[ndx2++];
  1336.     }
  1337.     ndx1 = asz;
  1338.     Via(result)[ndx1++] = datainit >> 24;
  1339.     Via(result)[ndx1++] = datainit >> 16;
  1340.     Via(result)[ndx1++] = datainit >> 8;
  1341.     Via(result)[ndx1++] = datainit;
  1342.  
  1343.     Via(result)[ndx1++] = 'm';
  1344.     Via(result)[ndx1++] = 'p';
  1345.     Via(result)[ndx1++] = 'w';
  1346.     Via(result)[ndx1++] = 'd';
  1347.     return theb;
  1348. }
  1349.  
  1350. Block_t
  1351. ImageJT(void)
  1352. {
  1353.     SegmentVia_t                    curseg;
  1354.     Block_t                         theb;
  1355.     DictionaryVia_t                 segname;
  1356.     ModulePackageVia_t              curmod;
  1357.     ModuleVia_t                     curmod2;
  1358.     EString_t                        result;
  1359.     long                            offset;
  1360.     char                            nm[64];
  1361.  
  1362.     if (!MAINmodule) {
  1363.     theb.mem = NULL;
  1364.     theb.size = 0;
  1365.     return theb;
  1366.     }
  1367.     result = Ealloc(16 + (JTEntries) * 8);
  1368.     theb.mem = result;
  1369.     theb.size = 16 + (JTEntries * 8);
  1370.     curseg = SegmentList;
  1371.     while (curseg) {
  1372.     curmod = Via(curseg)->ModuleList;
  1373.     while (curmod) {
  1374.         if (Via(Via(curmod)->themod)->isACTIVE) {
  1375.         offset = Via(Via(curmod)->themod)->A5offset - 16;
  1376.         offset -= 2;
  1377.         Via(result)[offset] = Via(Via(curmod)->themod)->segmentoffset >> 8;
  1378.         Via(result)[offset + 1] = Via(Via(curmod)->themod)->segmentoffset;
  1379.         Via(result)[offset + 2] = 0x3f;
  1380.         Via(result)[offset + 3] = 0x3c;
  1381.         Via(result)[offset + 4] = Via(curseg)->ID >> 8;
  1382.         Via(result)[offset + 5] = Via(curseg)->ID;
  1383.         Via(result)[offset + 6] = 0xa9;
  1384.         Via(result)[offset + 7] = 0xf0;
  1385.         if (Via(Via(curmod)->themod)->Entries) {
  1386.             curmod2 = Via(Via(curmod)->themod)->Entries;
  1387.             while (curmod2) {
  1388.             offset = Via(curmod2)->A5offset - 16;
  1389.             offset -= 2;
  1390.             Via(result)[offset] = Via(curmod2)->segmentoffset >> 8;
  1391.             Via(result)[offset + 1] = Via(curmod2)->segmentoffset;
  1392.             Via(result)[offset + 2] = 0x3f;
  1393.             Via(result)[offset + 3] = 0x3c;
  1394.             Via(result)[offset + 4] = Via(curseg)->ID >> 8;
  1395.             Via(result)[offset + 5] = Via(curseg)->ID;
  1396.             Via(result)[offset + 6] = 0xa9;
  1397.             Via(result)[offset + 7] = 0xf0;
  1398.             curmod2 = Via(curmod2)->next;
  1399.             }
  1400.         }
  1401.         }
  1402.         curmod = Via(curmod)->next;
  1403.     }
  1404.     curseg = Via(curseg)->next;
  1405.     }
  1406.     /* Now we store the header values */
  1407.     Via(result)[0] = (theb.size + 16) >> 24;
  1408.     Via(result)[1] = (theb.size + 16) >> 16;
  1409.     Via(result)[2] = (theb.size + 16) >> 8;
  1410.     Via(result)[3] = (theb.size + 16);
  1411.     Via(result)[4] = (-NextDataOffset) >> 24;
  1412.     Via(result)[5] = (-NextDataOffset) >> 16;
  1413.     Via(result)[6] = (-NextDataOffset) >> 8;
  1414.     Via(result)[7] = (-NextDataOffset);
  1415.     Via(result)[8] = (theb.size - 16) >> 24;
  1416.     Via(result)[9] = (theb.size - 16) >> 16;
  1417.     Via(result)[10] = (theb.size - 16) >> 8;
  1418.     Via(result)[11] = (theb.size - 16);
  1419.     Via(result)[12] = A5TOJT >> 24;
  1420.     Via(result)[13] = A5TOJT >> 16;
  1421.     Via(result)[14] = A5TOJT >> 8;
  1422.     Via(result)[15] = A5TOJT;
  1423.     return theb;
  1424. }
  1425.  
  1426. void
  1427. AdjustOneRef(ModuleVia_t curmod)
  1428. {
  1429.     ReferenceVia_t                  curref;
  1430.     ModuleVia_t                     curmod2;
  1431.     long                            theoffset;
  1432.     int                             ndx;
  1433.     if (!Via(curmod)->Bytes) {
  1434.         return;
  1435.     }
  1436.     if (!Via(curmod)->sizeBytes) {
  1437.         return;
  1438.     }
  1439. #ifdef OLDMEM
  1440.     HLock((Handle) Via(curmod)->Bytes);
  1441. #endif
  1442.  
  1443. #ifdef HDEBUG
  1444.     fprintf(dumpFile,"Adjusting references for module %d\n",curmod->ID);
  1445.     if (curmod->ID == 529) Debugger();
  1446. #endif
  1447.     if (Via(curmod)->isACTIVE) {
  1448.     curref = Via(curmod)->ReferenceList;
  1449.     while (curref) {
  1450.         switch (Via(curref)->patchkind) {
  1451.         case 1:
  1452.         if (Via(curref)->isCOMPUTED) {
  1453. #ifdef HDEBUG
  1454.             fprintf(dumpFile,"Next ref computed\n");
  1455. #endif
  1456.             theoffset = Via(Via(curref)->WhichModule)->segmentoffset -
  1457.             Via(Via(curref)->OtherModule)->segmentoffset;
  1458.             ndx = 0;
  1459.             while (ndx < Via(curref)->RefCount) {
  1460.             char                           *thepoint;
  1461.             thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1462. #ifdef HDEBUG
  1463.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1464.                 char                            tmp[128];
  1465.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1466.                   Via(Via(curref)->Offsets)[ndx],
  1467.                   Via(curmod)->modulesize);
  1468.                 c2pstr(tmp);
  1469.                 DebugStr(tmp);
  1470.             }
  1471. #endif
  1472. #ifdef HDEBUG
  1473.                 fprintf(dumpFile,"Patchkind 1 at %x size %d value %x\n",
  1474.                     Via(Via(curref)->Offsets)[ndx],
  1475.                     Via(curref)->patchsize,
  1476.                     theoffset);
  1477. #endif
  1478.             switch (Via(curref)->patchsize) {
  1479.             case 32:
  1480.                 *((long *) thepoint) += theoffset;
  1481.                 break;
  1482.             case 16:
  1483.                 *((short *) thepoint) += theoffset;
  1484.                 break;
  1485.             case 8:
  1486.                 *((char *) thepoint) += theoffset;
  1487.                 break;
  1488.             default:
  1489.                 break;
  1490.             }
  1491.             ndx++;
  1492.             }
  1493.         } else {
  1494.             if (Via(curref)->isA5REL) {
  1495.             theoffset = Via(Via(curref)->WhichModule)->A5offset;
  1496.             ndx = 0;
  1497.             while (ndx < Via(curref)->RefCount) {
  1498.                 char                           *thepoint;
  1499.                 thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1500. #ifdef HDEBUG
  1501.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1502.                 char                            tmp[128];
  1503.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1504.                   Via(Via(curref)->Offsets)[ndx],
  1505.                   Via(curmod)->modulesize);
  1506.                 c2pstr(tmp);
  1507.                 DebugStr(tmp);
  1508.             }
  1509. #endif
  1510. #ifdef HDEBUG
  1511.                 fprintf(dumpFile,"Patchkind 1 at %x size %d value %x\n",
  1512.                     Via(Via(curref)->Offsets)[ndx],
  1513.                     Via(curref)->patchsize,
  1514.                     theoffset);
  1515. #endif
  1516.                 switch (Via(curref)->patchsize) {
  1517.                 case 32:
  1518.                 *((long *) thepoint) += theoffset;
  1519.                 break;
  1520.                 case 16:
  1521.                 *((short *) thepoint) += theoffset;
  1522.                 break;
  1523.                 case 8:
  1524.                 *((char *) thepoint) += theoffset;
  1525.                 break;
  1526.                 default:
  1527.                 break;
  1528.                 }
  1529.                 ndx++;
  1530.             }
  1531.             } else {
  1532.             /* This case requires instruction editing */
  1533.             SegmentVia_t                    thisseg;
  1534.             SegmentVia_t                    thatseg;
  1535.             thisseg = GetSeg(Via(curmod)->segment, Via(curmod)->file);
  1536.             thatseg = GetSeg(Via(Via(curref)->WhichModule)->segment, Via(Via(curref)->WhichModule)->file);
  1537.             if (thisseg != thatseg) {
  1538.                 theoffset = Via(Via(curref)->WhichModule)->A5offset;
  1539.                 ndx = 0;
  1540.                 while (ndx < Via(curref)->RefCount) {
  1541.                 char                           *thepoint;
  1542.                  char                   j;
  1543.                 thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1544. #ifdef HDEBUG
  1545.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1546.                 char                            tmp[128];
  1547.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1548.                   Via(Via(curref)->Offsets)[ndx],
  1549.                   Via(curmod)->modulesize);
  1550.                 c2pstr(tmp);
  1551.                 DebugStr(tmp);
  1552.             }
  1553. #endif
  1554.                 j = *(thepoint - 1);    // preceding byte
  1555.                 j = j & (128 + 64);    // strip out low 6 bits
  1556.                 j = j | 0x2d;        // set to A5
  1557.                 *(thepoint - 1) = j;
  1558. #ifdef HDEBUG
  1559.                 fprintf(dumpFile,"Patchkind 1 (nonA5) at %x size %d value %x\n",
  1560.                     Via(Via(curref)->Offsets)[ndx],
  1561.                     Via(curref)->patchsize,
  1562.                     theoffset);
  1563. #endif
  1564.                 switch (Via(curref)->patchsize) {
  1565.                 case 32:
  1566.                     *((long *) thepoint) += theoffset;
  1567.                     break;
  1568.                 case 16:
  1569.                     *((short *) thepoint) += theoffset;
  1570.                     break;
  1571.                 case 8:
  1572.                     *((char *) thepoint) += theoffset;
  1573.                     break;
  1574.                 default:
  1575.                     break;
  1576.                 }
  1577.                 ndx++;
  1578.                 }
  1579.             } else {
  1580.                 ndx = 0;
  1581.                 while (ndx < Via(curref)->RefCount) {
  1582.                 char                           *thepoint;
  1583.                  char                   j;
  1584.                 thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1585.                 theoffset = Via(Via(curref)->WhichModule)->segmentoffset -
  1586.                     (Via(curmod)->segmentoffset + Via(Via(curref)->Offsets)[ndx]);
  1587. #ifdef HDEBUG
  1588.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1589.                 char                            tmp[128];
  1590.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1591.                   Via(Via(curref)->Offsets)[ndx],
  1592.                   Via(curmod)->modulesize);
  1593.                 c2pstr(tmp);
  1594.                 DebugStr(tmp);
  1595.             }
  1596. #endif
  1597.                 j = *(thepoint - 1);    // previous byte
  1598.                 j = j & (128 + 64);    // strip out low 6 bits
  1599.                 j = j | 0x3a;        // set to PC rel
  1600.                 *(thepoint - 1) = j;
  1601. #ifdef HDEBUG
  1602.                     fprintf(dumpFile,"Patchkind 1 (nonA5) at %x size %d value %x\n",
  1603.                         Via(Via(curref)->Offsets)[ndx],
  1604.                         Via(curref)->patchsize,
  1605.                         theoffset);
  1606. #endif
  1607.                 switch (Via(curref)->patchsize) {
  1608.                 case 32:
  1609.                     *((long *) thepoint) += theoffset;
  1610.                     break;
  1611.                 case 16:
  1612.                     *((short *) thepoint) += theoffset;
  1613.                     break;
  1614.                 case 8:
  1615.                     *((char *) thepoint) += theoffset;
  1616.                     break;
  1617.                 default:
  1618.                     break;
  1619.                 }
  1620.                 ndx++;
  1621.                 }
  1622.             }
  1623.             }
  1624.         }
  1625.         break;
  1626.         case 2:
  1627.         if (Via(curref)->isCOMPUTED) {
  1628. #ifdef HDEBUG
  1629.             fprintf(dumpFile,"Next ref computed\n");
  1630. #endif
  1631.             theoffset = Via(Via(curref)->WhichModule)->A5offset - Via(Via(curref)->OtherModule)->A5offset;
  1632.             ndx = 0;
  1633.             while (ndx < Via(curref)->RefCount) {
  1634.             char                           *thepoint;
  1635.             thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1636. #ifdef HDEBUG
  1637.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1638.                 char                            tmp[128];
  1639.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1640.                   Via(Via(curref)->Offsets)[ndx],
  1641.                   Via(curmod)->modulesize);
  1642.                 c2pstr(tmp);
  1643.                 DebugStr(tmp);
  1644.             }
  1645. #endif
  1646. #ifdef HDEBUG
  1647.                 fprintf(dumpFile,"Patchkind 2 at %x size %d value %x\n",
  1648.                     Via(Via(curref)->Offsets)[ndx],
  1649.                     Via(curref)->patchsize,
  1650.                     theoffset);
  1651. #endif
  1652.             switch (Via(curref)->patchsize) {
  1653.             case 32:
  1654.                 *((long *) thepoint) += theoffset;
  1655.                 break;
  1656.             case 16:
  1657.                 *((short *) thepoint) += theoffset;
  1658.                 break;
  1659.             case 8:
  1660.                 *((char *) thepoint) += theoffset;
  1661.                 break;
  1662.             default:
  1663.                 break;
  1664.             }
  1665.             ndx++;
  1666.             }
  1667.         } else {
  1668.             if (!Via(curref)->isA5REL)
  1669.             LinkerError("# Code to data refs must be a5 rel");
  1670.             theoffset = Via(Via(curref)->WhichModule)->A5offset;
  1671.             ndx = 0;
  1672.             while (ndx < Via(curref)->RefCount) {
  1673.             char                           *thepoint;
  1674.             thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1675. #ifdef HDEBUG
  1676.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1677.                 char                            tmp[128];
  1678.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1679.                   Via(Via(curref)->Offsets)[ndx],
  1680.                   Via(curmod)->modulesize);
  1681.                 c2pstr(tmp);
  1682.                 DebugStr(tmp);
  1683.             }
  1684. #endif
  1685. #ifdef HDEBUG
  1686.                 fprintf(dumpFile,"Patchkind 2 at %x size %d value %x\n",
  1687.                     Via(Via(curref)->Offsets)[ndx],
  1688.                     Via(curref)->patchsize,
  1689.                     theoffset);
  1690. #endif
  1691.             switch (Via(curref)->patchsize) {
  1692.             case 32:
  1693.                 *((long *) thepoint) += theoffset;
  1694.                 break;
  1695.             case 16:
  1696.                 *((short *) thepoint) += theoffset;
  1697.                 break;
  1698.             case 8:
  1699.                 *((char *) thepoint) += theoffset;
  1700.                 break;
  1701.             default:
  1702.                 break;
  1703.             }
  1704.             ndx++;
  1705.             }
  1706.         }
  1707.         break;
  1708.         case 3:
  1709.         case 4:
  1710.         theoffset = Via(Via(curref)->WhichModule)->A5offset;
  1711.         if (Via(curref)->isCOMPUTED)
  1712.             theoffset -= Via(Via(curref)->OtherModule)->A5offset;
  1713.         ndx = 0;
  1714.         while (ndx < Via(curref)->RefCount) {
  1715.             char                           *thepoint;
  1716.             thepoint = &(Via(Via(curmod)->Bytes)[Via(Via(curref)->Offsets)[ndx]]);
  1717. #ifdef HDEBUG
  1718.             if ((Via(Via(curref)->Offsets)[ndx]) > Via(curmod)->modulesize) {
  1719.                 char                            tmp[128];
  1720.                 sprintf(tmp, "AdjustOneRef: offset out of range %d (size %d)",
  1721.                   Via(Via(curref)->Offsets)[ndx],
  1722.                   Via(curmod)->modulesize);
  1723.                 c2pstr(tmp);
  1724.                 DebugStr(tmp);
  1725.             }
  1726. #endif
  1727. #ifdef HDEBUG
  1728.                 fprintf(dumpFile,"Patchkind 3/4 at %x size %d value %x\n",
  1729.                     Via(Via(curref)->Offsets)[ndx],
  1730.                     Via(curref)->patchsize,
  1731.                     theoffset);
  1732. #endif
  1733.             switch (Via(curref)->patchsize) {
  1734.             case 32:
  1735.             *((long *) thepoint) += theoffset;
  1736.             break;
  1737.             case 16:
  1738.             *((short *) thepoint) += theoffset;
  1739.             break;
  1740.             case 8:
  1741.             *((char *) thepoint) += theoffset;
  1742.             break;
  1743.             default:
  1744.             break;
  1745.             }
  1746.             ndx++;
  1747.         }
  1748.         break;
  1749.         default:
  1750.         assert(0);
  1751.         break;
  1752.         }
  1753.         curref = Via(curref)->next;
  1754.     }
  1755.     }
  1756.     #ifdef OLDMEM
  1757.     HUnlock((Handle) Via(curmod)->Bytes);
  1758.     #endif
  1759. }
  1760.  
  1761. void
  1762. AdjustAllReferences(LinkerFileVia_t files)
  1763. {
  1764.     LinkerFileVia_t                 curfile = files;
  1765.     ModuleVia_t                     curmod;
  1766.     ReferenceVia_t                  curref;
  1767.     char buf[256];
  1768.  
  1769.     while (curfile) {
  1770.     curmod = Via(curfile)->ModuleList;
  1771.     while (curmod) {
  1772. #ifdef HDEBUG
  1773.         if (curmod->ID == 529) {
  1774.             sprintf(buf,"Dump of module %d in %s",curmod->ID,curfile->name);
  1775.             hex_dump(dumpFile,buf,curmod->Bytes,curmod->modulesize);
  1776.         }
  1777. #endif
  1778.         AdjustOneRef(curmod);
  1779. #ifdef HDEBUG
  1780.         if (curmod->ID == 529) {
  1781.             sprintf(buf,"SecondDump of module %d in %s",curmod->ID,curfile->name);
  1782.             hex_dump(dumpFile,buf,curmod->Bytes,curmod->modulesize);
  1783.         }
  1784. #endif
  1785.         curmod = Via(curmod)->next;
  1786.     }
  1787.     curfile = Via(curfile)->next;
  1788.     }
  1789. }
  1790.  
  1791. #ifndef OLDMEM
  1792. void
  1793. AddIceResource(char *mem,long sz,OSType resType,short theID,char *name)
  1794. {
  1795.     Handle h;
  1796.     h = NewHandleClear(sz);
  1797.     memcpy(*h,mem,sz);
  1798.     AddResource(h,resType,theID,name);
  1799. }
  1800.  
  1801. #endif
  1802.  
  1803. int
  1804. FlushLink(char *name, short volrefnum, long dirID, LinkerFileVia_t files)
  1805. /* The argument is the name of the destination file */
  1806. {
  1807.     struct FInfo                    ftype;
  1808.     SegmentVia_t                    curseg;
  1809.     int                             thef;
  1810.     OSErr                           bad;
  1811.     char                            segname[256];
  1812.     int                             datainit = 0;
  1813.     Str255                          pname;
  1814.     if (!MAINmodule) {
  1815.         LinkerError("No main entry point !");
  1816.         return 0;
  1817.     }
  1818.     if (!LinkErrorCount) {
  1819.         theDATA.Image = ImageDATA();
  1820.         theJT.Image = ImageJT();
  1821.         theJT.ID = 0;
  1822.         theJT.name = NULL;
  1823.         theJT.CurrentSize = 0;    /* unused field for this struct */
  1824.         theJT.ModuleList = NULL;
  1825.         theJT.next = NULL;
  1826.     }
  1827.     if (!LinkErrorCount) {
  1828.     strcpy((char *) pname, name);
  1829.     c2pstr(pname);
  1830.     bad = HDelete(volrefnum, dirID, pname);
  1831.     HCreateResFile(volrefnum, dirID, pname);
  1832.     thef = HOpenResFile(volrefnum, dirID, pname, 2);
  1833.     if (thef == -1) {
  1834.         LinkerError("Couldn't open app file for writing");
  1835.         return 0;
  1836.     }
  1837.     curseg = SegmentList;
  1838.     while (curseg) {
  1839.         Via(curseg)->Image = ImageCODE(curseg);
  1840.         #ifdef OLDMEM
  1841.         HLock((Handle) Via(curseg)->name);
  1842.         #endif
  1843.         if (!strcmp(Via(Via(curseg)->name), "%A5Init")) {
  1844.         Via(curseg)->Image = ConcatImage(Via(curseg)->Image, theDATA.Image, files);
  1845.         datainit = 1;
  1846.         }
  1847.         strcpy(segname, Via(Via(curseg)->name));
  1848.         c2pstr(segname);
  1849.         #ifdef OLDMEM
  1850.         HUnlock((Handle) Via(curseg)->name);
  1851.         AddResource((Handle) Via(curseg)->Image.mem, MakeOSType("CODE"), Via(curseg)->ID, segname);
  1852.         #endif
  1853.         AddIceResource(Via(curseg)->Image.mem,Via(curseg)->Image.size,MakeOSType("CODE"), Via(curseg)->ID, segname);
  1854.         curseg = Via(curseg)->next;
  1855.     }
  1856.     #ifdef OLDMEM
  1857.     AddResource((Handle) theJT.Image.mem, MakeOSType("CODE"), 0, NULL);
  1858.     #endif
  1859.     AddIceResource(theJT.Image.mem,theJT.Image.size, MakeOSType("CODE"), 0, NULL);
  1860.     HGetFInfo(volrefnum, dirID, pname, &ftype);
  1861.     ftype.fdType = 'APPL';
  1862.     ftype.fdCreator = gProject->itsSignature;
  1863.     HSetFInfo(volrefnum, dirID, pname, &ftype);
  1864.     /* Now we add a SIZE resource */
  1865.     {
  1866.         Handle siz;
  1867.         long *lptr;
  1868.         siz = NewHandle(10);
  1869.         *((short *) *siz) = gProject->itsSizeFlags;
  1870.         *((long *) ((*((char **) siz))+2)) = gProject->itsPartition;
  1871.         *((long *) ((*((char **) siz))+6)) = gProject->itsPartition;
  1872.         AddResource(siz, 'SIZE', -1, gProject->StdAppName);
  1873.     }
  1874.     CloseResFile(thef);
  1875.     if (!datainit) {
  1876.         LinkerError("No data initialization code present !");
  1877.         return 0;
  1878.     }
  1879.     } else {
  1880.         LinkerError("No application generated");
  1881.         return 0;
  1882.     }
  1883.     return 1;
  1884. }
  1885.  
  1886. void
  1887. KillRefs(ReferenceVia_t head)
  1888. {
  1889.     if (head) {
  1890.     if (Via(head)->next)
  1891.         KillRefs(Via(head)->next);
  1892.     if (Via(head)->Offsets)
  1893.         Efree(Via(head)->Offsets);
  1894.     Efree(head);
  1895.     }
  1896. }
  1897.  
  1898. void
  1899. KillModules(ModuleVia_t head)
  1900. {
  1901.     if (head) {
  1902.     if (Via(head)->next)
  1903.         KillModules(Via(head)->next);
  1904.     KillModules(Via(head)->Entries);
  1905.     KillRefs(Via(head)->ReferenceList);
  1906.     if (Via(head)->Bytes)
  1907.         Efree(Via(head)->Bytes);
  1908.     Efree(head);
  1909.     }
  1910. }
  1911.  
  1912. void
  1913. KillDicts(DictionaryVia_t head)
  1914. {
  1915.     if (head) {
  1916.     if (Via(head)->next)
  1917.         KillDicts(Via(head)->next);
  1918.     Efree(head);
  1919.     }
  1920. }
  1921.  
  1922.  
  1923. void
  1924. KillModPacks(ModulePackageVia_t head)
  1925. {
  1926.     if (head) {
  1927.     if (Via(head)->next)
  1928.         KillModPacks(Via(head)->next);
  1929.     Efree(head);
  1930.     }
  1931. }
  1932.  
  1933. void
  1934. KillImage(Block_t im)
  1935. {
  1936.     Efree(im.mem);
  1937. }
  1938.  
  1939. void
  1940. KillSegments(SegmentVia_t head)
  1941. {
  1942.     if (head) {
  1943.     if (Via(head)->next)
  1944.         KillSegments(Via(head)->next);
  1945.     KillModPacks(Via(head)->ModuleList);
  1946.     }
  1947. }
  1948.  
  1949. void
  1950. KillLinkFiles(LinkerFileVia_t head)
  1951. {
  1952.     if (head) {
  1953.     if (Via(head)->next) {
  1954.         KillLinkFiles(Via(head)->next);
  1955.     }
  1956.     KillModules(Via(head)->ModuleList);
  1957.     KillDicts(Via(head)->DictionaryList);
  1958.     Efree(head);
  1959.     }
  1960. }
  1961.  
  1962.