]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/7l/mod.c
merge
[plan9front.git] / sys / src / cmd / 7l / mod.c
1 #include        "l.h"
2
3 void
4 readundefs(char *f, int t)
5 {
6         int i, n;
7         Sym *s;
8         Biobuf *b;
9         char *l, buf[256], *fields[64];
10
11         if(f == nil)
12                 return;
13         b = Bopen(f, OREAD);
14         if(b == nil){
15                 diag("could not open %s: %r", f);
16                 errorexit();
17         }
18         while((l = Brdline(b, '\n')) != nil){
19                 n = Blinelen(b);
20                 if(n >= sizeof(buf)){
21                         diag("%s: line too long", f);
22                         errorexit();
23                 }
24                 memmove(buf, l, n);
25                 buf[n-1] = '\0';
26                 n = getfields(buf, fields, nelem(fields), 1, " \t\r\n");
27                 if(n == nelem(fields)){
28                         diag("%s: bad format", f);
29                         errorexit();
30                 }
31                 for(i = 0; i < n; i++){
32                         s = lookup(fields[i], 0);
33                         s->type = SXREF;
34                         s->subtype = t;
35                         if(t == SIMPORT)
36                                 nimports++;
37                         else
38                                 nexports++;
39                 }
40         }
41         Bterm(b);
42 }
43
44 void
45 undefsym(Sym *s)
46 {
47         int n;
48
49         n = imports;
50         if(s->value != 0)
51                 diag("value != 0 on SXREF");
52         if(n >= 1<<Rindex)
53                 diag("import index %d out of range", n);
54         s->value = n<<Roffset;
55         s->type = SUNDEF;
56         imports++;
57 }
58
59 void
60 zerosig(char *sp)
61 {
62         Sym *s;
63
64         s = lookup(sp, 0);
65         s->sig = 0;
66 }
67
68 void
69 import(void)
70 {
71         int i;
72         Sym *s;
73
74         for(i = 0; i < NHASH; i++)
75                 for(s = hash[i]; s != S; s = s->link)
76                         if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
77                                 undefsym(s);
78                                 Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, (vlong)s->value);
79                         }
80 }
81
82 void
83 ckoff(Sym *s, long v)
84 {
85         if(v < 0 || v >= 1<<Roffset)
86                 diag("relocation offset %ld for %s out of range", v, s->name);
87 }
88
89 static Prog*
90 newdata(Sym *s, int o, int w, int t)
91 {
92         Prog *p;
93
94         p = prg();
95         p->link = datap;
96         datap = p;
97         p->as = ADATA;
98         p->reg = w;
99         p->from.type = D_OREG;
100         p->from.name = t;
101         p->from.sym = s;
102         p->from.offset = o;
103         p->to.type = D_CONST;
104         p->to.name = D_NONE;
105         return p;
106 }
107
108 void
109 export(void)
110 {
111         int i, j, n, off, nb, sv, ne;
112         Sym *s, *et, *str, **esyms;
113         Prog *p;
114         char buf[NSNAME], *t;
115
116         n = 0;
117         for(i = 0; i < NHASH; i++)
118                 for(s = hash[i]; s != S; s = s->link)
119                         if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
120                                 n++;
121         esyms = malloc(n*sizeof(Sym*));
122         ne = n;
123         n = 0;
124         for(i = 0; i < NHASH; i++)
125                 for(s = hash[i]; s != S; s = s->link)
126                         if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
127                                 esyms[n++] = s;
128         for(i = 0; i < ne-1; i++)
129                 for(j = i+1; j < ne; j++)
130                         if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
131                                 s = esyms[i];
132                                 esyms[i] = esyms[j];
133                                 esyms[j] = s;
134                         }
135
136         nb = 0;
137         off = 0;
138         et = lookup(EXPTAB, 0);
139         if(et->type != 0 && et->type != SXREF)
140                 diag("%s already defined", EXPTAB);
141         et->type = SDATA;
142         str = lookup(".string", 0);
143         if(str->type == 0)
144                 str->type = SDATA;
145         sv = str->value;
146         for(i = 0; i < ne; i++){
147                 s = esyms[i];
148                 Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
149
150                 /* signature */
151                 p = newdata(et, off, sizeof(long), D_EXTERN);
152                 off += sizeof(long);
153                 p->to.offset = s->sig;
154
155                 /* address */
156                 p = newdata(et, off, sizeof(long), D_EXTERN);
157                 off += sizeof(long);
158                 p->to.name = D_EXTERN;
159                 p->to.sym = s;
160
161                 /* string */
162                 t = s->name;
163                 n = strlen(t)+1;
164                 for(;;){
165                         buf[nb++] = *t;
166                         sv++;
167                         if(nb >= NSNAME){
168                                 p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
169                                 p->to.type = D_SCONST;
170                                 p->to.sval = malloc(NSNAME);
171                                 memmove(p->to.sval, buf, NSNAME);
172                                 nb = 0;
173                         }
174                         if(*t++ == 0)
175                                 break;
176                 }
177
178                 /* name */
179                 p = newdata(et, off, sizeof(long), D_EXTERN);
180                 off += sizeof(long);
181                 p->to.name = D_STATIC;
182                 p->to.sym = str;
183                 p->to.offset = sv-n;
184         }
185
186         if(nb > 0){
187                 p = newdata(str, sv-nb, nb, D_STATIC);
188                 p->to.type = D_SCONST;
189                 p->to.sval = malloc(NSNAME);
190                 memmove(p->to.sval, buf, nb);
191         }
192
193         for(i = 0; i < 3; i++){
194                 newdata(et, off, sizeof(long), D_EXTERN);
195                 off += sizeof(long);
196         }
197         et->value = off;
198         if(sv == 0)
199                 sv = 1;
200         str->value = sv;
201         exports = ne;
202         free(esyms);
203 }