as: Use a file pointer for sections - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit fba444a27d3a288a7180c980f48a0cd1bfdd88ee
 (DIR) parent 9d275a5c7bede08ee3ab2c2012ffeda5e011c137
 (HTM) 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:
         M include/scc/scc/mach.h              |       3 ---
         M src/cmd/as/as.h                     |       1 -
         M src/cmd/as/binfmt.c                 |      30 ++++++++++++++++++++++++------
         M src/cmd/as/symbol.c                 |      79 +++++++++++++++++++------------
       
       4 files changed, 72 insertions(+), 41 deletions(-)
       ---
 (DIR) 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;
        };
        
        /**
 (DIR) 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 *);
 (DIR) 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);
        }
       -
 (DIR) 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;
                }