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