mirror of
https://git.openafs.org/openafs.git
synced 2025-01-21 00:10:15 +00:00
b0601bd700
don't build the 64 bit stuff on aix 4 |
||
---|---|---|
.. | ||
.cvsignore | ||
cfgafs.c | ||
cfgexport.c | ||
export4-64.exp | ||
export4.exp | ||
export5-64.exp | ||
export5.exp | ||
export.c | ||
export.h | ||
extras.exp | ||
Makefile.in | ||
README | ||
sym.h | ||
symtab.c |
Copyright 2000, International Business Machines Corporation and others. All Rights Reserved. This software has been released under the terms of the IBM Public License. For details, see the LICENSE file in the top-level source directory or online at http://www.openafs.org/dl/license10.html EXPORT is an aix3.1 kernel extension whose sole purpose in life is to provide access to kernel symbols that were mistakenly (or purposefully) omitted from the kernel exports list. The way EXPORT works is as follows: /etc/cfgexport -a /etc/export.ext loads in the EXPORT kernel extension, and passes all relevant info from the /unix symbol table. THIS HAD BETTER BE THE SAME KERNEL THAT WAS BOOTED FROM! /etc/export.ext is the load module for the EXPORT kernel extension. When it is loaded, is slurps in the symbol table information, and makes available the following: import_kfunc(struct k_func *kfp) import_kvar(struct k_var *kvp, ulong *toc) The relevant data structures are defined in "export.h": /* * kernel function import */ struct k_func { void *(**fpp)(); /* ^ to ^ to function we import */ char *name; /* ^ to symbol name */ ulong fdesc[3]; /* function descriptor storage */ }; /* * kernel variable import */ struct k_var { void *varp; /* ^ to surrogate variable */ char *name; /* ^ to symbol name */ }; import_kfunc() can be used to acquire a function pointer to most kernel functions. import_kvar() can be used to redirect references to a local surrogate variable to the kernel variable. An example of usage would be: #include "export.h" static void (*kluge_iput)(); /* ^ to kernel's `iput()' */ void *u; /* surrogate `u.' variable */ void *vnodefops; /* surrogate `vnodefops' var */ struct k_func kfuncs[] = { { &kluge_iput, ".iput" }, { 0 } }; struct k_var kvars[] = { { (void *) &u, "u" }, { (void *) &vnodefops, "vnodefops" }, { 0 }, }; kluge_init() { register struct k_func *kfp; register struct k_var *kvp; register ulong *toc; toc = (ulong *) get_toc(); for (kfp = kfuncs; kfp->name; ++kfp) import_kfunc(kfp); for (kvp = kvars; kvp->name; ++kvp) import_kvar(kvp, toc); } iput(ip) struct inode *ip; { return (*kluge_iput)(ip); } Note the call to `get_toc()'. This returns the value that will be in the TOC register (a dedicated general purpose register, R2, that is used as the base register to the `table-of-contents' area that is where references to all global variables is placed). The TOC is distinct for each kernel extension. There is code for `get_toc' in afs/misc.s. It is not possible to import functions the same as variables. If one were to replace a TOC entry for a function, one would most likely panic very soon after calling that function, if one were lucky! The calling sequence for inter-module (inter-extension) differs from that of intra-module (intra-extension), in order to save/restore the TOC register, and load the correct TOC register value for the called code. Calls through pointers to functions must already handle this, so importing functions is done by constructing function pointers, and calling into the kernel with them. Note also that is is not possible (currently) to import functions (in the above manner) that are provided by other kernel extensions. This is due to the fact that import_kfunc() uses the kernel's TOC register value when constructing the function descriptors, rather than the correct one for the kernel extension in which the target function resides. Since the set of functions that is available is restricted (normally) to those described in /unix's symbol table, this is not usually a problem. When the /unix symbol table explicitly refers to a function that it knows to be provided by subsequently loaded extension, there may or may not be a problem, depending on how the glue code generated in the kernel to make the external call interacts/conflicts with the `call thru pointer' code. I can't remember this off the top of my head just now... Enjoy!