changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/7l/mod.c

revision 7144: d0b9ab522e8b
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/cmd/7l/mod.c
     1.4@@ -0,0 +1,203 @@
     1.5+#include	"l.h"
     1.6+
     1.7+void
     1.8+readundefs(char *f, int t)
     1.9+{
    1.10+	int i, n;
    1.11+	Sym *s;
    1.12+	Biobuf *b;
    1.13+	char *l, buf[256], *fields[64];
    1.14+
    1.15+	if(f == nil)
    1.16+		return;
    1.17+	b = Bopen(f, OREAD);
    1.18+	if(b == nil){
    1.19+		diag("could not open %s: %r", f);
    1.20+		errorexit();
    1.21+	}
    1.22+	while((l = Brdline(b, '\n')) != nil){
    1.23+		n = Blinelen(b);
    1.24+		if(n >= sizeof(buf)){
    1.25+			diag("%s: line too long", f);
    1.26+			errorexit();
    1.27+		}
    1.28+		memmove(buf, l, n);
    1.29+		buf[n-1] = '\0';
    1.30+		n = getfields(buf, fields, nelem(fields), 1, " \t\r\n");
    1.31+		if(n == nelem(fields)){
    1.32+			diag("%s: bad format", f);
    1.33+			errorexit();
    1.34+		}
    1.35+		for(i = 0; i < n; i++){
    1.36+			s = lookup(fields[i], 0);
    1.37+			s->type = SXREF;
    1.38+			s->subtype = t;
    1.39+			if(t == SIMPORT)
    1.40+				nimports++;
    1.41+			else
    1.42+				nexports++;
    1.43+		}
    1.44+	}
    1.45+	Bterm(b);
    1.46+}
    1.47+
    1.48+void
    1.49+undefsym(Sym *s)
    1.50+{
    1.51+	int n;
    1.52+
    1.53+	n = imports;
    1.54+	if(s->value != 0)
    1.55+		diag("value != 0 on SXREF");
    1.56+	if(n >= 1<<Rindex)
    1.57+		diag("import index %d out of range", n);
    1.58+	s->value = n<<Roffset;
    1.59+	s->type = SUNDEF;
    1.60+	imports++;
    1.61+}
    1.62+
    1.63+void
    1.64+zerosig(char *sp)
    1.65+{
    1.66+	Sym *s;
    1.67+
    1.68+	s = lookup(sp, 0);
    1.69+	s->sig = 0;
    1.70+}
    1.71+
    1.72+void
    1.73+import(void)
    1.74+{
    1.75+	int i;
    1.76+	Sym *s;
    1.77+
    1.78+	for(i = 0; i < NHASH; i++)
    1.79+		for(s = hash[i]; s != S; s = s->link)
    1.80+			if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
    1.81+				undefsym(s);
    1.82+				Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, (vlong)s->value);
    1.83+			}
    1.84+}
    1.85+
    1.86+void
    1.87+ckoff(Sym *s, long v)
    1.88+{
    1.89+	if(v < 0 || v >= 1<<Roffset)
    1.90+		diag("relocation offset %ld for %s out of range", v, s->name);
    1.91+}
    1.92+
    1.93+static Prog*
    1.94+newdata(Sym *s, int o, int w, int t)
    1.95+{
    1.96+	Prog *p;
    1.97+
    1.98+	p = prg();
    1.99+	p->link = datap;
   1.100+	datap = p;
   1.101+	p->as = ADATA;
   1.102+	p->reg = w;
   1.103+	p->from.type = D_OREG;
   1.104+	p->from.name = t;
   1.105+	p->from.sym = s;
   1.106+	p->from.offset = o;
   1.107+	p->to.type = D_CONST;
   1.108+	p->to.name = D_NONE;
   1.109+	return p;
   1.110+}
   1.111+
   1.112+void
   1.113+export(void)
   1.114+{
   1.115+	int i, j, n, off, nb, sv, ne;
   1.116+	Sym *s, *et, *str, **esyms;
   1.117+	Prog *p;
   1.118+	char buf[NSNAME], *t;
   1.119+
   1.120+	n = 0;
   1.121+	for(i = 0; i < NHASH; i++)
   1.122+		for(s = hash[i]; s != S; s = s->link)
   1.123+			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
   1.124+				n++;
   1.125+	esyms = malloc(n*sizeof(Sym*));
   1.126+	ne = n;
   1.127+	n = 0;
   1.128+	for(i = 0; i < NHASH; i++)
   1.129+		for(s = hash[i]; s != S; s = s->link)
   1.130+			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
   1.131+				esyms[n++] = s;
   1.132+	for(i = 0; i < ne-1; i++)
   1.133+		for(j = i+1; j < ne; j++)
   1.134+			if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
   1.135+				s = esyms[i];
   1.136+				esyms[i] = esyms[j];
   1.137+				esyms[j] = s;
   1.138+			}
   1.139+
   1.140+	nb = 0;
   1.141+	off = 0;
   1.142+	et = lookup(EXPTAB, 0);
   1.143+	if(et->type != 0 && et->type != SXREF)
   1.144+		diag("%s already defined", EXPTAB);
   1.145+	et->type = SDATA;
   1.146+	str = lookup(".string", 0);
   1.147+	if(str->type == 0)
   1.148+		str->type = SDATA;
   1.149+	sv = str->value;
   1.150+	for(i = 0; i < ne; i++){
   1.151+		s = esyms[i];
   1.152+		Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
   1.153+
   1.154+		/* signature */
   1.155+		p = newdata(et, off, sizeof(long), D_EXTERN);
   1.156+		off += sizeof(long);
   1.157+		p->to.offset = s->sig;
   1.158+
   1.159+		/* address */
   1.160+		p = newdata(et, off, sizeof(long), D_EXTERN);
   1.161+		off += sizeof(long);
   1.162+		p->to.name = D_EXTERN;
   1.163+		p->to.sym = s;
   1.164+
   1.165+		/* string */
   1.166+		t = s->name;
   1.167+		n = strlen(t)+1;
   1.168+		for(;;){
   1.169+			buf[nb++] = *t;
   1.170+			sv++;
   1.171+			if(nb >= NSNAME){
   1.172+				p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
   1.173+				p->to.type = D_SCONST;
   1.174+				p->to.sval = malloc(NSNAME);
   1.175+				memmove(p->to.sval, buf, NSNAME);
   1.176+				nb = 0;
   1.177+			}
   1.178+			if(*t++ == 0)
   1.179+				break;
   1.180+		}
   1.181+
   1.182+		/* name */
   1.183+		p = newdata(et, off, sizeof(long), D_EXTERN);
   1.184+		off += sizeof(long);
   1.185+		p->to.name = D_STATIC;
   1.186+		p->to.sym = str;
   1.187+		p->to.offset = sv-n;
   1.188+	}
   1.189+
   1.190+	if(nb > 0){
   1.191+		p = newdata(str, sv-nb, nb, D_STATIC);
   1.192+		p->to.type = D_SCONST;
   1.193+		p->to.sval = malloc(NSNAME);
   1.194+		memmove(p->to.sval, buf, nb);
   1.195+	}
   1.196+
   1.197+	for(i = 0; i < 3; i++){
   1.198+		newdata(et, off, sizeof(long), D_EXTERN);
   1.199+		off += sizeof(long);
   1.200+	}
   1.201+	et->value = off;
   1.202+	if(sv == 0)
   1.203+		sv = 1;
   1.204+	str->value = sv;
   1.205+	exports = ne;
   1.206+	free(esyms);
   1.207+}