scc

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

commit fba444a27d3a288a7180c980f48a0cd1bfdd88ee
parent 9d275a5c7bede08ee3ab2c2012ffeda5e011c137
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 15 Feb 2024 07:38:49 +0100

as: Use a file pointer for sections

This helps to avoid having a memory pointer in the section
structure that is used only in the case of as, and it makes
easier to use libmach in the case of as.

Diffstat:
Minclude/scc/scc/mach.h | 3---
Msrc/cmd/as/as.h | 1-
Msrc/cmd/as/binfmt.c | 30++++++++++++++++++++++++------
Msrc/cmd/as/symbol.c | 79++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
4 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -68,9 +68,6 @@ struct section { int align; int fill; char type; - - /* TODO: Remove it once as if fixed */ - char *mem; }; /** diff --git a/src/cmd/as/as.h b/src/cmd/as/as.h @@ -118,7 +118,6 @@ extern Symbol *tmpsym(TUINT); extern void killtmp(void); extern int toobig(Node *, int); extern void dumpstab(char *); -extern Section *secindex(int); int forallsecs(int (*)(Section *, void *), void *); extern Symbol *lookup(char *); extern Symbol *deflabel(char *); diff --git a/src/cmd/as/binfmt.c b/src/cmd/as/binfmt.c @@ -8,15 +8,33 @@ #include "as.h" +/* + * FIXME: Horrible hack, just the data structure copied here + * To be able to continue working and not breaking the tests + * but it should be removed from here as soon as posible. + */ +struct lsection { + Section sec; + FILE *fp; +}; + static int -dumpsec(Section *sec, void *arg) +dumpsec(Section *sec, void *dst) { - FILE *fp = arg; + int c; + struct lsection *lsec = (struct lsection *) sec; + FILE *src = lsec->fp; - if (!sec->mem) + if (!src) return 0; - fwrite(sec->mem, sec->size, 1, fp); + rewind(src); + while ((c = getc(src)) != EOF) + putc(c, dst); + + if (ferror(src)) + return -1; + return 0; } @@ -28,7 +46,8 @@ writeout(char *fname) if ((fp = fopen(fname, "wb")) == NULL) goto error; - forallsecs(dumpsec, fp); + if (forallsecs(dumpsec, fp) < 0) + goto error; fflush(fp); if (ferror(fp)) @@ -43,4 +62,3 @@ error: fprintf(stderr, "as: %s: %s\n", fname, strerror(errno)); exit(EXIT_FAILURE); } - diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c @@ -13,17 +13,30 @@ #define HASHSIZ 64 #define NALLOC 10 +/* + * sym must be the first field because we generate + * a pointer to lsymbol from the symbol + */ struct lsymbol { Symbol sym; + Section *sec; struct lsymbol *next; struct lsymbol *hash; }; +/* + * sec must be the first field because we generate + * a pointer to lsection from the section + */ struct lsection { - Section s; + Section sec; + FILE *fp; + unsigned long long curpc; + unsigned long long pc; struct lsection *next; }; +Map *map; Section *cursec; Section *sabs, *sbss, *sdata, *stext; Symbol *linesym; @@ -86,6 +99,7 @@ lookup(char *name) lp = xmalloc(sizeof(*lp)); lp->next = NULL; lp->hash = hashtbl[h]; + lp->sec = NULL; hashtbl[h] = lp; if (symlast) @@ -229,36 +243,30 @@ secflags(char *attr) return flags; } -Section * -secindex(int n) -{ - struct lsection *lp; - - for (lp = seclist; lp && lp->s.index != n; lp = lp->next) - ; - - return (lp) ? &lp->s : NULL; -} - static Section * newsect(Symbol *sym) { Section *sec; - struct lsection *lp; + struct lsection *lsec; + struct lsymbol *lsym; static int index; - lp = xmalloc(sizeof(*lp)); - lp->next = seclist; - seclist = lp; + lsec = xmalloc(sizeof(*lsec)); + lsec->next = seclist; + lsec->fp = NULL; + seclist = lsec; - sec = &lp->s; - sec->mem = NULL; - sec->name = xstrdup(sym->name); + sec = &lsec->sec; + sec->name = sym->name; sec->base = sec->size = sec->pc = sec->curpc = 0; sec->flags = 0; sec->fill = 0; sec->align = 0; sec->index = index++; + setmap(map, sym->name, NULL, 0, 0, 0); + + lsym = (struct lsymbol *) sym; + lsym->sec = sec; return sec; } @@ -266,6 +274,7 @@ newsect(Symbol *sym) Section * setsec(char *name, char *attr) { + struct lsymbol *lsym; Section *sec; Symbol *sym; @@ -274,9 +283,11 @@ setsec(char *name, char *attr) if (sym->flags & ~FSECT) error("invalid section name '%s'", name); - sec = secindex(sym->section); + lsym = (struct lsymbol *) sym; + sec = lsym->sec; if (sec == NULL) { sec = newsect(sym); + lsym->sec = sec; sym->section = sec->index; sym->flags = FSECT; } @@ -288,6 +299,11 @@ setsec(char *name, char *attr) void isecs(void) { + if ((map = newmap(NULL, 4)) == NULL) { + perror("as"); + exit(EXIT_FAILURE); + } + sabs = setsec(".abs", "rwxa"); sbss = setsec(".bss", "rw"); sdata = setsec(".data", "rwc"); @@ -298,17 +314,18 @@ void cleansecs(void) { Section *sec; - struct lsection *lp; + struct lsection *lsec; - for (lp = seclist; lp; lp = lp->next) { - sec = &lp->s; + for (lsec = seclist; lsec; lsec = lsec->next) { + sec = &lsec->sec; sec->curpc = sec->pc = sec->base; if (pass == 1 || (sec->flags & SALLOC) == 0) continue; - if (sec->size > SIZE_MAX) - die("as: out of memory"); - sec->mem = xmalloc(sec->size); + if ((lsec->fp = tmpfile()) == NULL) { + perror("as"); + exit(EXIT_FAILURE); + } } cursec = stext; } @@ -316,10 +333,10 @@ cleansecs(void) void emit(char *bytes, int n) { - if (cursec->mem) { - size_t len = cursec->pc - cursec->base; - memcpy(&cursec->mem[len], bytes, n); - } + struct lsection *lsec = (struct lsection *) cursec; + + if (lsec->fp) + fwrite(bytes, n, 1, lsec->fp); incpc(n); } @@ -353,7 +370,7 @@ forallsecs(int (*fn)(Section *, void *), void *arg) struct lsection *lp; for (lp = seclist; lp; lp = lp->next) { - if ((*fn)(&lp->s, arg) < 0) + if ((*fn)(&lp->sec, arg) < 0) return -1; }