scc

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

commit b6459c65a740c350d9088c2e383909b035790b00
parent d35d5fe22f66775de64c768ab1271430dbbf9eb5
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 15 Feb 2024 10:21:40 +0100

libmach: Remove pc from Section

The two values of pc were addede to section just
to make easier moving as to use libmach, but they
don't make too much sense to have them in the
libmach, and as we have the mechanism to store
additional data in the section of as then we can
safely remove it from libmach.

Diffstat:
Minclude/scc/scc/mach.h | 2--
Msrc/cmd/as/as.h | 1+
Msrc/cmd/as/ins.c | 8++++----
Msrc/cmd/as/symbol.c | 57+++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/cmd/as/target/powerpc/ins.c | 4++--
Msrc/cmd/as/target/x80/ins.c | 2+-
6 files changed, 51 insertions(+), 23 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -60,8 +60,6 @@ struct section { char *name; unsigned long long base; unsigned long long size; - unsigned long long curpc; - unsigned long long pc; unsigned flags; int index; diff --git a/src/cmd/as/as.h b/src/cmd/as/as.h @@ -120,6 +120,7 @@ extern int toobig(Node *, int); extern void dumpstab(char *); extern Symbol *lookup(char *); extern Symbol *deflabel(char *); +extern unsigned long long getpc(void); /* parser.c */ extern Node **getargs(char *); diff --git a/src/cmd/as/ins.c b/src/cmd/as/ins.c @@ -230,7 +230,7 @@ void align(Op *op, Node **args) { Symbol *sym = args[0]->sym; - TUINT curpc, pc, al; + TUINT pcal, pc, al; if ((sym->flags & FABS) == 0) error("align expression is not an absolute expression"); @@ -238,10 +238,10 @@ align(Op *op, Node **args) return; al--; - curpc = cursec->curpc; - pc = curpc+al & ~al; + pc = getpc(); + pcal = pc+al & ~al; - for (al = pc - curpc; al > 0; --al) + for (al = pcal - pc; al > 0; --al) emit((char []) {0}, 1); } diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c @@ -124,6 +124,7 @@ deflabel(char *name) { int local = 0; Symbol *sym; + struct lsection *lsec; char label[MAXSYM+1]; if (*name == '.') { @@ -150,7 +151,9 @@ deflabel(char *name) error("redefinition of label '%s'", name); if (cursec->flags & SABS) sym->flags |= FABS; - sym->value = cursec->curpc; + + lsec = (struct lsection *) cursec; + sym->value = lsec->curpc; sym->section = cursec->index; if (!local) @@ -183,29 +186,41 @@ toobig(Node *np, int type) } } +unsigned long long +getpc(void) +{ + struct lsection *lsec; + + lsec = (struct lsection *) cursec; + return lsec->curpc; +} + static void incpc(int nbytes) { + struct lsection *lsec; unsigned long long siz; TUINT pc, curpc; - pc = cursec->pc; - curpc = cursec->curpc; + lsec = (struct lsection *) cursec; - cursec->curpc += nbytes; - cursec->pc += nbytes; + pc = lsec->pc; + curpc = lsec->curpc; + + lsec->curpc += nbytes; + lsec->pc += nbytes; if (pass == 2) return; - siz =cursec->pc - cursec->base; + siz = lsec->pc - cursec->base; if (siz > cursec->size) cursec->size = siz; - if (pc > cursec->pc || - curpc > cursec->curpc || - cursec->curpc > maxaddr || - cursec->pc > maxaddr) { + if (pc > lsec->pc || + curpc > lsec->curpc || + lsec->curpc > maxaddr || + lsec->pc > maxaddr) { die("as: address overflow in section '%s'"); } } @@ -252,14 +267,20 @@ newsect(Symbol *sym) struct lsymbol *lsym; static int index; + if (setmap(map, sym->name, NULL, 0, 0, 0) < 0) { + perror("as"); + exit(EXIT_FAILURE); + } + lsec = xmalloc(sizeof(*lsec)); + lsec->pc = lsec->curpc = 0; lsec->next = seclist; lsec->fp = NULL; seclist = lsec; sec = &lsec->sec; sec->name = sym->name; - sec->base = sec->size = sec->pc = sec->curpc = 0; + sec->base = sec->size = 0; sec->flags = 0; sec->fill = 0; sec->align = 0; @@ -314,17 +335,25 @@ isecs(void) void cleansecs(void) { + int r; Section *sec; struct lsection *lsec; for (lsec = seclist; lsec; lsec = lsec->next) { sec = &lsec->sec; - sec->curpc = sec->pc = sec->base; + lsec->curpc = lsec->pc = sec->base; if (pass == 1 || (sec->flags & SALLOC) == 0) continue; - if ((lsec->fp = tmpfile()) == NULL) { - perror("as"); + lsec->fp = tmpfile(); + r = setmap(map, + sec->name, + lsec->fp, + sec->base, + sec->size, 0); + + if (!lsec->fp || r < 0) { + perror("as: creating section mapping"); exit(EXIT_FAILURE); } } diff --git a/src/cmd/as/target/powerpc/ins.c b/src/cmd/as/target/powerpc/ins.c @@ -156,7 +156,7 @@ i_form(Op *op, Node **args) if (dst & 0x3) error("unaligned branch"); if (aa) - dst -= cursec->curpc - 4; + dst -= getpc() - 4; if (dst < min || dst > max) error("out of range branch"); @@ -185,7 +185,7 @@ b_form(Op *op, Node **args) if (dst & 0x3) error("unaligned branch"); if (aa) - dst -= cursec->curpc - 4; + dst -= getpc() - 4; if (dst < min || dst > max) error("out of range branch"); diff --git a/src/cmd/as/target/x80/ins.c b/src/cmd/as/target/x80/ins.c @@ -568,7 +568,7 @@ branch(int relative, Op *op, Node **args) if (!relative) buf[--i] = val >> 8; else - val -= cursec->curpc - 2; + val -= getpc() - 2; buf[--i] = val; }