home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / a / as1_23 / source / c / output < prev    next >
Encoding:
Text File  |  1993-12-28  |  5.4 KB  |  185 lines

  1.  
  2. /*
  3.  * output.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "error.h"
  11. #include "ChunkFile.h"
  12. #include "AofFile.h"
  13. #include "symbol.h"
  14. #include "output.h"
  15. #include "area.h"
  16. #include "riscos.h"
  17. #include "endian.h"
  18. #include "version.h"
  19.  
  20. static FILE *objfile;
  21. extern char *ObjFileName;
  22.  
  23. #define FIX(n) ((3+(int)n)&~3)
  24. #define EXTRA(n) (FIX(n)-n)
  25.  
  26. char *idfn_text = MESSAGE;
  27.  
  28. #define MAXNAME 256
  29. static char outname[MAXNAME];
  30.  
  31. void outputInit(char *outfile)
  32. {
  33.   if(outfile && strcmp(outfile,"-")) {
  34.     strncpy(outname,toriscos(outfile,"os",'o'),MAXNAME);
  35.     if((objfile = fopen(outname,"wb")) == NULL) {
  36.       error(ErrorAbort,FALSE,"As can't write %s",outfile);
  37.     }
  38.   } else {
  39.     outname[0] = 0;
  40.     objfile = stdout;
  41.   }
  42. }
  43.  
  44. void outputFinish(void)
  45. {
  46.   if(objfile != stdout)
  47.     fclose(objfile);
  48. }
  49.  
  50. void outputRemove(void)
  51. {
  52.   outputFinish();
  53.   if(outname[0])
  54.     remove(outname);
  55. }
  56.  
  57. int countAreas(Symbol *ap)
  58. {
  59.   int i = 0;
  60.   while(ap) {
  61.     ap->used = i++;
  62.     ap = ap->area.info->next;
  63.   }
  64.   return i;
  65. }
  66.  
  67. int sizeAreas(Symbol *ap, AofHeader *op)
  68. {
  69.   int size = 0;
  70.   for(; ap; ap = ap->area.info->next)
  71.     if(!(ap->area.info->type & AREA_UDATA))
  72.       size += ourword(op->entry[ap->used].Size) + 
  73.             8*ourword(op->entry[ap->used].noRelocations);
  74.   return size;
  75. }
  76.  
  77. void outputAof(void)
  78. {
  79.   ChunkFileHeader *chunkFile;
  80.   AofHeader      *objHeader;
  81.   int noareas = countAreas(areaHead);
  82.   int cfhsize = chunkFileHeaderSize(5);
  83.   int ohsize = aofHeaderSize(noareas);
  84.   int offset = cfhsize;
  85.   Symbol *ap;
  86.   int pad;
  87.  
  88.   if((chunkFile = malloc(cfhsize))==0)
  89.     errorLine(0,ErrorSerious,FALSE,"Out of memory when allocating chunkFileHeader");
  90.   chunkFile->ChunkField = ChunkFileID;
  91.   chunkFile->maxChunks = chunkFile->noChunks = 5;
  92.  
  93.   if((objHeader = malloc(ohsize))==0)
  94.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Out of memory when allocating objHeader");
  95.  
  96.   for(ap = areaHead; ap; ap = ap->area.info->next) {
  97.     objHeader->entry[ap->used].Type = ap->area.info->type;
  98.     objHeader->entry[ap->used].Size = FIX(ap->value.ValueInt.i);
  99.     if((objHeader->entry[ap->used].noRelocations = relocFix(ap)) != 0 &&
  100.         objHeader->entry[ap->used].Type & AREA_UDATA)
  101.       errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Relocations in uninitsialised area.");
  102.     objHeader->entry[ap->used].Unused = 0;
  103.   }
  104.  
  105.   objHeader->Type = AofHeaderID;
  106.   objHeader->Version = 150;
  107.   objHeader->noAreas = noareas;
  108.   objHeader->noSymbols = symbolFix();
  109.   objHeader->EntryArea = areaEntry?areaEntry->used+1:0; 
  110.   objHeader->EntryOffset = areaEntry?areaEntryOffset:0;  
  111.   for(ap = areaHead; ap; ap = ap->area.info->next)
  112.     objHeader->entry[ap->used].Name = ap->offset;
  113.  
  114.   chunkFile->entry[0].ChunkIDPrefix = ChunkID_OBJ;
  115.   chunkFile->entry[0].ChunkIDType = ChunkID_OBJ_HEAD;
  116.   chunkFile->entry[0].FileOffset = offset;
  117.   chunkFile->entry[0].Size = ohsize;
  118.   offset += chunkFile->entry[0].Size;
  119.  
  120.   chunkFile->entry[1].ChunkIDPrefix = ChunkID_OBJ;
  121.   chunkFile->entry[1].ChunkIDType = ChunkID_OBJ_IDFN;
  122.   chunkFile->entry[1].FileOffset = offset;
  123.   chunkFile->entry[1].Size = FIX(strlen(idfn_text)+1);
  124.   offset += chunkFile->entry[1].Size;
  125.  
  126.   chunkFile->entry[2].ChunkIDPrefix = ChunkID_OBJ;
  127.   chunkFile->entry[2].ChunkIDType = ChunkID_OBJ_STRT;
  128.   chunkFile->entry[2].FileOffset = offset;
  129.   chunkFile->entry[2].Size = FIX(symbolStringSize());
  130.   offset += chunkFile->entry[2].Size;
  131.  
  132.   chunkFile->entry[3].ChunkIDPrefix = ChunkID_OBJ;
  133.   chunkFile->entry[3].ChunkIDType = ChunkID_OBJ_SYMT;
  134.   chunkFile->entry[3].FileOffset = offset;
  135.   chunkFile->entry[3].Size = objHeader->noSymbols*16;
  136.   offset += chunkFile->entry[3].Size;
  137.  
  138.   chunkFile->entry[4].ChunkIDPrefix = ChunkID_OBJ;
  139.   chunkFile->entry[4].ChunkIDType = ChunkID_OBJ_AREA;
  140.   chunkFile->entry[4].FileOffset = offset;
  141.   chunkFile->entry[4].Size = sizeAreas(areaHead,objHeader);
  142.  offset += chunkFile->entry[4].Size;
  143.  
  144. /******** File header ***********/
  145.   if(cfhsize != fwrite((void *)chunkFile,1,cfhsize,objfile)) {
  146.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing chunk file header.");
  147.     exit(-1);
  148.   }
  149. /******** Chunk 0 Header ********/
  150.   if(ourword(chunkFile->entry[0].Size) !=
  151.         fwrite((void *)objHeader,1,ourword(chunkFile->entry[0].Size),objfile)) {
  152.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing chunk header.");
  153.     exit(-1);
  154.   }
  155. /******** Chunk 1 Identification *********/
  156.   if(ourword(chunkFile->entry[1].Size) != 
  157.         fwrite((void *)idfn_text,1,ourword(chunkFile->entry[1].Size),objfile)) {
  158.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing identification.");
  159.     exit(-1);
  160.   }
  161. /******** Chunk 2 String Table ***********/
  162.   if(4 != fwrite((void *)&chunkFile->entry[2].Size,1,4,objfile)) {
  163.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing string table size.");
  164.     exit(-1);
  165.   }
  166.   symbolStringOutput(objfile);
  167.   for(pad = EXTRA(symbolStringSize()); pad; pad--)
  168.     fputc(0,objfile);
  169.  
  170. /******** Chunk 3 Symbol Table ***********/
  171.   symbolSymbolOutput(objfile);
  172.  
  173. /******** Chunk 4 Area *****************/
  174.   for(ap = areaHead; ap; ap = ap->area.info->next) {
  175.     if(!(ap->area.info->type & AREA_UDATA)) {
  176.       if(ourword(objHeader->entry[ap->used].Size) !=
  177.             fwrite((void *)ap->area.info->image,1,ourword(objHeader->entry[ap->used].Size),objfile)){
  178.         errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing %s image.",ap->str);
  179.         exit(-1);
  180.       }
  181.       relocOutput(objfile, ap);
  182.     }
  183.   }
  184. }
  185.