xref: /inferno-os/libinterp/link.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 "raise.h"
5*37da2899SCharles.Forsyth #include <kernel.h>
6*37da2899SCharles.Forsyth 
7*37da2899SCharles.Forsyth static void
newlink(Link * l,char * fn,int sig,Type * t)8*37da2899SCharles.Forsyth newlink(Link *l, char *fn, int sig, Type *t)
9*37da2899SCharles.Forsyth {
10*37da2899SCharles.Forsyth 	l->name = malloc(strlen(fn)+1);
11*37da2899SCharles.Forsyth 	if(l->name == nil)
12*37da2899SCharles.Forsyth 		error(exNomem);
13*37da2899SCharles.Forsyth 	strcpy(l->name, fn);
14*37da2899SCharles.Forsyth 	l->sig = sig;
15*37da2899SCharles.Forsyth 	l->frame = t;
16*37da2899SCharles.Forsyth }
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth void
runtime(Module * m,Link * l,char * fn,int sig,void (* runt)(void *),Type * t)19*37da2899SCharles.Forsyth runtime(Module *m, Link *l, char *fn, int sig, void (*runt)(void*), Type *t)
20*37da2899SCharles.Forsyth {
21*37da2899SCharles.Forsyth 	USED(m);
22*37da2899SCharles.Forsyth 	newlink(l, fn, sig, t);
23*37da2899SCharles.Forsyth 	l->u.runt = runt;
24*37da2899SCharles.Forsyth }
25*37da2899SCharles.Forsyth 
26*37da2899SCharles.Forsyth void
mlink(Module * m,Link * l,uchar * fn,int sig,int pc,Type * t)27*37da2899SCharles.Forsyth mlink(Module *m, Link* l, uchar *fn, int sig, int pc, Type *t)
28*37da2899SCharles.Forsyth {
29*37da2899SCharles.Forsyth 	newlink(l, (char*)fn, sig, t);
30*37da2899SCharles.Forsyth 	l->u.pc = m->prog+pc;
31*37da2899SCharles.Forsyth }
32*37da2899SCharles.Forsyth 
33*37da2899SCharles.Forsyth static int
linkm(Module * m,Modlink * ml,int i,Import * ldt)34*37da2899SCharles.Forsyth linkm(Module *m, Modlink *ml, int i, Import *ldt)
35*37da2899SCharles.Forsyth {
36*37da2899SCharles.Forsyth 	Link *l;
37*37da2899SCharles.Forsyth 	int sig;
38*37da2899SCharles.Forsyth 	char e[ERRMAX];
39*37da2899SCharles.Forsyth 
40*37da2899SCharles.Forsyth 	sig = ldt->sig;
41*37da2899SCharles.Forsyth 	for(l = m->ext; l->name; l++)
42*37da2899SCharles.Forsyth 		if(strcmp(ldt->name, l->name) == 0)
43*37da2899SCharles.Forsyth 			break;
44*37da2899SCharles.Forsyth 
45*37da2899SCharles.Forsyth 	if(l == nil) {
46*37da2899SCharles.Forsyth 		snprint(e, sizeof(e), "link failed fn %s->%s() not implemented", m->name, ldt->name);
47*37da2899SCharles.Forsyth 		goto bad;
48*37da2899SCharles.Forsyth 	}
49*37da2899SCharles.Forsyth 	if(l->sig != sig) {
50*37da2899SCharles.Forsyth 		snprint(e, sizeof(e), "link typecheck %s->%s() %ux/%ux",
51*37da2899SCharles.Forsyth 							m->name, ldt->name, l->sig, sig);
52*37da2899SCharles.Forsyth 		goto bad;
53*37da2899SCharles.Forsyth 	}
54*37da2899SCharles.Forsyth 
55*37da2899SCharles.Forsyth 	ml->links[i].u = l->u;
56*37da2899SCharles.Forsyth 	ml->links[i].frame = l->frame;
57*37da2899SCharles.Forsyth 	return 0;
58*37da2899SCharles.Forsyth bad:
59*37da2899SCharles.Forsyth 	kwerrstr(e);
60*37da2899SCharles.Forsyth 	print("%s\n", e);
61*37da2899SCharles.Forsyth 	return -1;
62*37da2899SCharles.Forsyth }
63*37da2899SCharles.Forsyth 
64*37da2899SCharles.Forsyth Modlink*
mklinkmod(Module * m,int n)65*37da2899SCharles.Forsyth mklinkmod(Module *m, int n)
66*37da2899SCharles.Forsyth {
67*37da2899SCharles.Forsyth 	Heap *h;
68*37da2899SCharles.Forsyth 	Modlink *ml;
69*37da2899SCharles.Forsyth 
70*37da2899SCharles.Forsyth 	h = nheap(sizeof(Modlink)+(n-1)*sizeof(ml->links[0]));
71*37da2899SCharles.Forsyth 	h->t = &Tmodlink;
72*37da2899SCharles.Forsyth 	Tmodlink.ref++;
73*37da2899SCharles.Forsyth 	ml = H2D(Modlink*, h);
74*37da2899SCharles.Forsyth 	ml->nlinks = n;
75*37da2899SCharles.Forsyth 	ml->m = m;
76*37da2899SCharles.Forsyth 	ml->prog = m->prog;
77*37da2899SCharles.Forsyth 	ml->type = m->type;
78*37da2899SCharles.Forsyth 	ml->compiled = m->compiled;
79*37da2899SCharles.Forsyth 	ml->MP = H;
80*37da2899SCharles.Forsyth 	ml->data = nil;
81*37da2899SCharles.Forsyth 
82*37da2899SCharles.Forsyth 	return ml;
83*37da2899SCharles.Forsyth }
84*37da2899SCharles.Forsyth 
85*37da2899SCharles.Forsyth Modlink*
linkmod(Module * m,Import * ldt,int mkmp)86*37da2899SCharles.Forsyth linkmod(Module *m, Import *ldt, int mkmp)
87*37da2899SCharles.Forsyth {
88*37da2899SCharles.Forsyth 	Type *t;
89*37da2899SCharles.Forsyth 	Heap *h;
90*37da2899SCharles.Forsyth 	int i;
91*37da2899SCharles.Forsyth 	Modlink *ml;
92*37da2899SCharles.Forsyth 	Import *l;
93*37da2899SCharles.Forsyth 
94*37da2899SCharles.Forsyth 	if(m == nil)
95*37da2899SCharles.Forsyth 		return H;
96*37da2899SCharles.Forsyth 
97*37da2899SCharles.Forsyth 	for(i = 0, l = ldt; l->name != nil; i++, l++)
98*37da2899SCharles.Forsyth 		;
99*37da2899SCharles.Forsyth 	ml = mklinkmod(m, i);
100*37da2899SCharles.Forsyth 
101*37da2899SCharles.Forsyth 	if(mkmp){
102*37da2899SCharles.Forsyth 		if(m->rt == DYNMOD)
103*37da2899SCharles.Forsyth 			newdyndata(ml);
104*37da2899SCharles.Forsyth 		else if(mkmp && m->origmp != H && m->ntype > 0) {
105*37da2899SCharles.Forsyth 			t = m->type[0];
106*37da2899SCharles.Forsyth 			h = nheap(t->size);
107*37da2899SCharles.Forsyth 			h->t = t;
108*37da2899SCharles.Forsyth 			t->ref++;
109*37da2899SCharles.Forsyth 			ml->MP = H2D(uchar*, h);
110*37da2899SCharles.Forsyth 			newmp(ml->MP, m->origmp, t);
111*37da2899SCharles.Forsyth 		}
112*37da2899SCharles.Forsyth 	}
113*37da2899SCharles.Forsyth 
114*37da2899SCharles.Forsyth 	for(i = 0, l = ldt; l->name != nil; i++, l++) {
115*37da2899SCharles.Forsyth 		if(linkm(m, ml, i, l) < 0){
116*37da2899SCharles.Forsyth 			destroy(ml);
117*37da2899SCharles.Forsyth 			return H;
118*37da2899SCharles.Forsyth 		}
119*37da2899SCharles.Forsyth 	}
120*37da2899SCharles.Forsyth 
121*37da2899SCharles.Forsyth 	return ml;
122*37da2899SCharles.Forsyth }
123*37da2899SCharles.Forsyth 
124*37da2899SCharles.Forsyth void
destroylinks(Module * m)125*37da2899SCharles.Forsyth destroylinks(Module *m)
126*37da2899SCharles.Forsyth {
127*37da2899SCharles.Forsyth 	Link *l;
128*37da2899SCharles.Forsyth 
129*37da2899SCharles.Forsyth 	for(l = m->ext; l->name; l++)
130*37da2899SCharles.Forsyth 		free(l->name);
131*37da2899SCharles.Forsyth 	free(m->ext);
132*37da2899SCharles.Forsyth }
133