death to register
[openafs.git] / src / export / export.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * export -     EXPORT kernel extension
12  */
13
14 /* Unsafe: conflicts with _KERNEL inclusion of headers below */
15 /* #include <afs/param.h> */
16 /* #include <afsconfig.h> */
17
18 #define _KERNEL
19 #include "sys/types.h"
20 #include "sys/user.h"
21 #include "sys/conf.h"
22 #include "sys/errno.h"
23 #include "sys/device.h"
24 #include "sys/uio.h"
25 #include "sys/pri.h"
26 #include "sys/malloc.h"
27 #include "sym.h"
28 #include "export.h"
29
30 #undef RELOC
31
32 sym_t *toc_syms;                /* symbol table                 */
33 int toc_nsyms;                  /* # of symbols                 */
34 caddr_t toc_strs;               /* string table                 */
35 int toc_size;                   /* size of toc_syms             */
36
37 /*
38  * export       -       entry point to EXPORT kernel extension
39  *
40  * Input:
41  *      cmd     -       add/delete command
42  *      uiop    -       uio vector describing any config params
43  */
44 export(cmd, uiop)
45      struct uio *uiop;
46 {
47     int err, monster;
48     static once;
49
50     err = 0;
51     monster = lockl(&kernel_lock, LOCK_SHORT);
52
53     switch (cmd) {
54     case CFG_INIT:              /* add EXPORT           */
55         if (err = config(uiop))
56             export_cleanup();
57         break;
58
59     case CFG_TERM:              /* remove EXPORT        */
60         if (err = export_cleanup())
61             break;
62         break;
63
64     default:
65         err = EINVAL;
66         break;
67     }
68
69     if (monster != LOCK_NEST)
70         unlockl(&kernel_lock);
71
72     return err;
73 }
74 \f
75 /*
76  * config -     process configuration data
77  */
78 config(uiop)
79      struct uio *uiop;
80 {
81     struct k_conf conf;
82     struct export_nl *np;
83     sym_t *sym;
84     int err;
85
86     if (err = uiomove((char *)&conf, sizeof(conf), UIO_WRITE, uiop))
87         return err;
88
89     toc_nsyms = conf.nsyms;
90     toc_size = conf.symt_sz + conf.str_sz;
91
92     if (toc_nsyms * sizeof(sym_t) != conf.symt_sz || toc_size > (1024 * 1024))
93 #ifdef AFS_AIX51_ENV
94         return EFBIG;
95 #else
96         return EINVAL;
97 #endif
98
99     toc_syms = (sym_t *) xmalloc(toc_size, 2, kernel_heap);
100
101     if (!toc_syms)
102         return ENOMEM;
103
104     toc_strs = (char *)&toc_syms[toc_nsyms];
105
106     /*
107      * copy in the symbol table and the string table
108      */
109     if (err = copyin(conf.symtab, toc_syms, conf.symt_sz)
110         || (err = copyin(conf.strtab, toc_strs, conf.str_sz))) {
111         xmfree(toc_syms, kernel_heap);
112         toc_syms = 0;
113         return err;
114     }
115
116     /*
117      * `TOC' format in kernel has offsets relocated to point directly
118      * into the string table.
119      */
120     for (sym = toc_syms; sym < &toc_syms[toc_nsyms]; ++sym)
121 #ifndef __XCOFF64__
122         if (sym->n_zeroes == 0)
123 #endif
124             sym->n_nptr = sym->n_offset + toc_strs;
125
126     return 0;
127 }
128
129 /*
130  * export_cleanup -     cleanup EXPORT prior to removing kernel extension
131  */
132 export_cleanup()
133 {
134
135     /*
136      * get rid of the symbol table
137      */
138     if (toc_syms) {
139         xmfree(toc_syms, kernel_heap);
140         toc_syms = 0;
141         toc_size = 0;
142         toc_strs = 0;
143     }
144
145     return 0;
146 }
147
148 /*
149  * import_kfunc -       import a kernel function that was mistakenly left
150  *                      off the exports list
151  *
152  * NOTE:
153  *      We are assuming that the functions we are importing from the
154  *      kernel really are within the kernel.  If they are actually
155  *      exported from some other kernel extension (but referenced in
156  *      the /unix symbol table) we are in trouble.
157  */
158 #ifdef __XCOFF64__
159 u_int64 *myg_toc;
160 #else
161 u_int32 *myg_toc;
162 #endif
163
164 import_kfunc(struct k_func * kfp)
165 {
166     sym_t *sym;
167     int i, pri;
168 #if 0
169     static caddr_t *g_toc;
170 #endif
171
172     if (!myg_toc) {
173 #ifdef __XCOFF64__
174         sym = sym_lookup("ktoc", 0);
175 #else
176         sym = sym_lookup("g_toc", 0);
177 #endif
178         if (!sym) {
179             printf("\nimport: can't ascertain kernel's TOC\n");
180             return EINVAL;
181         }
182         myg_toc = sym->n_value;
183     }
184
185     sym = sym_lookup(kfp->name, 0);
186     if (!sym) {
187         printf("\nimport: function `%s' not found\n", kfp->name);
188         return EINVAL;
189     }
190
191     kfp->fdesc[0] = sym->n_value;
192     kfp->fdesc[1] = *myg_toc;
193     kfp->fdesc[2] = 0;
194
195 #ifdef __XCOFF64__
196     *(u_int64 **) kfp->fpp = kfp->fdesc;
197 #else
198     *(u_int **) kfp->fpp = kfp->fdesc;
199 #endif
200
201     return 0;
202 }
203
204 /*
205  * import_kvar -        import a kernel variable that was mistakenly left
206  *                      off the exports list
207  */
208 import_kvar(struct k_var * kvp, caddr_t * toc)
209 {
210     sym_t *sym;
211     int i, pri;
212     label_t jmpbuf;
213
214     switch (setjmpx(&jmpbuf)) {
215     case 0:
216         break;
217
218     default:
219         return EINVAL;
220     }
221
222     sym = sym_lookup(kvp->name, 0);
223     if (!sym) {
224         printf("\nimport: variable `%s' not found\n", kvp->name);
225         longjmpx(EINVAL);
226     }
227
228     /*
229      * look through the caller's TOC for the reference to his surrogate
230      * variable.
231      */
232     while (*toc != kvp->varp)
233         ++toc;
234
235     printf("import(%s): replacing my TOC at 0x%x: 0x%8x with 0x%8x\n",
236            kvp->name, toc, *toc, sym->n_value);
237
238     /*
239      * replace reference to surrogate with reference real
240      */
241     pri = i_disable(INTMAX);
242     *toc = (caddr_t) sym->n_value;
243     i_enable(pri);
244
245     clrjmpx(&jmpbuf);
246
247     return 0;
248 }
249
250
251 /*
252  * Call vanilla syscalls
253  */
254 #ifndef AFS_AIX51_ENV
255 osetgroups(ngroups, gidset)
256      int ngroups;
257      gid_t *gidset;
258 {
259     int error;
260
261     error = setgroups(ngroups, gidset);
262     return (error);
263 }
264 #endif
265
266 #ifdef AFS_AIX51_ENV
267 #ifdef AFS_64BIT_KERNEL
268 okioctl(fdes, cmd, arg, ext, arg2, arg3)
269 #else /* AFS_64BIT_KERNEL */
270 okioctl32(fdes, cmd, arg, ext, arg2, arg3)
271 #endif /* AFS_64BIT_KERNEL */
272      int fdes, cmd;
273      caddr_t ext, arg, arg2, arg3;
274 #else
275 okioctl(fdes, cmd, arg, ext)
276      int fdes, cmd, arg;
277      caddr_t ext;
278 #endif
279 {
280     int error;
281
282 #ifdef AFS_AIX51_ENV
283 #ifdef AFS_64BIT_KERNEL
284     error = kioctl(fdes, cmd, arg, ext, arg2, arg3);
285 #else /* AFS_64BIT_KERNEL */
286     error = kioctl32(fdes, cmd, arg, ext, arg2, arg3);
287 #endif /* AFS_64BIT_KERNEL */
288 #else
289     error = kioctl(fdes, cmd, arg, ext);
290 #endif
291     return (error);
292 }
293
294 #ifdef  notdef
295 ocore(signo, sigctx)
296      char signo;
297      struct sigcontext *sigctx;
298 {
299     int error;
300 #include <sys/user.h>
301     u.u_sigflags[signo] |= SA_FULLDUMP; /* XXX */
302     error = core(signo, sigctx);
303     return (error);
304 }
305 #endif