scc

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

commit 7b484ddf2a8546ce55949d81cb177bbef416dcff
parent 70b4d78d91cd330d951b919534c0da553489be55
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 11 Feb 2024 16:19:30 +0100

as: Align symbol and section with mach.h

As uses types very similar to the types used
in mach.h and if we want to use libmach in
as then we have to align these structures
to avoid the collition between them.

Diffstat:
Minclude/scc/scc/mach.h | 11+++++++++++
Msrc/cmd/as/as.h | 47++++++++++++++++++++++++-----------------------
Msrc/cmd/as/binfmt.c | 24+++++++++++++++++-------
Msrc/cmd/as/ins.c | 2+-
Msrc/cmd/as/symbol.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/libmach/libmach.h | 1-
6 files changed, 160 insertions(+), 79 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -60,12 +60,21 @@ struct section { char *name; unsigned long long base; unsigned long long size; + unsigned long long curpc; + unsigned long long pc; + unsigned flags; int index; int align; + int fill; char type; }; +/** + * @stype: Used internally by libmach + * @dtype: Coff debug type + * @flags: Used only by the assembler + */ struct symbol { char *name; unsigned long long size; @@ -74,6 +83,8 @@ struct symbol { int section; char type; int stype; + int dtype; + unsigned flags; }; extern int archive(FILE *fp); diff --git a/src/cmd/as/as.h b/src/cmd/as/as.h @@ -108,29 +108,31 @@ struct op { }; struct section { - Symbol *sym; + char *name; + unsigned long long base; + unsigned long long size; + unsigned long long curpc; + unsigned long long pc; + + unsigned flags; + int index; + int align; + int fill; + char type; + char *mem; - unsigned char flags; - unsigned char fill; - unsigned char aligment; - unsigned id; - TUINT base; - TUINT max; - TUINT curpc; - TUINT pc; - struct section *next; }; struct symbol { char *name; - char *type; - unsigned char flags; - unsigned char pass; - TUINT value; - TUINT size; - Section *section; - struct symbol *next; - struct symbol *hash; + unsigned long long size; + unsigned long long value; + int index; + int section; + char type; + int stype; + int dtype; + unsigned flags; }; struct node { @@ -146,7 +148,6 @@ union yylval { Symbol *sym; }; - /* symbol.c */ extern void cleansecs(void); extern void isecs(void); @@ -156,8 +157,8 @@ extern Symbol *tmpsym(TUINT); extern void killtmp(void); extern int toobig(Node *, int); extern void dumpstab(char *); - -/* main.c */ +extern Section *secindex(int); +int forallsecs(int (*)(Section *, void *), void *); extern Symbol *lookup(char *); extern Symbol *deflabel(char *); @@ -200,13 +201,13 @@ extern void writeout(char *); */ extern unsigned long M, S, K; extern short hashmap[]; -extern Section *cursec, *seclist; +extern Section *cursec; extern Ins instab[]; extern Op optab[]; extern int pass; extern TUINT maxaddr; extern int endian; -extern Symbol *linesym, *symlist; +extern Symbol *linesym; extern char *infile, *outfile; extern int endpass; extern int yytoken; diff --git a/src/cmd/as/binfmt.c b/src/cmd/as/binfmt.c @@ -7,23 +7,33 @@ #include "as.h" +static int +dumpsec(Section *sec, void *arg) +{ + FILE *fp = arg; + + if (!sec->mem) + return 0; + + fwrite(sec->mem, sec->size, 1, fp); + return 0; +} + void writeout(char *fname) { - Section *sp; FILE *fp; if ((fp = fopen(fname, "wb")) == NULL) goto error; - for (sp = seclist; sp; sp = sp->next) { - if (!sp->mem) - continue; - fwrite(sp->mem, sp->max - sp->base, 1, fp); - } + forallsecs(dumpsec, fp); + fflush(fp); - if (fclose(fp)) + if (ferror(fp)) goto error; + + fclose(fp); outfile = NULL; return; diff --git a/src/cmd/as/ins.c b/src/cmd/as/ins.c @@ -149,7 +149,7 @@ symexp(int which, Op *op, Node **args) sym->size = exp->value; break; case TYPE: - sym->type = xstrdup(exp->name); + sym->dtype = exp->value; break; } } diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c @@ -11,19 +11,33 @@ #define HASHSIZ 64 #define NALLOC 10 -Section *cursec, *seclist; +struct lsymbol { + Symbol sym; + struct lsymbol *next; + struct lsymbol *hash; +}; + +struct lsection { + Section s; + struct lsection *next; +}; + +Section *cursec; Section *sabs, *sbss, *sdata, *stext; -Symbol *linesym, *symlist; +Symbol *linesym; int pass; -static Symbol *hashtbl[HASHSIZ], *symlast, *cursym; +static struct lsection *seclist; +static struct lsymbol *hashtbl[HASHSIZ], *symlast, *symlist; + +static Symbol *cursym; static Alloc *tmpalloc; #ifndef NDEBUG void dumpstab(char *msg) { - Symbol **bp, *sym; + struct lsymbol **bp, *lp; fprintf(stderr, "%s\n", msg); for (bp = hashtbl; bp < &hashtbl[HASHSIZ]; ++bp) { @@ -31,9 +45,11 @@ dumpstab(char *msg) continue; fprintf(stderr, "[%d]", (int) (bp - hashtbl)); - for (sym = *bp; sym; sym = sym->hash) { + for (lp = *bp; lp; lp = lp->hash) { fprintf(stderr, " -> %s:%0X:%0X", - sym->name, sym->flags, sym->value); + lp->sym.name, + lp->sym.flags, + lp->sym.value); } putc('\n', stderr); } @@ -44,10 +60,10 @@ Symbol * lookup(char *name) { unsigned h; - Symbol *sym, **list; + Symbol *sym; int r, c, symtype; - char *t; - char buf[INTIDENTSIZ+1]; + struct lsymbol *lp, **list; + char *t, buf[INTIDENTSIZ+1]; if (*name == '.' && cursym) { if (!cursym) @@ -63,26 +79,30 @@ lookup(char *name) c = toupper(*name); list = &hashtbl[h]; - for (sym = *list; sym; sym = sym->hash) { - t = sym->name; + for (lp = *list; lp; lp = lp->hash) { + sym = &lp->sym; + t = lp->sym.name; if (c == toupper(*t) && !casecmp(t, name)) return sym; } - sym = xmalloc(sizeof(*sym)); - sym->name = xstrdup(name); - sym->flags = 0; - sym->size = sym->value = 0; - sym->section = cursec; - sym->hash = *list; - sym->next = NULL; + lp = xmalloc(sizeof(*lp)); + lp->next = NULL; + lp->hash = *list; + *list = lp; - *list = sym; if (symlast) - symlast->next = sym; - symlast = sym; + symlast->next = lp; + symlast = lp; + if (!symlist) - symlist = sym; + symlist = lp; + + sym = &lp->sym; + sym->name = xstrdup(name); + sym->flags = 0; + sym->size = sym->value = 0; + sym->section = cursec ? cursec->index : -1; return sym; } @@ -119,7 +139,7 @@ deflabel(char *name) if (cursec->flags & SABS) sym->flags |= FABS; sym->value = cursec->curpc; - sym->section = cursec; + sym->section = cursec->index; if (!local) cursym = sym; @@ -152,21 +172,23 @@ toobig(Node *np, int type) } static void -incpc(int siz) +incpc(int nbytes) { + unsigned long long siz; TUINT pc, curpc; pc = cursec->pc; curpc = cursec->curpc; - cursec->curpc += siz; - cursec->pc += siz; + cursec->curpc += nbytes; + cursec->pc += nbytes; if (pass == 2) return; - if (cursec->pc > cursec->max) - cursec->max = cursec->pc; + siz =cursec->pc - cursec->base; + if (siz > cursec->size) + cursec->size = siz; if (pc > cursec->pc || curpc > cursec->curpc || @@ -211,6 +233,40 @@ secflags(char *attr) } 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; + static int index; + + lp = xmalloc(sizeof(*lp)); + lp->next = seclist; + seclist = lp; + + sec = &lp->s; + sec->mem = NULL; + sec->name = xstrdup(sym->name); + sec->base = sec->size = sec->pc = sec->curpc = 0; + sec->flags = 0; + sec->fill = 0; + sec->align = 0; + sec->index = index++; + + return sec; +} + +Section * setsec(char *name, char *attr) { Section *sec; @@ -221,19 +277,10 @@ setsec(char *name, char *attr) if (sym->flags & ~FSECT) error("invalid section name '%s'", name); - if ((sec = sym->section) == NULL) { - sec = xmalloc(sizeof(*sec)); - sec->mem = NULL; - sec->sym = sym; - sec->base = sec->max = sec->pc = sec->curpc = 0; - sec->next = seclist; - sec->flags = 0; - sec->fill = 0; - sec->aligment = 0; - sec->next = seclist; - seclist = sec; - - sym->section = sec; + sec = secindex(sym->section); + if (sec == NULL) { + sec = newsect(sym); + sym->section = sec->index; sym->flags = FSECT; } sec->flags |= secflags(attr); @@ -254,17 +301,17 @@ void cleansecs(void) { Section *sec; - TUINT siz; + struct lsection *lp; - for (sec = seclist; sec; sec = sec->next) { + for (lp = seclist; lp; lp = lp->next) { + sec = &lp->s; sec->curpc = sec->pc = sec->base; if (pass == 1 || sec->flags & SFILE) continue; - siz = sec->max - sec->base; - if (siz > SIZE_MAX) + if (sec->size > SIZE_MAX) die("as: out of memory"); - sec->mem = xmalloc(sec->max - sec->base); + sec->mem = xmalloc(sec->size); } cursec = stext; } @@ -288,7 +335,7 @@ tmpsym(TUINT val) tmpalloc = alloc(sizeof(*sym), NALLOC); sym = new(tmpalloc); sym->value = val; - sym->section = NULL; + sym->section = -1; sym->flags = FABS; return sym; @@ -302,3 +349,16 @@ killtmp(void) dealloc(tmpalloc); tmpalloc = NULL; } + +int +forallsecs(int (*fn)(Section *, void *), void *arg) +{ + struct lsection *lp; + + for (lp = seclist; lp; lp = lp->next) { + if ((*fn)(&lp->s, arg) < 0) + return -1; + } + + return 0; +} diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -53,7 +53,6 @@ struct objops { int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp); }; - struct map { int n; struct mapsec {