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+}