1 #include "l.h"
2
3 void
readundefs(char * f,int t)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
undefsym(Sym * s)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
zerosig(char * sp)60 zerosig(char *sp)
61 {
62 Sym *s;
63
64 s = lookup(sp, 0);
65 s->sig = 0;
66 }
67
68 void
import(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
ckoff(Sym * s,long v)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*
newdata(Sym * s,int o,int w,int t)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
export(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 }
204