home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * output.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "error.h"
- #include "ChunkFile.h"
- #include "AofFile.h"
- #include "symbol.h"
- #include "output.h"
- #include "area.h"
- #include "riscos.h"
- #include "endian.h"
- #include "version.h"
- #include "uname.h"
-
- static FILE *objfile;
- extern char *ObjFileName;
- extern int dde;
-
- #define FIX(n) ((3+(int)n)&~3)
- #define EXTRA(n) (FIX(n)-n)
-
- char *idfn_text = MESSAGE;
-
- #define MAXNAME 256
- static char outname[MAXNAME];
-
- void
- outputInit (char *outfile)
- {
- if (outfile && strcmp (outfile, "-"))
- {
- char *temp;
- strncpy (outname, uname (outfile, dde), MAXNAME);
- temp = strrchr (outname, '.');
- if (temp > (outname + 2) && temp[-2] == '.' && temp[-1] == 's')
- temp[-1] = 'o';
- if ((objfile = fopen (outname, "wb")) == NULL)
- {
- error (ErrorAbort, FALSE, "As can't write %s", outfile);
- }
- }
- else
- {
- outname[0] = 0;
- objfile = stdout;
- }
- }
-
- void
- outputFinish (void)
- {
- if (objfile != stdout)
- fclose (objfile);
- }
-
- void
- outputRemove (void)
- {
- outputFinish ();
- if (outname[0])
- remove (outname);
- }
-
- int
- countAreas (Symbol * ap)
- {
- int i = 0;
- while (ap)
- {
- ap->used = i++;
- ap = ap->area.info->next;
- }
- return i;
- }
-
- int
- sizeAreas (Symbol * ap, AofHeader * op)
- {
- int size = 0;
- for (; ap; ap = ap->area.info->next)
- if (!(ap->area.info->type & AREA_UDATA))
- size += ourword (op->entry[ap->used].Size) +
- 8 * ourword (op->entry[ap->used].noRelocations);
- return size;
- }
-
- void
- outputAof (void)
- {
- ChunkFileHeader *chunkFile;
- AofHeader *objHeader;
- int noareas = countAreas (areaHead);
- int cfhsize = chunkFileHeaderSize (5);
- int ohsize = aofHeaderSize (noareas);
- int offset = cfhsize;
- Symbol *ap;
- int pad;
-
- if ((chunkFile = malloc (cfhsize)) == 0)
- errorLine (0, ErrorSerious, FALSE, "Out of memory when allocating chunkFileHeader");
- chunkFile->ChunkField = ChunkFileID;
- chunkFile->maxChunks = chunkFile->noChunks = 5;
-
- if ((objHeader = malloc (ohsize)) == 0)
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Out of memory when allocating objHeader");
-
- for (ap = areaHead; ap; ap = ap->area.info->next)
- {
- objHeader->entry[ap->used].Type = ap->area.info->type;
- objHeader->entry[ap->used].Size = FIX (ap->value.ValueInt.i);
- if ((objHeader->entry[ap->used].noRelocations = relocFix (ap)) != 0 &&
- objHeader->entry[ap->used].Type & AREA_UDATA)
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Relocations in uninitsialised area.");
- objHeader->entry[ap->used].Unused = 0;
- }
-
- objHeader->Type = AofHeaderID;
- objHeader->Version = 150;
- objHeader->noAreas = noareas;
- objHeader->noSymbols = symbolFix ();
- objHeader->EntryArea = areaEntry ? areaEntry->used + 1 : 0;
- objHeader->EntryOffset = areaEntry ? areaEntryOffset : 0;
- for (ap = areaHead; ap; ap = ap->area.info->next)
- objHeader->entry[ap->used].Name = ap->offset;
-
- chunkFile->entry[0].ChunkIDPrefix = ChunkID_OBJ;
- chunkFile->entry[0].ChunkIDType = ChunkID_OBJ_HEAD;
- chunkFile->entry[0].FileOffset = offset;
- chunkFile->entry[0].Size = ohsize;
- offset += chunkFile->entry[0].Size;
-
- chunkFile->entry[1].ChunkIDPrefix = ChunkID_OBJ;
- chunkFile->entry[1].ChunkIDType = ChunkID_OBJ_IDFN;
- chunkFile->entry[1].FileOffset = offset;
- chunkFile->entry[1].Size = FIX (strlen (idfn_text) + 1);
- offset += chunkFile->entry[1].Size;
-
- chunkFile->entry[2].ChunkIDPrefix = ChunkID_OBJ;
- chunkFile->entry[2].ChunkIDType = ChunkID_OBJ_STRT;
- chunkFile->entry[2].FileOffset = offset;
- chunkFile->entry[2].Size = FIX (symbolStringSize ());
- offset += chunkFile->entry[2].Size;
-
- chunkFile->entry[3].ChunkIDPrefix = ChunkID_OBJ;
- chunkFile->entry[3].ChunkIDType = ChunkID_OBJ_SYMT;
- chunkFile->entry[3].FileOffset = offset;
- chunkFile->entry[3].Size = objHeader->noSymbols * 16;
- offset += chunkFile->entry[3].Size;
-
- chunkFile->entry[4].ChunkIDPrefix = ChunkID_OBJ;
- chunkFile->entry[4].ChunkIDType = ChunkID_OBJ_AREA;
- chunkFile->entry[4].FileOffset = offset;
- chunkFile->entry[4].Size = sizeAreas (areaHead, objHeader);
- offset += chunkFile->entry[4].Size;
-
- /******** File header ***********/
- if (cfhsize != fwrite ((void *) chunkFile, 1, cfhsize, objfile))
- {
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Error when writing chunk file header.");
- exit (-1);
- }
- /******** Chunk 0 Header ********/
- if (ourword (chunkFile->entry[0].Size) !=
- fwrite ((void *) objHeader, 1, ourword (chunkFile->entry[0].Size), objfile))
- {
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Error when writing chunk header.");
- exit (-1);
- }
- /******** Chunk 1 Identification *********/
- if (ourword (chunkFile->entry[1].Size) !=
- fwrite ((void *) idfn_text, 1, ourword (chunkFile->entry[1].Size), objfile))
- {
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Error when writing identification.");
- exit (-1);
- }
- /******** Chunk 2 String Table ***********/
- if (4 != fwrite ((void *) &chunkFile->entry[2].Size, 1, 4, objfile))
- {
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Error when writing string table size.");
- exit (-1);
- }
- symbolStringOutput (objfile);
- for (pad = EXTRA (symbolStringSize ()); pad; pad--)
- fputc (0, objfile);
-
- /******** Chunk 3 Symbol Table ***********/
- symbolSymbolOutput (objfile);
-
- /******** Chunk 4 Area *****************/
- for (ap = areaHead; ap; ap = ap->area.info->next)
- {
- if (!(ap->area.info->type & AREA_UDATA))
- {
- if (ourword (objHeader->entry[ap->used].Size) !=
- fwrite ((void *) ap->area.info->image, 1, ourword (objHeader->entry[ap->used].Size), objfile))
- {
- errorLine (0, ErrorSerious, FALSE, "Internal outputAof: Error when writing %s image.", ap->str);
- exit (-1);
- }
- relocOutput (objfile, ap);
- }
- }
- }
-