scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 1f08b88131aeb2829ca3b726416420e485a5f297
parent 8948e258c4224a0a7e2ee5cced431b76f912e4d8
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  8 Feb 2019 07:47:13 +0000

[libmach/coff32] Add all the missed parts in coff32write

Diffstat:
Minclude/scc/scc/coff32/syms.h | 4++--
Msrc/libmach/coff32/coff32read.c | 6+++---
Msrc/libmach/coff32/coff32write.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 168 insertions(+), 28 deletions(-)

diff --git a/include/scc/scc/coff32/syms.h b/include/scc/scc/coff32/syms.h @@ -1,10 +1,10 @@ /* This file is inspired in the book "Understanding and using COFF" */ -#define E_SYMNMLEN 8 +#define SYMNMLEN 8 struct syment { union { - char _n_name[8]; /* symbol name */ + char _n_name[SYMNMLEN]; /* symbol name */ struct { long _n_zeroes; /* if _n_name[0-3] == 0 */ long _n_offset; /* offset into string table */ diff --git a/src/libmach/coff32/coff32read.c b/src/libmach/coff32/coff32read.c @@ -244,7 +244,8 @@ readstr(Obj *obj, FILE *fp) static int readreloc(Obj *obj, FILE *fp) { - int i, j; + int i; + long j; RELOC **rels, *rp; SCNHDR *scn; FILHDR *hdr; @@ -414,8 +415,7 @@ readscns(Obj *obj, FILE *fp) return 0; coff->scns = scn; } - if (fseek(fp, hdr->f_opthdr, SEEK_CUR) < 0) - return 0; + for (i = 0; i < hdr->f_nscns; i++) { if (fread(buf, SCNHSZ, 1, fp) < 0) return 0; diff --git a/src/libmach/coff32/coff32write.c b/src/libmach/coff32/coff32write.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <limits.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -60,11 +61,11 @@ pack_ent(int order, unsigned char *buf, SYMENT *ent) buf, "'8lsscc", ent->n_name, - &ent->n_value, - &ent->n_scnum, - &ent->n_type, - &ent->n_sclass, - &ent->n_numaux); + ent->n_value, + ent->n_scnum, + ent->n_type, + ent->n_sclass, + ent->n_numaux); assert(n == SYMESZ); } @@ -73,17 +74,17 @@ pack_aout(int order, unsigned char *buf, AOUTHDR *aout) { int n; - n = unpack(order, - buf, - "ssllllll", - aout->magic, - aout->vstamp, - aout->tsize, - aout->dsize, - aout->bsize, - aout->entry, - aout->text_start, - aout->data_start); + n = pack(order, + buf, + "ssllllll", + aout->magic, + aout->vstamp, + aout->tsize, + aout->dsize, + aout->bsize, + aout->entry, + aout->text_start, + aout->data_start); assert(n == AOUTSZ); } @@ -135,34 +136,173 @@ writehdr(Obj *obj, FILE *fp) static int writescns(Obj *obj, FILE *fp) { - /* TODO */ + int i; + SCNHDR *scn; + FILHDR *hdr; + struct coff32 *coff; + unsigned char buf[SCNHSZ]; + + coff = obj->data; + hdr = &coff->hdr; + + for (i = 0; i < hdr->f_nscns; i++) { + scn = &coff->scns[i]; + pack_scn(ORDER(obj->type), buf, scn); + if (fwrite(buf, SCNHSZ, 1, fp) != 1) + return 0; + } + + return 1; } static int writeents(Obj *obj, FILE *fp) { - /* TODO */ + long i, len, strsiz; + char *strtbl, *s; + FILHDR *hdr; + struct coff32 *coff; + unsigned char buf[SYMESZ]; + + coff = obj->data; + hdr = &coff->hdr; + strtbl = NULL; + strsiz = 0; + + for (i = 0; i < hdr->f_nsyms; i++) { + SYMENT *ent = &coff->ents[i]; + + len = strlen(ent->n_name) + 1; + if (len > strsiz - LONG_MAX) + goto err; + s = realloc(strtbl, strsiz + len); + if (!s) + goto err; + memcpy(s + strsiz, ent->n_name, len); + strtbl = s; + strsiz += len; + + pack_ent(ORDER(obj->type), buf, ent); + if (fwrite(buf, SYMESZ, 1, fp) != 1) + return 0; + } + + free(coff->strtbl); + coff->strtbl = strtbl; + coff->strsiz = strsiz; + + return 1; + +err: + free(strtbl); + return 0; } static int writestr(Obj *obj, FILE *fp) { - /* TODO */ + struct coff32 *coff; + unsigned char buf[4]; + + coff = obj->data; + if ((coff->strsiz & 0xffff) != coff->strsiz) + return 0; + + pack(ORDER(obj->type), buf, "l", coff->strsiz); + fwrite(buf, 4, 1, fp); + fwrite(coff->strtbl, coff->strsiz, 1, fp); + + return ferror(fp); } -int -coff32write(Obj *obj, FILE *fp) +static int +writeaout(Obj *obj, FILE *fp) { + FILHDR *hdr; struct coff32 *coff; + unsigned char buf[AOUTSZ]; coff = obj->data; - coff->strsiz = 0; - free(coff->strtbl); + hdr = &coff->hdr; + if (hdr->f_opthdr == 0) + return 1; + pack_aout(ORDER(obj->type), buf, coff->aout); + + return fread(buf, AOUTSZ, 1, fp) != 1; +} + +static int +writereloc(Obj *obj, FILE *fp) +{ + int i, j; + RELOC *rp; + SCNHDR *scn; + FILHDR *hdr; + struct coff32 *coff; + unsigned char buf[RELSZ]; + + coff = obj->data; + hdr = &coff->hdr; + + for (i = 0; i < hdr->f_nscns; i++) { + rp = coff->rels[i]; + if (!rp) + continue; + scn = &coff->scns[i]; + + for (j = 0; j < scn->s_nrelloc; j++) { + pack_reloc(ORDER(obj->type), buf, &rp[i]); + if (fwrite(buf, RELSZ, 1, fp) != 1) + return 0; + } + } + + return 1; +} + +static int +writelines(Obj *obj, FILE *fp) +{ + int i; + long j; + FILHDR *hdr; + LINENO *lp; + SCNHDR *scn; + struct coff32 *coff; + unsigned char buf[LINESZ]; + + coff = obj->data; + hdr = &coff->hdr; + + for (i = 0; i < hdr->f_nscns; i++) { + lp = coff->lines[i]; + if (!lp) + continue; + scn = &coff->scns[i]; + for (j = 0; j < scn->s_nlnno; j++) { + pack_line(ORDER(obj->type), buf, &lp[j]); + if (fwrite(buf, LINESZ, 1, fp) == 1) + return 0; + } + } + + return 1; +} + +int +coff32write(Obj *obj, FILE *fp) +{ if (!writehdr(obj, fp)) return -1; + if (!writeaout(obj, fp)) + return -1; if (!writescns(obj, fp)) return -1; + if (!writereloc(obj, fp)) + return -1; + if (!writelines(obj, fp)) + return -1; if (!writeents(obj, fp)) return -1; if (!writestr(obj, fp))