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