home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / output < prev    next >
Encoding:
Text File  |  1993-02-10  |  5.4 KB  |  184 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. static char *message = 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.   if(outname[0])
  53.     remove(outname);
  54. }
  55.  
  56. int countAreas(Symbol *ap)
  57. {
  58.   int i = 0;
  59.   while(ap) {
  60.     ap->used = i++;
  61.     ap = ap->area.info->next;
  62.   }
  63.   return i;
  64. }
  65.  
  66. int sizeAreas(Symbol *ap, AofHeader *op)
  67. {
  68.   int size = 0;
  69.   for(; ap; ap = ap->area.info->next)
  70.     if(!(ap->area.info->type & AREA_UDATA))
  71.       size += ourword(op->entry[ap->used].Size) + 
  72.             8*ourword(op->entry[ap->used].noRelocations);
  73.   return size;
  74. }
  75.  
  76. void outputAof(void)
  77. {
  78.   ChunkFileHeader *chunkFile;
  79.   AofHeader      *objHeader;
  80.   int noareas = countAreas(areaHead);
  81.   int cfhsize = chunkFileHeaderSize(5);
  82.   int ohsize = aofHeaderSize(noareas);
  83.   int offset = cfhsize;
  84.   Symbol *ap;
  85.   int pad;
  86.  
  87.   if((chunkFile = malloc(cfhsize))==0)
  88.     errorLine(0,ErrorSerious,FALSE,"Out of memory when allocating chunkFileHeader");
  89.   chunkFile->ChunkField = ChunkFileID;
  90.   chunkFile->maxChunks = chunkFile->noChunks = 5;
  91.  
  92.   if((objHeader = malloc(ohsize))==0)
  93.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Out of memory when allocating objHeader");
  94.  
  95.   for(ap = areaHead; ap; ap = ap->area.info->next) {
  96.     objHeader->entry[ap->used].Type = ap->area.info->type;
  97.     objHeader->entry[ap->used].Size = FIX(ap->value.ValueInt.i);
  98.     if((objHeader->entry[ap->used].noRelocations = relocFix(ap)) != 0 &&
  99.         objHeader->entry[ap->used].Type & AREA_UDATA)
  100.       errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Relocations in uninitsialised area.");
  101.     objHeader->entry[ap->used].Unused = 0;
  102.   }
  103.  
  104.   objHeader->Type = AofHeaderID;
  105.   objHeader->Version = 150;
  106.   objHeader->noAreas = noareas;
  107.   objHeader->noSymbols = symbolFix();
  108.   objHeader->EntryArea = areaEntry?areaEntry->used+1:0; 
  109.   objHeader->EntryOffset = areaEntry?areaEntryOffset:0;  
  110.   for(ap = areaHead; ap; ap = ap->area.info->next)
  111.     objHeader->entry[ap->used].Name = ap->offset;
  112.  
  113.   chunkFile->entry[0].ChunkIDPrefix = ChunkID_OBJ;
  114.   chunkFile->entry[0].ChunkIDType = ChunkID_OBJ_HEAD;
  115.   chunkFile->entry[0].FileOffset = offset;
  116.   chunkFile->entry[0].Size = ohsize;
  117.   offset += chunkFile->entry[0].Size;
  118.  
  119.   chunkFile->entry[1].ChunkIDPrefix = ChunkID_OBJ;
  120.   chunkFile->entry[1].ChunkIDType = ChunkID_OBJ_IDFN;
  121.   chunkFile->entry[1].FileOffset = offset;
  122.   chunkFile->entry[1].Size = FIX(strlen(message)+1);
  123.   offset += chunkFile->entry[1].Size;
  124.  
  125.   chunkFile->entry[2].ChunkIDPrefix = ChunkID_OBJ;
  126.   chunkFile->entry[2].ChunkIDType = ChunkID_OBJ_STRT;
  127.   chunkFile->entry[2].FileOffset = offset;
  128.   chunkFile->entry[2].Size = FIX(symbolStringSize());
  129.   offset += chunkFile->entry[2].Size;
  130.  
  131.   chunkFile->entry[3].ChunkIDPrefix = ChunkID_OBJ;
  132.   chunkFile->entry[3].ChunkIDType = ChunkID_OBJ_SYMT;
  133.   chunkFile->entry[3].FileOffset = offset;
  134.   chunkFile->entry[3].Size = objHeader->noSymbols*16;
  135.   offset += chunkFile->entry[3].Size;
  136.  
  137.   chunkFile->entry[4].ChunkIDPrefix = ChunkID_OBJ;
  138.   chunkFile->entry[4].ChunkIDType = ChunkID_OBJ_AREA;
  139.   chunkFile->entry[4].FileOffset = offset;
  140.   chunkFile->entry[4].Size = sizeAreas(areaHead,objHeader);
  141.  offset += chunkFile->entry[4].Size;
  142.  
  143. /******** File header ***********/
  144.   if(cfhsize != fwrite((void *)chunkFile,1,cfhsize,objfile)) {
  145.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing chunk file header.");
  146.     exit(-1);
  147.   }
  148. /******** Chunk 0 Header ********/
  149.   if(ourword(chunkFile->entry[0].Size) !=
  150.         fwrite((void *)objHeader,1,ourword(chunkFile->entry[0].Size),objfile)) {
  151.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing chunk header.");
  152.     exit(-1);
  153.   }
  154. /******** Chunk 1 Identification *********/
  155.   if(ourword(chunkFile->entry[1].Size) != 
  156.         fwrite((void *)message,1,ourword(chunkFile->entry[1].Size),objfile)) {
  157.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing identification.");
  158.     exit(-1);
  159.   }
  160. /******** Chunk 2 String Table ***********/
  161.   if(4 != fwrite((void *)&chunkFile->entry[2].Size,1,4,objfile)) {
  162.     errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing string table size.");
  163.     exit(-1);
  164.   }
  165.   symbolStringOutput(objfile);
  166.   for(pad = EXTRA(symbolStringSize()); pad; pad--)
  167.     fputc(0,objfile);
  168.  
  169. /******** Chunk 3 Symbol Table ***********/
  170.   symbolSymbolOutput(objfile);
  171.  
  172. /******** Chunk 4 Area *****************/
  173.   for(ap = areaHead; ap; ap = ap->area.info->next) {
  174.     if(!(ap->area.info->type & AREA_UDATA)) {
  175.       if(ourword(objHeader->entry[ap->used].Size) !=
  176.             fwrite((void *)ap->area.info->image,1,ourword(objHeader->entry[ap->used].Size),objfile)){
  177.         errorLine(0,ErrorSerious,FALSE,"Internal outputAof: Error when writing %s image.",ap->str);
  178.         exit(-1);
  179.       }
  180.       relocOutput(objfile, ap);
  181.     }
  182.   }
  183. }
  184.