1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "isa.h"
3*37da2899SCharles.Forsyth #include "interp.h"
4*37da2899SCharles.Forsyth #include "raise.h"
5*37da2899SCharles.Forsyth #include <kernel.h>
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsyth #define A(r) *((Array**)(r))
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsyth Module* modules;
10*37da2899SCharles.Forsyth int dontcompile;
11*37da2899SCharles.Forsyth
12*37da2899SCharles.Forsyth static int
operand(uchar ** p)13*37da2899SCharles.Forsyth operand(uchar **p)
14*37da2899SCharles.Forsyth {
15*37da2899SCharles.Forsyth int c;
16*37da2899SCharles.Forsyth uchar *cp;
17*37da2899SCharles.Forsyth
18*37da2899SCharles.Forsyth cp = *p;
19*37da2899SCharles.Forsyth c = cp[0];
20*37da2899SCharles.Forsyth switch(c & 0xC0) {
21*37da2899SCharles.Forsyth case 0x00:
22*37da2899SCharles.Forsyth *p = cp+1;
23*37da2899SCharles.Forsyth return c;
24*37da2899SCharles.Forsyth case 0x40:
25*37da2899SCharles.Forsyth *p = cp+1;
26*37da2899SCharles.Forsyth return c|~0x7F;
27*37da2899SCharles.Forsyth case 0x80:
28*37da2899SCharles.Forsyth *p = cp+2;
29*37da2899SCharles.Forsyth if(c & 0x20)
30*37da2899SCharles.Forsyth c |= ~0x3F;
31*37da2899SCharles.Forsyth else
32*37da2899SCharles.Forsyth c &= 0x3F;
33*37da2899SCharles.Forsyth return (c<<8)|cp[1];
34*37da2899SCharles.Forsyth case 0xC0:
35*37da2899SCharles.Forsyth *p = cp+4;
36*37da2899SCharles.Forsyth if(c & 0x20)
37*37da2899SCharles.Forsyth c |= ~0x3F;
38*37da2899SCharles.Forsyth else
39*37da2899SCharles.Forsyth c &= 0x3F;
40*37da2899SCharles.Forsyth return (c<<24)|(cp[1]<<16)|(cp[2]<<8)|cp[3];
41*37da2899SCharles.Forsyth }
42*37da2899SCharles.Forsyth return 0;
43*37da2899SCharles.Forsyth }
44*37da2899SCharles.Forsyth
45*37da2899SCharles.Forsyth static ulong
disw(uchar ** p)46*37da2899SCharles.Forsyth disw(uchar **p)
47*37da2899SCharles.Forsyth {
48*37da2899SCharles.Forsyth ulong v;
49*37da2899SCharles.Forsyth uchar *c;
50*37da2899SCharles.Forsyth
51*37da2899SCharles.Forsyth c = *p;
52*37da2899SCharles.Forsyth v = c[0] << 24;
53*37da2899SCharles.Forsyth v |= c[1] << 16;
54*37da2899SCharles.Forsyth v |= c[2] << 8;
55*37da2899SCharles.Forsyth v |= c[3];
56*37da2899SCharles.Forsyth *p = c + 4;
57*37da2899SCharles.Forsyth return v;
58*37da2899SCharles.Forsyth }
59*37da2899SCharles.Forsyth
60*37da2899SCharles.Forsyth double
canontod(ulong v[2])61*37da2899SCharles.Forsyth canontod(ulong v[2])
62*37da2899SCharles.Forsyth {
63*37da2899SCharles.Forsyth union { double d; unsigned long ul[2]; } a;
64*37da2899SCharles.Forsyth a.d = 1.;
65*37da2899SCharles.Forsyth if(a.ul[0]) {
66*37da2899SCharles.Forsyth a.ul[0] = v[0];
67*37da2899SCharles.Forsyth a.ul[1] = v[1];
68*37da2899SCharles.Forsyth }
69*37da2899SCharles.Forsyth else {
70*37da2899SCharles.Forsyth a.ul[1] = v[0];
71*37da2899SCharles.Forsyth a.ul[0] = v[1];
72*37da2899SCharles.Forsyth }
73*37da2899SCharles.Forsyth return a.d;
74*37da2899SCharles.Forsyth }
75*37da2899SCharles.Forsyth
76*37da2899SCharles.Forsyth Module*
load(char * path)77*37da2899SCharles.Forsyth load(char *path)
78*37da2899SCharles.Forsyth {
79*37da2899SCharles.Forsyth return readmod(path, nil, 0);
80*37da2899SCharles.Forsyth }
81*37da2899SCharles.Forsyth
82*37da2899SCharles.Forsyth int
brpatch(Inst * ip,Module * m)83*37da2899SCharles.Forsyth brpatch(Inst *ip, Module *m)
84*37da2899SCharles.Forsyth {
85*37da2899SCharles.Forsyth switch(ip->op) {
86*37da2899SCharles.Forsyth case ICALL:
87*37da2899SCharles.Forsyth case IJMP:
88*37da2899SCharles.Forsyth case IBEQW:
89*37da2899SCharles.Forsyth case IBNEW:
90*37da2899SCharles.Forsyth case IBLTW:
91*37da2899SCharles.Forsyth case IBLEW:
92*37da2899SCharles.Forsyth case IBGTW:
93*37da2899SCharles.Forsyth case IBGEW:
94*37da2899SCharles.Forsyth case IBEQB:
95*37da2899SCharles.Forsyth case IBNEB:
96*37da2899SCharles.Forsyth case IBLTB:
97*37da2899SCharles.Forsyth case IBLEB:
98*37da2899SCharles.Forsyth case IBGTB:
99*37da2899SCharles.Forsyth case IBGEB:
100*37da2899SCharles.Forsyth case IBEQF:
101*37da2899SCharles.Forsyth case IBNEF:
102*37da2899SCharles.Forsyth case IBLTF:
103*37da2899SCharles.Forsyth case IBLEF:
104*37da2899SCharles.Forsyth case IBGTF:
105*37da2899SCharles.Forsyth case IBGEF:
106*37da2899SCharles.Forsyth case IBEQC:
107*37da2899SCharles.Forsyth case IBNEC:
108*37da2899SCharles.Forsyth case IBLTC:
109*37da2899SCharles.Forsyth case IBLEC:
110*37da2899SCharles.Forsyth case IBGTC:
111*37da2899SCharles.Forsyth case IBGEC:
112*37da2899SCharles.Forsyth case IBEQL:
113*37da2899SCharles.Forsyth case IBNEL:
114*37da2899SCharles.Forsyth case IBLTL:
115*37da2899SCharles.Forsyth case IBLEL:
116*37da2899SCharles.Forsyth case IBGTL:
117*37da2899SCharles.Forsyth case IBGEL:
118*37da2899SCharles.Forsyth case ISPAWN:
119*37da2899SCharles.Forsyth if(ip->d.imm < 0 || ip->d.imm >= m->nprog)
120*37da2899SCharles.Forsyth return 0;
121*37da2899SCharles.Forsyth ip->d.imm = (WORD)&m->prog[ip->d.imm];
122*37da2899SCharles.Forsyth break;
123*37da2899SCharles.Forsyth }
124*37da2899SCharles.Forsyth return 1;
125*37da2899SCharles.Forsyth }
126*37da2899SCharles.Forsyth
127*37da2899SCharles.Forsyth Module*
parsemod(char * path,uchar * code,ulong length,Dir * dir)128*37da2899SCharles.Forsyth parsemod(char *path, uchar *code, ulong length, Dir *dir)
129*37da2899SCharles.Forsyth {
130*37da2899SCharles.Forsyth Heap *h;
131*37da2899SCharles.Forsyth Inst *ip;
132*37da2899SCharles.Forsyth Type *pt;
133*37da2899SCharles.Forsyth String *s;
134*37da2899SCharles.Forsyth Module *m;
135*37da2899SCharles.Forsyth Array *ary;
136*37da2899SCharles.Forsyth ulong ul[2];
137*37da2899SCharles.Forsyth WORD lo, hi;
138*37da2899SCharles.Forsyth int lsize, id, v, entry, entryt, tnp, tsz, siglen;
139*37da2899SCharles.Forsyth int de, pc, i, n, isize, dsize, hsize, dasp;
140*37da2899SCharles.Forsyth uchar *mod, sm, *istream, **isp, *si, *addr, *dastack[DADEPTH];
141*37da2899SCharles.Forsyth Link *l;
142*37da2899SCharles.Forsyth
143*37da2899SCharles.Forsyth istream = code;
144*37da2899SCharles.Forsyth isp = &istream;
145*37da2899SCharles.Forsyth
146*37da2899SCharles.Forsyth m = malloc(sizeof(Module));
147*37da2899SCharles.Forsyth if(m == nil)
148*37da2899SCharles.Forsyth return nil;
149*37da2899SCharles.Forsyth
150*37da2899SCharles.Forsyth m->dev = dir->dev;
151*37da2899SCharles.Forsyth m->dtype = dir->type;
152*37da2899SCharles.Forsyth m->qid = dir->qid;
153*37da2899SCharles.Forsyth m->mtime = dir->mtime;
154*37da2899SCharles.Forsyth m->origmp = H;
155*37da2899SCharles.Forsyth m->pctab = nil;
156*37da2899SCharles.Forsyth
157*37da2899SCharles.Forsyth switch(operand(isp)) {
158*37da2899SCharles.Forsyth default:
159*37da2899SCharles.Forsyth kwerrstr("bad magic");
160*37da2899SCharles.Forsyth goto bad;
161*37da2899SCharles.Forsyth case SMAGIC:
162*37da2899SCharles.Forsyth siglen = operand(isp);
163*37da2899SCharles.Forsyth n = length-(*isp-code);
164*37da2899SCharles.Forsyth if(n < 0 || siglen > n){
165*37da2899SCharles.Forsyth kwerrstr("corrupt signature");
166*37da2899SCharles.Forsyth goto bad;
167*37da2899SCharles.Forsyth }
168*37da2899SCharles.Forsyth if(verifysigner(*isp, siglen, *isp+siglen, n-siglen) == 0) {
169*37da2899SCharles.Forsyth kwerrstr("security violation");
170*37da2899SCharles.Forsyth goto bad;
171*37da2899SCharles.Forsyth }
172*37da2899SCharles.Forsyth *isp += siglen;
173*37da2899SCharles.Forsyth break;
174*37da2899SCharles.Forsyth case XMAGIC:
175*37da2899SCharles.Forsyth if(mustbesigned(path, code, length, dir)){
176*37da2899SCharles.Forsyth kwerrstr("security violation: not signed");
177*37da2899SCharles.Forsyth goto bad;
178*37da2899SCharles.Forsyth }
179*37da2899SCharles.Forsyth break;
180*37da2899SCharles.Forsyth }
181*37da2899SCharles.Forsyth
182*37da2899SCharles.Forsyth m->rt = operand(isp);
183*37da2899SCharles.Forsyth m->ss = operand(isp);
184*37da2899SCharles.Forsyth isize = operand(isp);
185*37da2899SCharles.Forsyth dsize = operand(isp);
186*37da2899SCharles.Forsyth hsize = operand(isp);
187*37da2899SCharles.Forsyth lsize = operand(isp);
188*37da2899SCharles.Forsyth entry = operand(isp);
189*37da2899SCharles.Forsyth entryt = operand(isp);
190*37da2899SCharles.Forsyth
191*37da2899SCharles.Forsyth if(isize < 0 || dsize < 0 || hsize < 0 || lsize < 0) {
192*37da2899SCharles.Forsyth kwerrstr("implausible Dis file");
193*37da2899SCharles.Forsyth goto bad;
194*37da2899SCharles.Forsyth }
195*37da2899SCharles.Forsyth
196*37da2899SCharles.Forsyth m->nprog = isize;
197*37da2899SCharles.Forsyth m->prog = mallocz(isize*sizeof(Inst), 0);
198*37da2899SCharles.Forsyth if(m->prog == nil) {
199*37da2899SCharles.Forsyth kwerrstr(exNomem);
200*37da2899SCharles.Forsyth goto bad;
201*37da2899SCharles.Forsyth }
202*37da2899SCharles.Forsyth
203*37da2899SCharles.Forsyth m->ref = 1;
204*37da2899SCharles.Forsyth
205*37da2899SCharles.Forsyth ip = m->prog;
206*37da2899SCharles.Forsyth for(i = 0; i < isize; i++) {
207*37da2899SCharles.Forsyth ip->op = *istream++;
208*37da2899SCharles.Forsyth ip->add = *istream++;
209*37da2899SCharles.Forsyth ip->reg = 0;
210*37da2899SCharles.Forsyth ip->s.imm = 0;
211*37da2899SCharles.Forsyth ip->d.imm = 0;
212*37da2899SCharles.Forsyth switch(ip->add & ARM) {
213*37da2899SCharles.Forsyth case AXIMM:
214*37da2899SCharles.Forsyth case AXINF:
215*37da2899SCharles.Forsyth case AXINM:
216*37da2899SCharles.Forsyth ip->reg = operand(isp);
217*37da2899SCharles.Forsyth break;
218*37da2899SCharles.Forsyth }
219*37da2899SCharles.Forsyth switch(UXSRC(ip->add)) {
220*37da2899SCharles.Forsyth case SRC(AFP):
221*37da2899SCharles.Forsyth case SRC(AMP):
222*37da2899SCharles.Forsyth case SRC(AIMM):
223*37da2899SCharles.Forsyth ip->s.ind = operand(isp);
224*37da2899SCharles.Forsyth break;
225*37da2899SCharles.Forsyth case SRC(AIND|AFP):
226*37da2899SCharles.Forsyth case SRC(AIND|AMP):
227*37da2899SCharles.Forsyth ip->s.i.f = operand(isp);
228*37da2899SCharles.Forsyth ip->s.i.s = operand(isp);
229*37da2899SCharles.Forsyth break;
230*37da2899SCharles.Forsyth }
231*37da2899SCharles.Forsyth switch(UXDST(ip->add)) {
232*37da2899SCharles.Forsyth case DST(AFP):
233*37da2899SCharles.Forsyth case DST(AMP):
234*37da2899SCharles.Forsyth ip->d.ind = operand(isp);
235*37da2899SCharles.Forsyth break;
236*37da2899SCharles.Forsyth case DST(AIMM):
237*37da2899SCharles.Forsyth ip->d.ind = operand(isp);
238*37da2899SCharles.Forsyth if(brpatch(ip, m) == 0) {
239*37da2899SCharles.Forsyth kwerrstr("bad branch addr");
240*37da2899SCharles.Forsyth goto bad;
241*37da2899SCharles.Forsyth }
242*37da2899SCharles.Forsyth break;
243*37da2899SCharles.Forsyth case DST(AIND|AFP):
244*37da2899SCharles.Forsyth case DST(AIND|AMP):
245*37da2899SCharles.Forsyth ip->d.i.f = operand(isp);
246*37da2899SCharles.Forsyth ip->d.i.s = operand(isp);
247*37da2899SCharles.Forsyth break;
248*37da2899SCharles.Forsyth }
249*37da2899SCharles.Forsyth ip++;
250*37da2899SCharles.Forsyth }
251*37da2899SCharles.Forsyth
252*37da2899SCharles.Forsyth m->ntype = hsize;
253*37da2899SCharles.Forsyth m->type = malloc(hsize*sizeof(Type*));
254*37da2899SCharles.Forsyth if(m->type == nil) {
255*37da2899SCharles.Forsyth kwerrstr(exNomem);
256*37da2899SCharles.Forsyth goto bad;
257*37da2899SCharles.Forsyth }
258*37da2899SCharles.Forsyth for(i = 0; i < hsize; i++) {
259*37da2899SCharles.Forsyth id = operand(isp);
260*37da2899SCharles.Forsyth if(id > hsize) {
261*37da2899SCharles.Forsyth kwerrstr("heap id range");
262*37da2899SCharles.Forsyth goto bad;
263*37da2899SCharles.Forsyth }
264*37da2899SCharles.Forsyth tsz = operand(isp);
265*37da2899SCharles.Forsyth tnp = operand(isp);
266*37da2899SCharles.Forsyth if(tsz < 0 || tnp < 0 || tnp > 128*1024){
267*37da2899SCharles.Forsyth kwerrstr("implausible Dis file");
268*37da2899SCharles.Forsyth goto bad;
269*37da2899SCharles.Forsyth }
270*37da2899SCharles.Forsyth pt = dtype(freeheap, tsz, istream, tnp);
271*37da2899SCharles.Forsyth if(pt == nil) {
272*37da2899SCharles.Forsyth kwerrstr(exNomem);
273*37da2899SCharles.Forsyth goto bad;
274*37da2899SCharles.Forsyth }
275*37da2899SCharles.Forsyth istream += tnp;
276*37da2899SCharles.Forsyth m->type[id] = pt;
277*37da2899SCharles.Forsyth }
278*37da2899SCharles.Forsyth
279*37da2899SCharles.Forsyth if(dsize != 0) {
280*37da2899SCharles.Forsyth pt = m->type[0];
281*37da2899SCharles.Forsyth if(pt == 0 || pt->size != dsize) {
282*37da2899SCharles.Forsyth kwerrstr("bad desc for mp");
283*37da2899SCharles.Forsyth goto bad;
284*37da2899SCharles.Forsyth }
285*37da2899SCharles.Forsyth h = heapz(pt);
286*37da2899SCharles.Forsyth m->origmp = H2D(uchar*, h);
287*37da2899SCharles.Forsyth }
288*37da2899SCharles.Forsyth addr = m->origmp;
289*37da2899SCharles.Forsyth dasp = 0;
290*37da2899SCharles.Forsyth for(;;) {
291*37da2899SCharles.Forsyth sm = *istream++;
292*37da2899SCharles.Forsyth if(sm == 0)
293*37da2899SCharles.Forsyth break;
294*37da2899SCharles.Forsyth n = DLEN(sm);
295*37da2899SCharles.Forsyth if(n == 0)
296*37da2899SCharles.Forsyth n = operand(isp);
297*37da2899SCharles.Forsyth v = operand(isp);
298*37da2899SCharles.Forsyth si = addr + v;
299*37da2899SCharles.Forsyth switch(DTYPE(sm)) {
300*37da2899SCharles.Forsyth default:
301*37da2899SCharles.Forsyth kwerrstr("bad data item");
302*37da2899SCharles.Forsyth goto bad;
303*37da2899SCharles.Forsyth case DEFS:
304*37da2899SCharles.Forsyth s = c2string((char*)istream, n);
305*37da2899SCharles.Forsyth istream += n;
306*37da2899SCharles.Forsyth *(String**)si = s;
307*37da2899SCharles.Forsyth break;
308*37da2899SCharles.Forsyth case DEFB:
309*37da2899SCharles.Forsyth for(i = 0; i < n; i++)
310*37da2899SCharles.Forsyth *si++ = *istream++;
311*37da2899SCharles.Forsyth break;
312*37da2899SCharles.Forsyth case DEFW:
313*37da2899SCharles.Forsyth for(i = 0; i < n; i++) {
314*37da2899SCharles.Forsyth *(WORD*)si = disw(isp);
315*37da2899SCharles.Forsyth si += sizeof(WORD);
316*37da2899SCharles.Forsyth }
317*37da2899SCharles.Forsyth break;
318*37da2899SCharles.Forsyth case DEFL:
319*37da2899SCharles.Forsyth for(i = 0; i < n; i++) {
320*37da2899SCharles.Forsyth hi = disw(isp);
321*37da2899SCharles.Forsyth lo = disw(isp);
322*37da2899SCharles.Forsyth *(LONG*)si = (LONG)hi << 32 | (LONG)(ulong)lo;
323*37da2899SCharles.Forsyth si += sizeof(LONG);
324*37da2899SCharles.Forsyth }
325*37da2899SCharles.Forsyth break;
326*37da2899SCharles.Forsyth case DEFF:
327*37da2899SCharles.Forsyth for(i = 0; i < n; i++) {
328*37da2899SCharles.Forsyth ul[0] = disw(isp);
329*37da2899SCharles.Forsyth ul[1] = disw(isp);
330*37da2899SCharles.Forsyth *(REAL*)si = canontod(ul);
331*37da2899SCharles.Forsyth si += sizeof(REAL);
332*37da2899SCharles.Forsyth }
333*37da2899SCharles.Forsyth break;
334*37da2899SCharles.Forsyth case DEFA: /* Array */
335*37da2899SCharles.Forsyth v = disw(isp);
336*37da2899SCharles.Forsyth if(v < 0 || v > m->ntype) {
337*37da2899SCharles.Forsyth kwerrstr("bad array type");
338*37da2899SCharles.Forsyth goto bad;
339*37da2899SCharles.Forsyth }
340*37da2899SCharles.Forsyth pt = m->type[v];
341*37da2899SCharles.Forsyth v = disw(isp);
342*37da2899SCharles.Forsyth h = nheap(sizeof(Array)+(pt->size*v));
343*37da2899SCharles.Forsyth h->t = &Tarray;
344*37da2899SCharles.Forsyth h->t->ref++;
345*37da2899SCharles.Forsyth ary = H2D(Array*, h);
346*37da2899SCharles.Forsyth ary->t = pt;
347*37da2899SCharles.Forsyth ary->len = v;
348*37da2899SCharles.Forsyth ary->root = H;
349*37da2899SCharles.Forsyth ary->data = (uchar*)ary+sizeof(Array);
350*37da2899SCharles.Forsyth memset((void*)ary->data, 0, pt->size*v);
351*37da2899SCharles.Forsyth initarray(pt, ary);
352*37da2899SCharles.Forsyth A(si) = ary;
353*37da2899SCharles.Forsyth break;
354*37da2899SCharles.Forsyth case DIND: /* Set index */
355*37da2899SCharles.Forsyth ary = A(si);
356*37da2899SCharles.Forsyth if(ary == H || D2H(ary)->t != &Tarray) {
357*37da2899SCharles.Forsyth kwerrstr("ind not array");
358*37da2899SCharles.Forsyth goto bad;
359*37da2899SCharles.Forsyth }
360*37da2899SCharles.Forsyth v = disw(isp);
361*37da2899SCharles.Forsyth if(v > ary->len || v < 0 || dasp >= DADEPTH) {
362*37da2899SCharles.Forsyth kwerrstr("array init range");
363*37da2899SCharles.Forsyth goto bad;
364*37da2899SCharles.Forsyth }
365*37da2899SCharles.Forsyth dastack[dasp++] = addr;
366*37da2899SCharles.Forsyth addr = ary->data+v*ary->t->size;
367*37da2899SCharles.Forsyth break;
368*37da2899SCharles.Forsyth case DAPOP:
369*37da2899SCharles.Forsyth if(dasp == 0) {
370*37da2899SCharles.Forsyth kwerrstr("pop range");
371*37da2899SCharles.Forsyth goto bad;
372*37da2899SCharles.Forsyth }
373*37da2899SCharles.Forsyth addr = dastack[--dasp];
374*37da2899SCharles.Forsyth break;
375*37da2899SCharles.Forsyth }
376*37da2899SCharles.Forsyth }
377*37da2899SCharles.Forsyth mod = istream;
378*37da2899SCharles.Forsyth if(memchr(mod, 0, 128) == 0) {
379*37da2899SCharles.Forsyth kwerrstr("bad module name");
380*37da2899SCharles.Forsyth goto bad;
381*37da2899SCharles.Forsyth }
382*37da2899SCharles.Forsyth m->name = strdup((char*)mod);
383*37da2899SCharles.Forsyth if(m->name == nil) {
384*37da2899SCharles.Forsyth kwerrstr(exNomem);
385*37da2899SCharles.Forsyth goto bad;
386*37da2899SCharles.Forsyth }
387*37da2899SCharles.Forsyth while(*istream++)
388*37da2899SCharles.Forsyth ;
389*37da2899SCharles.Forsyth
390*37da2899SCharles.Forsyth l = m->ext = (Link*)malloc((lsize+1)*sizeof(Link));
391*37da2899SCharles.Forsyth if(l == nil){
392*37da2899SCharles.Forsyth kwerrstr(exNomem);
393*37da2899SCharles.Forsyth goto bad;
394*37da2899SCharles.Forsyth }
395*37da2899SCharles.Forsyth for(i = 0; i < lsize; i++, l++) {
396*37da2899SCharles.Forsyth pc = operand(isp);
397*37da2899SCharles.Forsyth de = operand(isp);
398*37da2899SCharles.Forsyth v = disw(isp);
399*37da2899SCharles.Forsyth pt = nil;
400*37da2899SCharles.Forsyth if(de != -1)
401*37da2899SCharles.Forsyth pt = m->type[de];
402*37da2899SCharles.Forsyth mlink(m, l, istream, v, pc, pt);
403*37da2899SCharles.Forsyth while(*istream++)
404*37da2899SCharles.Forsyth ;
405*37da2899SCharles.Forsyth }
406*37da2899SCharles.Forsyth l->name = nil;
407*37da2899SCharles.Forsyth
408*37da2899SCharles.Forsyth if(m->rt & HASLDT0){
409*37da2899SCharles.Forsyth kwerrstr("obsolete dis");
410*37da2899SCharles.Forsyth goto bad;
411*37da2899SCharles.Forsyth }
412*37da2899SCharles.Forsyth
413*37da2899SCharles.Forsyth if(m->rt & HASLDT){
414*37da2899SCharles.Forsyth int j, nl;
415*37da2899SCharles.Forsyth Import *i1, **i2;
416*37da2899SCharles.Forsyth
417*37da2899SCharles.Forsyth nl = operand(isp);
418*37da2899SCharles.Forsyth i2 = m->ldt = (Import**)malloc((nl+1)*sizeof(Import*));
419*37da2899SCharles.Forsyth if(i2 == nil){
420*37da2899SCharles.Forsyth kwerrstr(exNomem);
421*37da2899SCharles.Forsyth goto bad;
422*37da2899SCharles.Forsyth }
423*37da2899SCharles.Forsyth for(i = 0; i < nl; i++, i2++){
424*37da2899SCharles.Forsyth n = operand(isp);
425*37da2899SCharles.Forsyth i1 = *i2 = (Import*)malloc((n+1)*sizeof(Import));
426*37da2899SCharles.Forsyth if(i1 == nil){
427*37da2899SCharles.Forsyth kwerrstr(exNomem);
428*37da2899SCharles.Forsyth goto bad;
429*37da2899SCharles.Forsyth }
430*37da2899SCharles.Forsyth for(j = 0; j < n; j++, i1++){
431*37da2899SCharles.Forsyth i1->sig = disw(isp);
432*37da2899SCharles.Forsyth i1->name = strdup((char*)istream);
433*37da2899SCharles.Forsyth if(i1->name == nil){
434*37da2899SCharles.Forsyth kwerrstr(exNomem);
435*37da2899SCharles.Forsyth goto bad;
436*37da2899SCharles.Forsyth }
437*37da2899SCharles.Forsyth while(*istream++)
438*37da2899SCharles.Forsyth ;
439*37da2899SCharles.Forsyth }
440*37da2899SCharles.Forsyth }
441*37da2899SCharles.Forsyth istream++;
442*37da2899SCharles.Forsyth }
443*37da2899SCharles.Forsyth
444*37da2899SCharles.Forsyth if(m->rt & HASEXCEPT){
445*37da2899SCharles.Forsyth int j, nh;
446*37da2899SCharles.Forsyth Handler *h;
447*37da2899SCharles.Forsyth Except *e;
448*37da2899SCharles.Forsyth
449*37da2899SCharles.Forsyth nh = operand(isp);
450*37da2899SCharles.Forsyth m->htab = malloc((nh+1)*sizeof(Handler));
451*37da2899SCharles.Forsyth if(m->htab == nil){
452*37da2899SCharles.Forsyth kwerrstr(exNomem);
453*37da2899SCharles.Forsyth goto bad;
454*37da2899SCharles.Forsyth }
455*37da2899SCharles.Forsyth h = m->htab;
456*37da2899SCharles.Forsyth for(i = 0; i < nh; i++, h++){
457*37da2899SCharles.Forsyth h->eoff = operand(isp);
458*37da2899SCharles.Forsyth h->pc1 = operand(isp);
459*37da2899SCharles.Forsyth h->pc2 = operand(isp);
460*37da2899SCharles.Forsyth n = operand(isp);
461*37da2899SCharles.Forsyth if(n != -1)
462*37da2899SCharles.Forsyth h->t = m->type[n];
463*37da2899SCharles.Forsyth n = operand(isp);
464*37da2899SCharles.Forsyth h->ne = n>>16;
465*37da2899SCharles.Forsyth n &= 0xffff;
466*37da2899SCharles.Forsyth h->etab = malloc((n+1)*sizeof(Except));
467*37da2899SCharles.Forsyth if(h->etab == nil){
468*37da2899SCharles.Forsyth kwerrstr(exNomem);
469*37da2899SCharles.Forsyth goto bad;
470*37da2899SCharles.Forsyth }
471*37da2899SCharles.Forsyth e = h->etab;
472*37da2899SCharles.Forsyth for(j = 0; j < n; j++, e++){
473*37da2899SCharles.Forsyth e->s = strdup((char*)istream);
474*37da2899SCharles.Forsyth if(e->s == nil){
475*37da2899SCharles.Forsyth kwerrstr(exNomem);
476*37da2899SCharles.Forsyth goto bad;
477*37da2899SCharles.Forsyth }
478*37da2899SCharles.Forsyth while(*istream++)
479*37da2899SCharles.Forsyth ;
480*37da2899SCharles.Forsyth e->pc = operand(isp);
481*37da2899SCharles.Forsyth }
482*37da2899SCharles.Forsyth e->s = nil;
483*37da2899SCharles.Forsyth e->pc = operand(isp);
484*37da2899SCharles.Forsyth }
485*37da2899SCharles.Forsyth istream++;
486*37da2899SCharles.Forsyth }
487*37da2899SCharles.Forsyth
488*37da2899SCharles.Forsyth m->entryt = nil;
489*37da2899SCharles.Forsyth m->entry = m->prog;
490*37da2899SCharles.Forsyth if((ulong)entry < isize && (ulong)entryt < hsize) {
491*37da2899SCharles.Forsyth m->entry = &m->prog[entry];
492*37da2899SCharles.Forsyth m->entryt = m->type[entryt];
493*37da2899SCharles.Forsyth }
494*37da2899SCharles.Forsyth
495*37da2899SCharles.Forsyth if(cflag) {
496*37da2899SCharles.Forsyth if((m->rt&DONTCOMPILE) == 0 && !dontcompile)
497*37da2899SCharles.Forsyth compile(m, isize, nil);
498*37da2899SCharles.Forsyth }
499*37da2899SCharles.Forsyth else
500*37da2899SCharles.Forsyth if(m->rt & MUSTCOMPILE && !dontcompile) {
501*37da2899SCharles.Forsyth if(compile(m, isize, nil) == 0) {
502*37da2899SCharles.Forsyth kwerrstr("compiler required");
503*37da2899SCharles.Forsyth goto bad;
504*37da2899SCharles.Forsyth }
505*37da2899SCharles.Forsyth }
506*37da2899SCharles.Forsyth
507*37da2899SCharles.Forsyth m->path = strdup(path);
508*37da2899SCharles.Forsyth if(m->path == nil) {
509*37da2899SCharles.Forsyth kwerrstr(exNomem);
510*37da2899SCharles.Forsyth goto bad;
511*37da2899SCharles.Forsyth }
512*37da2899SCharles.Forsyth m->link = modules;
513*37da2899SCharles.Forsyth modules = m;
514*37da2899SCharles.Forsyth
515*37da2899SCharles.Forsyth return m;
516*37da2899SCharles.Forsyth bad:
517*37da2899SCharles.Forsyth destroy(m->origmp);
518*37da2899SCharles.Forsyth freemod(m);
519*37da2899SCharles.Forsyth return nil;
520*37da2899SCharles.Forsyth }
521*37da2899SCharles.Forsyth
522*37da2899SCharles.Forsyth Module*
newmod(char * s)523*37da2899SCharles.Forsyth newmod(char *s)
524*37da2899SCharles.Forsyth {
525*37da2899SCharles.Forsyth Module *m;
526*37da2899SCharles.Forsyth
527*37da2899SCharles.Forsyth m = malloc(sizeof(Module));
528*37da2899SCharles.Forsyth if(m == nil)
529*37da2899SCharles.Forsyth error(exNomem);
530*37da2899SCharles.Forsyth m->ref = 1;
531*37da2899SCharles.Forsyth m->path = s;
532*37da2899SCharles.Forsyth m->origmp = H;
533*37da2899SCharles.Forsyth m->name = strdup(s);
534*37da2899SCharles.Forsyth if(m->name == nil) {
535*37da2899SCharles.Forsyth free(m);
536*37da2899SCharles.Forsyth error(exNomem);
537*37da2899SCharles.Forsyth }
538*37da2899SCharles.Forsyth m->link = modules;
539*37da2899SCharles.Forsyth modules = m;
540*37da2899SCharles.Forsyth m->pctab = nil;
541*37da2899SCharles.Forsyth return m;
542*37da2899SCharles.Forsyth }
543*37da2899SCharles.Forsyth
544*37da2899SCharles.Forsyth Module*
lookmod(char * s)545*37da2899SCharles.Forsyth lookmod(char *s)
546*37da2899SCharles.Forsyth {
547*37da2899SCharles.Forsyth Module *m;
548*37da2899SCharles.Forsyth
549*37da2899SCharles.Forsyth for(m = modules; m != nil; m = m->link)
550*37da2899SCharles.Forsyth if(strcmp(s, m->path) == 0) {
551*37da2899SCharles.Forsyth m->ref++;
552*37da2899SCharles.Forsyth return m;
553*37da2899SCharles.Forsyth }
554*37da2899SCharles.Forsyth return nil;
555*37da2899SCharles.Forsyth }
556*37da2899SCharles.Forsyth
557*37da2899SCharles.Forsyth void
freemod(Module * m)558*37da2899SCharles.Forsyth freemod(Module *m)
559*37da2899SCharles.Forsyth {
560*37da2899SCharles.Forsyth int i;
561*37da2899SCharles.Forsyth Handler *h;
562*37da2899SCharles.Forsyth Except *e;
563*37da2899SCharles.Forsyth Import *i1, **i2;
564*37da2899SCharles.Forsyth
565*37da2899SCharles.Forsyth if(m->type != nil) {
566*37da2899SCharles.Forsyth for(i = 0; i < m->ntype; i++)
567*37da2899SCharles.Forsyth freetype(m->type[i]);
568*37da2899SCharles.Forsyth free(m->type);
569*37da2899SCharles.Forsyth }
570*37da2899SCharles.Forsyth free(m->name);
571*37da2899SCharles.Forsyth free(m->prog);
572*37da2899SCharles.Forsyth free(m->path);
573*37da2899SCharles.Forsyth free(m->pctab);
574*37da2899SCharles.Forsyth if(m->ldt != nil){
575*37da2899SCharles.Forsyth for(i2 = m->ldt; *i2 != nil; i2++){
576*37da2899SCharles.Forsyth for(i1 = *i2; i1->name != nil; i1++)
577*37da2899SCharles.Forsyth free(i1->name);
578*37da2899SCharles.Forsyth free(*i2);
579*37da2899SCharles.Forsyth }
580*37da2899SCharles.Forsyth free(m->ldt);
581*37da2899SCharles.Forsyth }
582*37da2899SCharles.Forsyth if(m->htab != nil){
583*37da2899SCharles.Forsyth for(h = m->htab; h->etab != nil; h++){
584*37da2899SCharles.Forsyth for(e = h->etab; e->s != nil; e++)
585*37da2899SCharles.Forsyth free(e->s);
586*37da2899SCharles.Forsyth free(h->etab);
587*37da2899SCharles.Forsyth }
588*37da2899SCharles.Forsyth free(m->htab);
589*37da2899SCharles.Forsyth }
590*37da2899SCharles.Forsyth free(m);
591*37da2899SCharles.Forsyth }
592*37da2899SCharles.Forsyth
593*37da2899SCharles.Forsyth void
unload(Module * m)594*37da2899SCharles.Forsyth unload(Module *m)
595*37da2899SCharles.Forsyth {
596*37da2899SCharles.Forsyth Module **last, *mm;
597*37da2899SCharles.Forsyth
598*37da2899SCharles.Forsyth m->ref--;
599*37da2899SCharles.Forsyth if(m->ref > 0)
600*37da2899SCharles.Forsyth return;
601*37da2899SCharles.Forsyth if(m->ref == -1)
602*37da2899SCharles.Forsyth abort();
603*37da2899SCharles.Forsyth
604*37da2899SCharles.Forsyth last = &modules;
605*37da2899SCharles.Forsyth for(mm = modules; mm != nil; mm = mm->link) {
606*37da2899SCharles.Forsyth if(mm == m) {
607*37da2899SCharles.Forsyth *last = m->link;
608*37da2899SCharles.Forsyth break;
609*37da2899SCharles.Forsyth }
610*37da2899SCharles.Forsyth last = &mm->link;
611*37da2899SCharles.Forsyth }
612*37da2899SCharles.Forsyth
613*37da2899SCharles.Forsyth if(m->rt == DYNMOD)
614*37da2899SCharles.Forsyth freedyncode(m);
615*37da2899SCharles.Forsyth else
616*37da2899SCharles.Forsyth destroy(m->origmp);
617*37da2899SCharles.Forsyth
618*37da2899SCharles.Forsyth destroylinks(m);
619*37da2899SCharles.Forsyth
620*37da2899SCharles.Forsyth freemod(m);
621*37da2899SCharles.Forsyth }
622