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