Home
as: Align symbol and section with mach.h - scc - simple c99 compiler HTML git clone git://git.simple-cc.org/scc DIR Log DIR Files DIR Refs DIR Submodules DIR README DIR LICENSE --- DIR commit 7b484ddf2a8546ce55949d81cb177bbef416dcff DIR parent 70b4d78d91cd330d951b919534c0da553489be55 HTML 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: M include/scc/scc/mach.h | 11 +++++++++++ M src/cmd/as/as.h | 47 ++++++++++++++++--------------- M src/cmd/as/binfmt.c | 24 +++++++++++++++++------- M src/cmd/as/ins.c | 2 +- M src/cmd/as/symbol.c | 154 +++++++++++++++++++++---------- M src/libmach/libmach.h | 1 - 6 files changed, 160 insertions(+), 79 deletions(-) --- DIR 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); DIR 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; DIR 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; DIR 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; } } DIR 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; +} DIR 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 {