ref: 620493c9bdc92f1d4309f1b6bbf9c23f2000aecb
dir: /as/myro.c/
static char sccsid[] = "@(#) ./as/myro.c"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../inc/scc.h" #include "as.h" struct myrohdr { unsigned long format; unsigned long long entry; unsigned long long strsize; unsigned long long secsize; unsigned long long symsize; unsigned long long relsize; }; struct myrosect { unsigned long name; unsigned short flags; unsigned char fill; unsigned char aligment; unsigned long long offset; unsigned long long len; }; struct myrosym { unsigned long name; unsigned long type; unsigned char section; unsigned char flags; unsigned long long offset; unsigned long long len; }; struct myrorel { unsigned long id; unsigned char flags; unsigned char size; unsigned char nbits; unsigned char shift; unsigned long long offset; }; static Reloc *relocs; static size_t relcap, relsiz; static void writehdr(FILE *fp, struct myrohdr *hdr) { unsigned char buf[sizeof(*hdr)]; size_t len; len = lpack(buf, "lqqqqq", hdr->format, hdr->entry, hdr->strsize, hdr->secsize, hdr->symsize, hdr->relsize); fwrite(buf, len, 1, fp); } static size_t writesec(FILE *fp, struct myrosect *sect) { unsigned char buf[sizeof(*sect)]; size_t len; len = lpack(buf, "lsccqq", sect->name, sect->flags, sect->fill, sect->aligment, sect->offset, sect->len); fwrite(buf, len, 1, fp); return len; } static size_t writestrings(FILE *fp) { size_t off = 0; size_t len; Symbol *sym; Section *sp; String str; fputs("z80-scc", fp); off = 7; for (sym = symlist; sym; sym = sym->next) { str = sym->name; len = strlen(str.buf) + 1; fwrite(str.buf, len, 1, fp); str.offset = off; off += len; } for (sp = seclist; sp; sp = sp->next) { str = sp->name; len = strlen(str.buf) + 1; fwrite(str.buf, len, 1, fp); str.offset = off; off += len; } return off; } static size_t writesections(FILE *fp) { Section *sp; size_t off = 0; struct myrosect sect; for (sp = seclist; sp; sp = sp->next) { sect.name = sp->name.offset; sect.flags = 0; sect.fill = 0; sect.aligment = 0; sect.offset = off; sect.len = 0; off += writesec(fp, §); } return off; } static size_t writesym(FILE *fp, struct myrosym *sym) { unsigned char buf[sizeof(*sym)]; size_t len; len = lpack(buf, "llccqq", sym->name, sym->type, sym->section, sym->flags, sym->offset, sym->len); fwrite(buf, len, 1, fp); return len; } static size_t writesymbols(FILE *fp) { Symbol *sym; size_t off = 0; struct myrosym symbol; for (sym = symlist; sym; sym = sym->next) { symbol.name = sym->name.offset; symbol.type = -1; symbol.section = -1; symbol.flags = 0; symbol.offset = off; symbol.len = 0; off += writesym(fp, &symbol); } return off; } static size_t writerel(FILE *fp, struct myrorel *rel) { unsigned char buf[sizeof(*rel)]; size_t len; len = lpack(buf, "lccccq", rel->id, rel->flags, rel->size, rel->nbits, rel->shift, rel->offset); return len; } static size_t writerelocs(FILE *fp) { Reloc *bp, *lim; size_t off = 0; struct myrorel reloc; lim = &relocs[relsiz]; for (bp = relocs; bp < lim; ++bp) { reloc.id = 0; reloc.flags = bp->flags; reloc.size = bp->size; reloc.nbits = bp->nbits; reloc.shift = bp->shift; reloc.offset = bp->offset; off += writerel(fp, &reloc); } return off; } static void writedata(FILE *fp) { Section *sp; for (sp = seclist; sp; sp = sp->next) { if (!sp->mem) continue; fwrite(sp->mem, sp->max - sp->base, 1, fp); } } void writeout(char *name) { FILE *fp; long hdrpos; struct myrohdr hdr = {0}; if ((fp = fopen(name, "wb")) == NULL) die("error opening output file '%s'\n", name); fputs("uobj", fp); hdrpos = ftell(fp); writehdr(fp, &hdr); hdr.strsize = writestrings(fp); hdr.secsize = writesections(fp); hdr.symsize = writesymbols(fp); hdr.relsize = writerelocs(fp); writedata(fp); fseek(fp, hdrpos, SEEK_SET); writehdr(fp, &hdr); if (fclose(fp)) die("error writing the output file"); } void reloc(Symbol *sym, unsigned flags, unsigned size, unsigned nbits, unsigned shift) { size_t tmp; Reloc *p; if (relcap == relsiz) { tmp = ((relcap + 1) * 3) / 2; if ((p = realloc(relocs, tmp * sizeof(Reloc))) == NULL) { tmp = relcap + 1; p = xrealloc(relocs, tmp * sizeof(Reloc)); } relcap = tmp; relocs = p; } p = &relocs[relsiz++]; p->sym = sym; p->flags = flags; p->size = size; p->nbits = nbits; p->shift = shift; p->offset = cursec->pc - cursec->base; }