xref: /inferno-os/libinterp/dlm-Inferno.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 "pool.h"
6*37da2899SCharles.Forsyth #include "kernel.h"
7*37da2899SCharles.Forsyth #include "dynld.h"
8*37da2899SCharles.Forsyth 
9*37da2899SCharles.Forsyth #define	DBG	if(1) print
10*37da2899SCharles.Forsyth 
11*37da2899SCharles.Forsyth extern Dynobj* dynld(int);
12*37da2899SCharles.Forsyth extern char*	enverror(void);
13*37da2899SCharles.Forsyth 
14*37da2899SCharles.Forsyth typedef struct{char *name; long sig; void (*fn)(void*); int size; int np; uchar map[16];} Runtab;
15*37da2899SCharles.Forsyth 
16*37da2899SCharles.Forsyth static void*
addr(char * pre,char * suf,Dynobj * o,ulong sig)17*37da2899SCharles.Forsyth addr(char *pre, char *suf, Dynobj *o, ulong sig)
18*37da2899SCharles.Forsyth {
19*37da2899SCharles.Forsyth 	char buf[64];
20*37da2899SCharles.Forsyth 
21*37da2899SCharles.Forsyth 	if(o == nil || strlen(pre)+strlen(suf) > 64-1)
22*37da2899SCharles.Forsyth 		return nil;
23*37da2899SCharles.Forsyth 	snprint(buf, sizeof(buf), "%s%s", pre, suf);
24*37da2899SCharles.Forsyth 	return dynimport(o, buf, sig);
25*37da2899SCharles.Forsyth }
26*37da2899SCharles.Forsyth 
27*37da2899SCharles.Forsyth Module*
newdyncode(int fd,char * path,Dir * dir)28*37da2899SCharles.Forsyth newdyncode(int fd, char *path, Dir *dir)
29*37da2899SCharles.Forsyth {
30*37da2899SCharles.Forsyth 	Module *m;
31*37da2899SCharles.Forsyth 	void *v;
32*37da2899SCharles.Forsyth 	Runtab *r;
33*37da2899SCharles.Forsyth 	Dynobj *o;
34*37da2899SCharles.Forsyth 	char *name;
35*37da2899SCharles.Forsyth 
36*37da2899SCharles.Forsyth 	DBG("module path is %s\n", path);
37*37da2899SCharles.Forsyth 	m = nil;
38*37da2899SCharles.Forsyth 	o = dynld(fd);
39*37da2899SCharles.Forsyth 	if(o == nil){
40*37da2899SCharles.Forsyth 		DBG("%s\n", enverror());
41*37da2899SCharles.Forsyth 		goto Error;
42*37da2899SCharles.Forsyth 	}
43*37da2899SCharles.Forsyth 	v = addr("XXX", "module", o, signof(char*));
44*37da2899SCharles.Forsyth 	if(v == nil)
45*37da2899SCharles.Forsyth 		goto Error;
46*37da2899SCharles.Forsyth 	name = *(char**)v;
47*37da2899SCharles.Forsyth 	DBG("module name is %s\n", name);
48*37da2899SCharles.Forsyth 	r = addr(name, "modtab", o, signof(Runtab[]));
49*37da2899SCharles.Forsyth 	if(r == nil)
50*37da2899SCharles.Forsyth 		goto Error;
51*37da2899SCharles.Forsyth 	m = builtinmod(name, r, 0);
52*37da2899SCharles.Forsyth 	m->rt = DYNMOD;
53*37da2899SCharles.Forsyth 	m->dev = dir->dev;
54*37da2899SCharles.Forsyth 	m->dtype = dir->type;
55*37da2899SCharles.Forsyth 	m->qid = dir->qid;
56*37da2899SCharles.Forsyth 	m->mtime = dir->mtime;
57*37da2899SCharles.Forsyth 	m->path = strdup(path);
58*37da2899SCharles.Forsyth 	if(m->path == nil)
59*37da2899SCharles.Forsyth 		goto Error;
60*37da2899SCharles.Forsyth 	m->dlm = o;
61*37da2899SCharles.Forsyth 	DBG("module base is 0x%p\n", o->base);
62*37da2899SCharles.Forsyth 	return m;
63*37da2899SCharles.Forsyth Error:
64*37da2899SCharles.Forsyth 	if(o != nil)
65*37da2899SCharles.Forsyth 		dynobjfree(o);
66*37da2899SCharles.Forsyth 	if(m != nil)
67*37da2899SCharles.Forsyth 		freemod(m);
68*37da2899SCharles.Forsyth 	return nil;
69*37da2899SCharles.Forsyth }
70*37da2899SCharles.Forsyth 
71*37da2899SCharles.Forsyth void
freedyncode(Module * m)72*37da2899SCharles.Forsyth freedyncode(Module *m)
73*37da2899SCharles.Forsyth {
74*37da2899SCharles.Forsyth 	dynobjfree(m->dlm);
75*37da2899SCharles.Forsyth }
76*37da2899SCharles.Forsyth 
77*37da2899SCharles.Forsyth static void
callfn(Module * m,char * fn)78*37da2899SCharles.Forsyth callfn(Module *m, char *fn)
79*37da2899SCharles.Forsyth {
80*37da2899SCharles.Forsyth 	void *v, (*f)(void);
81*37da2899SCharles.Forsyth 
82*37da2899SCharles.Forsyth 	if(m->ref != 1)
83*37da2899SCharles.Forsyth 		return;
84*37da2899SCharles.Forsyth 	v = addr(m->name, fn, m->dlm, signof(*f));
85*37da2899SCharles.Forsyth 	if(v != nil){
86*37da2899SCharles.Forsyth 		f = v;
87*37da2899SCharles.Forsyth 		(*f)();
88*37da2899SCharles.Forsyth 	}
89*37da2899SCharles.Forsyth }
90*37da2899SCharles.Forsyth 
91*37da2899SCharles.Forsyth void
newdyndata(Modlink * ml)92*37da2899SCharles.Forsyth newdyndata(Modlink *ml)
93*37da2899SCharles.Forsyth {
94*37da2899SCharles.Forsyth 	callfn(ml->m, "init");
95*37da2899SCharles.Forsyth }
96*37da2899SCharles.Forsyth 
97*37da2899SCharles.Forsyth void
freedyndata(Modlink * ml)98*37da2899SCharles.Forsyth freedyndata(Modlink *ml)
99*37da2899SCharles.Forsyth {
100*37da2899SCharles.Forsyth 	callfn(ml->m, "end");
101*37da2899SCharles.Forsyth }
102