ref: 9fbc6a472de910787bc0ba27ceac576392b46045
parent: 8de2cd4ed1cc4193a4db1c7aad83133dea693f96
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Dec 15 16:59:18 EST 2017
[as] Rework section layer There were several problems with the section layer and this patch unifies sections and symbols, making easier to handle them.
--- a/as/as.h
+++ b/as/as.h
@@ -9,6 +9,8 @@
FUNDEF = 1 << 3,
FDEDUP = 1 << 4,
FRELOC = 1 << 5,
+ FSECT = 1 << 6,
+ FNTYPE = 1 << 7,
};
enum secflags {
@@ -99,7 +101,7 @@
};
struct section {
- String name;
+ Symbol *sym;
char *mem;
unsigned char flags;
unsigned char fill;
@@ -132,9 +134,10 @@
};
/* symbol.c */
-extern void isections(void);
+extern void cleansecs(void);
+extern void isecs(void);
extern void emit(char *bytes, int nbytes);
-extern Section *setsection(char *name);
+extern Section *setsec(char *name, char *attr);
extern Symbol *tmpsym(TUINT val);
extern void killtmp(void);
extern int toobig(Node *np, int type);
@@ -142,7 +145,7 @@
extern String newstring(char *s);
/* main.c */
-extern Symbol *lookup(char *name, int type);
+extern Symbol *lookup(char *name);
extern Symbol *deflabel(char *name);
/* parser.c */
--- a/as/expr.c
+++ b/as/expr.c
@@ -200,7 +200,7 @@
}
tok2str();
- yylval.sym = lookup(yytext, FUNDEF);
+ yylval.sym = lookup(yytext);
return IDEN;
}
@@ -267,9 +267,9 @@
while (isalnum(c = *endp))
++endp;
tok2str();
- yylval.sym = lookup(yytext, FREG);
- if (!yylval.sym->argtype)
- error("incorrect register name");
+ yylval.sym = lookup(yytext);
+ if ((yylval.sym->flags & FREG) == 0)
+ error("incorrect register name '%s'", yytext);
return REG;
}
--- a/as/ins.c
+++ b/as/ins.c
@@ -3,6 +3,8 @@
#include "../inc/scc.h"
#include "as.h"
+extern Section *sabs, *sbss, *sdata, *stext;
+
char *
tobytes(TUINT v, int nbytes, int inc)
{
@@ -79,23 +81,23 @@
{
Symbol *sym = args[0]->sym;
- setsection(sym->name.buf);
+ setsec(sym->name.buf, NULL);
}
void
text(Op *op, Node **args)
{
- setsection("text");
+ cursec = stext;
}
void
data(Op *op, Node **args)
{
- setsection("data");
+ cursec = sdata;
}
void
bss(Op *op, Node **args)
{
- setsection("bss");
+ cursec = sbss;
}
--- a/as/main.c
+++ b/as/main.c
@@ -75,7 +75,7 @@
if ((fp = fopen(fname, "r")) == NULL)
die("as: error opening '%s'", fname);
- isections();
+ cleansecs();
setjmp(recover);
while (nextline(fp, &line)) {
@@ -128,6 +128,7 @@
atexit(cleanup);
iarch();
+ isecs();
for (pass = 1; pass <= 2; pass++) {
if (!dopass(infile))
return 1;
--- a/as/myro.c
+++ b/as/myro.c
@@ -35,14 +35,6 @@
off += len;
}
- for (sp = seclist; sp; sp = sp->next) {
- str = &sp->name;
- len = strlen(str->buf) + 1;
- fwrite(str->buf, len, 1, fp);
- str->offset = off;
- off += len;
- }
-
return off;
}
@@ -78,7 +70,7 @@
if (id == MYROMAXSEC)
die("too many sections for a myro file");
sp->id = id++;
- sect.name = sp->name.offset;
+ sect.name = sp->sym->name.offset;
sect.flags = getsecflags(sp);
sect.fill = sp->fill;
sect.aligment = sp->aligment;
@@ -114,7 +106,7 @@
struct myrosym symbol;
for (sym = symlist; sym; sym = sym->next) {
- if (sym->flags & FREG)
+ if (sym->flags & (FREG|FSECT))
continue;
symbol.name = sym->name.offset;
symbol.type = -1;
--- a/as/symbol.c
+++ b/as/symbol.c
@@ -11,37 +11,14 @@
#define HASHSIZ 64
#define NALLOC 10
-static Section abss = {
- .name = (String) {"abs"},
- .flags = SABS|SREAD|SWRITE|SFILE|SLOAD,
-};
-
-static Section bss = {
- .name = (String) {"bss"},
- .flags = SREAD|SWRITE|SLOAD,
- .next = &abss,
-};
-
-static Section data = {
- .name = (String) {"data"},
- .flags = SREAD|SWRITE|SFILE|SLOAD,
- .next = &bss,
-};
-
-static Section text = {
- .name = (String) {"text"},
- .flags = SREAD|SEXEC|SLOAD|SFILE,
- .next = &data,
-};
-
-Section *cursec = &text, *seclist = &text;
-
+Section *cursec, *seclist;
+Section *sabs, *sbss, *sdata, *stext;
+Symbol *linesym, *symlist;
int pass;
-static Symbol *hashtbl[HASHSIZ];
+static Symbol *hashtbl[HASHSIZ], *symlast;
static Alloc *tmpalloc;
-Symbol *linesym, *symlist, *symlast;
#ifndef NDEBUG
void
@@ -65,7 +42,7 @@
#endif
Symbol *
-lookup(char *name, int type)
+lookup(char *name)
{
unsigned h;
Symbol *sym, **list;
@@ -81,17 +58,13 @@
list = &hashtbl[h];
for (sym = *list; sym; sym = sym->hash) {
t = sym->name.buf;
- if (c != toupper(*t) || casecmp(t, name))
- continue;
- symtype = sym->flags;
- if (((symtype | type) & FUNDEF) == 0 && symtype != type)
- continue;
- return sym;
+ if (c == toupper(*t) && !casecmp(t, name))
+ return sym;
}
sym = xmalloc(sizeof(*sym));
sym->name = newstring(name);
- sym->flags = FRELOC | FUNDEF | type;
+ sym->flags = FRELOC | FUNDEF | FNTYPE;
sym->value = 0;
sym->section = cursec;
sym->hash = *list;
@@ -132,7 +105,7 @@
name = label;
}
- sym = lookup(name, FUNDEF);
+ sym = lookup(name);
if (pass == 1 && (sym->flags & FUNDEF) == 0)
error("redefinition of label '%s'", name);
if (cursec->flags & SABS)
@@ -139,6 +112,7 @@
sym->flags &= ~FRELOC;
sym->flags &= ~FUNDEF;
sym->value = cursec->curpc;
+ sym->section = cursec;
if (*name != '.')
cursym = sym;
@@ -177,50 +151,97 @@
}
}
-
-static void
-isect(Section *sec)
+static int
+secflags(char *attr)
{
- TUINT siz;
+ int c, flags;
- sec->curpc = sec->pc = sec->base;
- if (pass == 1 || !(sec->flags & SFILE))
- return;
+ if (!attr)
+ return 0;
- siz = sec->max - sec->base;
- if (siz > SIZE_MAX)
- die("out of memory");
- sec->mem = xmalloc(sec->max - sec->base);
+ for (flags = 0; c = *attr++; ) {
+ switch (c) {
+ case 'w':
+ flags |= SWRITE;
+ break;
+ case 'r':
+ flags |= SREAD;
+ break;
+ case 'x':
+ flags |= SEXEC;
+ break;
+ case 'f':
+ flags |= SFILE;
+ break;
+ case 'l':
+ flags |= SLOAD;
+ break;
+ case 'a':
+ flags |= SABS;
+ break;
+ }
+ }
+
+ return flags;
}
Section *
-setsection(char *name)
+setsec(char *name, char *attr)
{
Section *sec;
+ Symbol *sym;
+ int flags;
- for (sec = seclist; sec; sec = sec->next) {
- if (!strcmp(sec->name.buf, name))
- break;
- }
- if (!sec) {
+ cursec = NULL;
+ sym = lookup(name);
+ if ((sym->flags & (FNTYPE | FSECT)) == 0)
+ error("invalid section name '%s'", name);
+
+ if ((sec = sym->section) == NULL) {
sec = xmalloc(sizeof(*sec));
- sec->name = newstring(name);
+ 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;
+ sym->flags = FSECT;
}
+ sec->flags |= secflags(attr);
+
return cursec = sec;
}
void
-isections(void)
+isecs(void)
{
+ sabs = setsec(".abs", "rwxafl");
+ sbss = setsec(".bss", "rwl");
+ sdata = setsec(".data", "rwfl");
+ stext = setsec(".text", "rxfl");
+}
+
+void
+cleansecs(void)
+{
Section *sec;
+ TUINT siz;
- for (sec = seclist; sec; sec = sec->next)
- isect(sec);
+ for (sec = seclist; sec; sec = sec->next) {
+ sec->curpc = sec->pc = sec->base;
+ if (pass == 1 || !(sec->flags & SFILE))
+ continue;
+
+ siz = sec->max - sec->base;
+ if (siz > SIZE_MAX)
+ die("out of memory");
+ sec->mem = xmalloc(sec->max - sec->base);
+ }
+ cursec = stext;
}
void
--- a/as/target/i386/proc.c
+++ b/as/target/i386/proc.c
@@ -92,7 +92,8 @@
}, *bp;
for (bp = regs; bp->name; ++bp) {
- Symbol *sym = lookup(bp->name, FREG);
+ Symbol *sym = lookup(bp->name);
+ sym->flags = FREG;
sym->argtype = bp->type;
}
}
--- a/as/target/z80/proc.c
+++ b/as/target/z80/proc.c
@@ -45,7 +45,8 @@
}, *bp;
for (bp = regs; bp->name; ++bp) {
- Symbol *sym = lookup(bp->name, FREG);
+ Symbol *sym = lookup(bp->name);
+ sym->flags = FREG;
sym->argtype = bp->type;
}
}