aix-51-support-20030701
[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 /* RCSID("$Header$"); */
18
19 #define _KERNEL
20 #include "sys/types.h"
21 #include "sys/user.h"
22 #include "sys/conf.h"
23 #include "sys/errno.h"
24 #include "sys/device.h"
25 #include "sys/uio.h"
26 #include "sys/pri.h"
27 #include "sys/malloc.h"
28 #include "sym.h"
29 #include "export.h"
30
31 #undef RELOC
32
33 sym_t  *toc_syms;               /* symbol table                 */
34 int     toc_nsyms;              /* # of symbols                 */
35 caddr_t toc_strs;               /* string table                 */
36 int     toc_size;               /* size of toc_syms             */
37
38 /*
39  * export       -       entry point to EXPORT kernel extension
40  *
41  * Input:
42  *      cmd     -       add/delete command
43  *      uiop    -       uio vector describing any config params
44  */
45 export(cmd, uiop)
46 struct uio *uiop; {
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 register struct uio *uiop; {
80         struct k_conf conf;
81         register struct export_nl *np;
82         register sym_t *sym;
83         register err;
84
85         if (err = uiomove((char *)&conf, sizeof (conf), UIO_WRITE, uiop))
86                 return err;
87
88         toc_nsyms = conf.nsyms;
89         toc_size  = conf.symt_sz + conf.str_sz;
90
91         if (toc_nsyms * sizeof (sym_t) != conf.symt_sz
92             || 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          * get rid of the symbol table
136          */
137         if (toc_syms) {
138                 xmfree(toc_syms, kernel_heap);
139                 toc_syms = 0;
140                 toc_size = 0;
141                 toc_strs = 0;
142         }
143
144         return 0;
145 }
146
147 /*
148  * import_kfunc -       import a kernel function that was mistakenly left
149  *                      off the exports list
150  *
151  * NOTE:
152  *      We are assuming that the functions we are importing from the
153  *      kernel really are within the kernel.  If they are actually
154  *      exported from some other kernel extension (but referenced in
155  *      the /unix symbol table) we are in trouble.
156  */
157 #ifdef __XCOFF64__
158         u_int64 *myg_toc;
159 #else
160         u_int32 *myg_toc;
161 #endif
162
163 import_kfunc(struct k_func *kfp) {
164         register sym_t *sym;
165         register i, pri;
166 #if 0
167         static caddr_t *g_toc;
168 #endif
169
170         if (!myg_toc) {
171 #ifdef __XCOFF64__
172                 sym = sym_lookup("ktoc", 0);
173 #else
174                 sym = sym_lookup("g_toc", 0);
175 #endif
176                 if (!sym) {
177                         printf("\nimport: can't ascertain kernel's TOC\n");
178                         return EINVAL;
179                 }
180                 myg_toc = sym->n_value;
181         }
182
183         sym = sym_lookup(kfp->name, 0);
184         if (!sym) {
185                 printf("\nimport: function `%s' not found\n", kfp->name);
186                 return EINVAL;
187         }
188
189         kfp->fdesc[0] = sym->n_value;
190         kfp->fdesc[1] = *myg_toc;
191         kfp->fdesc[2] = 0;
192
193 #ifdef __XCOFF64__
194         *(u_int64**) kfp->fpp = kfp->fdesc;
195 #else
196         *(u_int **) kfp->fpp = kfp->fdesc;
197 #endif
198
199         return 0;
200 }
201
202 /*
203  * import_kvar -        import a kernel variable that was mistakenly left
204  *                      off the exports list
205  */
206 import_kvar(struct k_var *kvp, caddr_t *toc) {
207         register sym_t *sym;
208         register i, pri;
209         label_t jmpbuf;
210
211         switch (setjmpx(&jmpbuf)) {
212             case 0:
213                 break;
214
215             default:
216                 return EINVAL;
217         }
218
219         sym = sym_lookup(kvp->name, 0);
220         if (!sym) {
221                 printf("\nimport: variable `%s' not found\n", kvp->name);
222                 longjmpx(EINVAL);
223         }
224
225         /*
226          * look through the caller's TOC for the reference to his surrogate
227          * variable.
228          */
229         while (*toc != kvp->varp)
230                 ++toc;
231
232         printf("import(%s): replacing my TOC at 0x%x: 0x%8x with 0x%8x\n"
233                , kvp->name, toc, *toc, sym->n_value);
234
235         /*
236          * replace reference to surrogate with reference real
237          */
238         pri = i_disable(INTMAX);
239         *toc = (caddr_t) sym->n_value;
240         i_enable(pri);
241
242         clrjmpx(&jmpbuf);
243
244         return 0;
245 }
246
247
248 /*
249  * Call vanilla syscalls
250  */
251 #ifndef AFS_AIX51_ENV
252 osetgroups(ngroups, gidset)
253     int ngroups;
254     gid_t *gidset;
255 {
256     int error;
257
258     error = setgroups(ngroups, gidset);
259     return (error);
260 }
261 #endif
262
263 #ifdef AFS_AIX51_ENV
264 #ifdef AFS_64BIT_KERNEL
265 okioctl(fdes, cmd, arg, ext, arg2, arg3)
266 #else /* AFS_64BIT_KERNEL */
267 okioctl32(fdes, cmd, arg, ext, arg2, arg3)
268 #endif /* AFS_64BIT_KERNEL */
269     int fdes, cmd;
270     caddr_t ext, arg, arg2, arg3;
271 #else
272 okioctl(fdes, cmd, arg, ext)
273     int fdes, cmd, arg;
274     caddr_t ext;
275 #endif
276 {
277     int error;
278     
279 #ifdef AFS_AIX51_ENV
280 #ifdef AFS_64BIT_KERNEL
281     error = kioctl(fdes, cmd, arg, ext, arg2, arg3);
282 #else /* AFS_64BIT_KERNEL */
283     error = kioctl32(fdes, cmd, arg, ext, arg2, arg3);
284 #endif /* AFS_64BIT_KERNEL */
285 #else
286     error = kioctl(fdes, cmd, arg, ext);
287 #endif
288     return (error);
289 }
290
291 #ifdef  notdef
292 ocore(signo, sigctx)
293     char signo;
294     struct sigcontext *sigctx;
295 {
296     int error;
297 #include <sys/user.h>
298     u.u_sigflags[signo] |= SA_FULLDUMP;         /* XXX */
299     error = core(signo, sigctx);
300     return (error);
301 }
302 #endif
303