1 #include "lib9.h"
2 #include "isa.h"
3 #include "interp.h"
4 #include "runt.h"
5 #include "loadermod.h"
6 #include "raise.h"
7 #include <kernel.h>
8
9 static uchar Instmap[] = Loader_Inst_map;
10 static Type* Tinst;
11 static uchar Tdescmap[] = Loader_Typedesc_map;
12 static Type* Tdesc;
13 static uchar Tlinkmap[] = Loader_Link_map;
14 static Type* Tlink;
15
16 void
loadermodinit(void)17 loadermodinit(void)
18 {
19 sysinit();
20 builtinmod("$Loader", Loadermodtab, Loadermodlen);
21 Tinst = dtype(freeheap, sizeof(Loader_Inst), Instmap, sizeof(Instmap));
22 Tdesc = dtype(freeheap, sizeof(Loader_Typedesc), Tdescmap, sizeof(Tdescmap));
23 Tlink = dtype(freeheap, sizeof(Loader_Link), Tlinkmap, sizeof(Tlinkmap));
24 }
25
26 static void
brunpatch(Loader_Inst * ip,Module * m)27 brunpatch(Loader_Inst *ip, Module *m)
28 {
29 switch(ip->op) {
30 case ICALL:
31 case IJMP:
32 case IBEQW:
33 case IBNEW:
34 case IBLTW:
35 case IBLEW:
36 case IBGTW:
37 case IBGEW:
38 case IBEQB:
39 case IBNEB:
40 case IBLTB:
41 case IBLEB:
42 case IBGTB:
43 case IBGEB:
44 case IBEQF:
45 case IBNEF:
46 case IBLTF:
47 case IBLEF:
48 case IBGTF:
49 case IBGEF:
50 case IBEQC:
51 case IBNEC:
52 case IBLTC:
53 case IBLEC:
54 case IBGTC:
55 case IBGEC:
56 case IBEQL:
57 case IBNEL:
58 case IBLTL:
59 case IBLEL:
60 case IBGTL:
61 case IBGEL:
62 case ISPAWN:
63 ip->dst = (Inst*)ip->dst - m->prog;
64 break;
65 }
66 }
67
68 void
Loader_ifetch(void * a)69 Loader_ifetch(void *a)
70 {
71 Heap *h;
72 Array *ar;
73 Module *m;
74 Inst *i, *ie;
75 Loader_Inst *li;
76 F_Loader_ifetch *f;
77
78 f = a;
79 destroy(*f->ret);
80 *f->ret = H;
81
82 if(f->mp == H)
83 return;
84 m = f->mp->m;
85 if(m == H)
86 return;
87 if(m->compiled) {
88 kwerrstr("compiled module");
89 return;
90 }
91
92 h = nheap(sizeof(Array)+m->nprog*sizeof(Loader_Inst));
93 h->t = &Tarray;
94 h->t->ref++;
95 ar = H2D(Array*, h);
96 ar->t = Tinst;
97 Tinst->ref++;
98 ar->len = m->nprog;
99 ar->root = H;
100 ar->data = (uchar*)ar+sizeof(Array);
101
102 li = (Loader_Inst*)ar->data;
103 i = m->prog;
104 ie = i + m->nprog;
105 while(i < ie) {
106 li->op = i->op;
107 li->addr = i->add;
108 li->src = i->s.imm;
109 li->dst = i->d.imm;
110 li->mid = i->reg;
111 if(UDST(i->add) == AIMM)
112 brunpatch(li, m);
113 li++;
114 i++;
115 }
116
117 *f->ret = ar;
118 }
119
120 void
Loader_link(void * a)121 Loader_link(void *a)
122 {
123 Link *p;
124 Heap *h;
125 Type **t;
126 int nlink;
127 Module *m;
128 Array *ar;
129 Loader_Link *ll;
130 F_Loader_link *f;
131
132 f = a;
133 destroy(*f->ret);
134 *f->ret = H;
135
136 if(f->mp == H)
137 return;
138 m = f->mp->m;
139 if(m == H)
140 return;
141
142 nlink = 0;
143 for(p = m->ext; p->name; p++)
144 nlink++;
145
146 h = nheap(sizeof(Array)+nlink*sizeof(Loader_Link));
147 h->t = &Tarray;
148 h->t->ref++;
149 ar = H2D(Array*, h);
150 ar->t = Tlink;
151 Tlink->ref++;
152 ar->len = nlink;
153 ar->root = H;
154 ar->data = (uchar*)ar+sizeof(Array);
155
156 ll = (Loader_Link*)ar->data + nlink;
157 for(p = m->ext; p->name; p++) {
158 ll--;
159 ll->name = c2string(p->name, strlen(p->name));
160 ll->sig = p->sig;
161 if(m->prog == nil) {
162 ll->pc = -1;
163 ll->tdesc = -1;
164 } else {
165 ll->pc = p->u.pc - m->prog;
166 ll->tdesc = 0;
167 for(t = m->type; *t != p->frame; t++)
168 ll->tdesc++;
169 }
170 }
171
172 *f->ret = ar;
173 }
174
175 void
Loader_tdesc(void * a)176 Loader_tdesc(void *a)
177 {
178 int i;
179 Heap *h;
180 Type *t;
181 Array *ar;
182 Module *m;
183 F_Loader_tdesc *f;
184 Loader_Typedesc *lt;
185
186 f = a;
187 destroy(*f->ret);
188 *f->ret = H;
189
190 if(f->mp == H)
191 return;
192 m = f->mp->m;
193 if(m == H)
194 return;
195
196 h = nheap(sizeof(Array)+m->ntype*sizeof(Loader_Typedesc));
197 h->t = &Tarray;
198 h->t->ref++;
199 ar = H2D(Array*, h);
200 ar->t = Tdesc;
201 Tdesc->ref++;
202 ar->len = m->ntype;
203 ar->root = H;
204 ar->data = (uchar*)ar+sizeof(Array);
205
206 lt = (Loader_Typedesc*)ar->data;
207 for(i = 0; i < m->ntype; i++) {
208 t = m->type[i];
209 lt->size = t->size;
210 lt->map = H;
211 if(t->np != 0)
212 lt->map = mem2array(t->map, t->np);
213 lt++;
214 }
215
216 *f->ret = ar;
217 }
218
219 void
Loader_newmod(void * a)220 Loader_newmod(void *a)
221 {
222 Heap *h;
223 Module *m;
224 Array *ia;
225 Modlink *ml;
226 Inst *i, *ie;
227 Loader_Inst *li;
228 F_Loader_newmod *f;
229
230 f = a;
231 destroy(*f->ret);
232 *f->ret = H;
233
234 if(f->inst == H || f->data == H) {
235 kwerrstr("nil parameters");
236 return;
237 }
238 if(f->nlink < 0) {
239 kwerrstr("bad nlink");
240 return;
241 }
242
243 m = malloc(sizeof(Module));
244 if(m == nil) {
245 kwerrstr(exNomem);
246 return;
247 }
248 m->origmp = H;
249 m->ref = 1;
250 m->ss = f->ss;
251 m->name = strdup(string2c(f->name));
252 m->path = strdup(m->name);
253 m->ntype = 1;
254 m->type = malloc(sizeof(Type*));
255 if(m->name == nil || m->path == nil || m->type == nil) {
256 kwerrstr(exNomem);
257 goto bad;
258 }
259 m->origmp = (uchar*)f->data;
260 h = D2H(f->data);
261 h->ref++;
262 Setmark(h);
263 m->type[0] = h->t;
264 h->t->ref++;
265
266 ia = f->inst;
267 m->nprog = ia->len;
268 m->prog = malloc(m->nprog*sizeof(Inst));
269 if(m->prog == nil)
270 goto bad;
271 i = m->prog;
272 ie = i + m->nprog;
273 li = (Loader_Inst*)ia->data;
274 while(i < ie) {
275 i->op = li->op;
276 i->add = li->addr;
277 i->reg = li->mid;
278 i->s.imm = li->src;
279 i->d.imm = li->dst;
280 if(brpatch(i, m) == 0) {
281 kwerrstr("bad branch addr");
282 goto bad;
283 }
284 i++;
285 li++;
286 }
287 m->entryt = nil;
288 m->entry = m->prog;
289
290 ml = mklinkmod(m, f->nlink);
291 ml->MP = m->origmp;
292 m->origmp = H;
293 m->pctab = nil;
294 *f->ret = ml;
295 return;
296 bad:
297 destroy(m->origmp);
298 freemod(m);
299 }
300
301 void
Loader_tnew(void * a)302 Loader_tnew(void *a)
303 {
304 int mem;
305 Module *m;
306 Type *t, **nt;
307 Array *ar, az;
308 F_Loader_tnew *f;
309
310 f = a;
311 *f->ret = -1;
312 if(f->mp == H)
313 return;
314 m = f->mp->m;
315 if(m == H)
316 return;
317 if(m->origmp != H){
318 kwerrstr("need newmod");
319 return;
320 }
321
322 ar = f->map;
323 if(ar == H) {
324 ar = &az;
325 ar->len = 0;
326 ar->data = nil;
327 }
328
329 t = dtype(freeheap, f->size, ar->data, ar->len);
330 if(t == nil)
331 return;
332
333 mem = (m->ntype+1)*sizeof(Type*);
334 if(msize(m->type) > mem) {
335 *f->ret = m->ntype;
336 m->type[m->ntype++] = t;
337 return;
338 }
339 nt = realloc(m->type, mem);
340 if(nt == nil) {
341 kwerrstr(exNomem);
342 return;
343 }
344 m->type = nt;
345 f->mp->type = nt;
346 *f->ret = m->ntype;
347 m->type[m->ntype++] = t;
348 }
349
350 void
Loader_ext(void * a)351 Loader_ext(void *a)
352 {
353 Modl *l;
354 Module *m;
355 Modlink *ml;
356 F_Loader_ext *f;
357
358 f = a;
359 *f->ret = -1;
360 if(f->mp == H) {
361 kwerrstr("nil mp");
362 return;
363 }
364 ml = f->mp;
365 m = ml->m;
366 if(f->tdesc < 0 || f->tdesc >= m->ntype) {
367 kwerrstr("bad tdesc");
368 return;
369 }
370 if(f->pc < 0 || f->pc >= m->nprog) {
371 kwerrstr("bad pc");
372 return;
373 }
374 if(f->idx < 0 || f->idx >= ml->nlinks) {
375 kwerrstr("bad idx");
376 return;
377 }
378 l = &ml->links[f->idx];
379 l->u.pc = m->prog + f->pc;
380 l->frame = m->type[f->tdesc];
381 *f->ret = 0;
382 }
383
384 void
Loader_dnew(void * a)385 Loader_dnew(void *a)
386 {
387 F_Loader_dnew *f;
388 Heap *h;
389 Array *ar, az;
390 Type *t;
391
392 f = a;
393 *f->ret = H;
394 if(f->map == H)
395 return;
396 ar = f->map;
397 if(ar == H) {
398 ar = &az;
399 ar->len = 0;
400 ar->data = nil;
401 }
402 t = dtype(freeheap, f->size, ar->data, ar->len);
403 if(t == nil) {
404 kwerrstr(exNomem);
405 return;
406 }
407
408 h=heapz(t);
409 if(h == nil) {
410 freetype(t);
411 kwerrstr(exNomem);
412 return;
413 }
414
415 *f->ret=H2D(Loader_Niladt*, h);
416 }
417
418 void
Loader_compile(void * a)419 Loader_compile(void *a)
420 {
421 Module *m;
422 F_Loader_compile *f;
423
424 f = a;
425 *f->ret = -1;
426 if(f->mp == H) {
427 kwerrstr("nil mp");
428 return;
429 }
430 m = f->mp->m;
431 if(m->compiled) {
432 kwerrstr("compiled module");
433 return;
434 }
435 *f->ret = 0;
436 m->origmp = f->mp->MP;
437 if(cflag || f->flag)
438 if(compile(m, m->nprog, f->mp)) {
439 f->mp->prog = m->prog;
440 f->mp->compiled = 1;
441 } else
442 *f->ret = -1;
443 m->origmp = H;
444 }
445