diff options
29 files changed, 827 insertions, 375 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c index 1e7c86d..847ab2a 100644 --- a/sys/alpha/alpha/elf_machdep.c +++ b/sys/alpha/alpha/elf_machdep.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: elf_machdep.c,v 1.1 1998/09/11 08:47:02 dfr Exp $ */ #include <sys/param.h> @@ -38,73 +38,81 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) { Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); + Elf_Addr *where; + Elf_Addr addr, tmp_value; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; - switch (ELF_R_TYPE(rela->r_info)) { + switch (type) { + case ELF_RELOC_REL: + rel = (Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("elf_reloc: unknown relocation mode %d\n", type); + } - case R_ALPHA_REFQUAD: { - Elf_Addr addr; - Elf_Addr tmp_value; + switch (rtype) { + case R_ALPHA_REFQUAD: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; + addr += addend; + if (*where != addr) + *where = addr; + break; - tmp_value = addr + *where + rela->r_addend; - if (*where != tmp_value) - *where = tmp_value; - } - break; - - case R_ALPHA_GLOB_DAT: { - Elf_Addr addr; - + case R_ALPHA_GLOB_DAT: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_JMP_SLOT: { + case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - Elf_Addr addr; - addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_RELATIVE: { - *where += relocbase; - } - break; + case R_ALPHA_RELATIVE: + addr = relocbase + addend; + if (*where != addr) + *where = addr; + break; - case R_ALPHA_COPY: { + case R_ALPHA_COPY: /* * There shouldn't be copy relocations in kernel * objects. */ printf("kldload: unexpected R_COPY relocation\n"); return -1; - } - break; default: printf("kldload: unexpected relocation type %d\n", - ELF_R_TYPE(rela->r_info)); + rtype); return -1; } return(0); diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index 5600111..cf8c021 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.35 1998/10/05 16:37:36 jfieber Exp $ + * $Id: linux_sysvec.c,v 1.36 1998/10/11 21:08:02 alex Exp $ */ /* XXX we use functions that might not exist. */ @@ -52,6 +52,7 @@ #include <vm/vm_extern.h> #include <sys/exec.h> #include <sys/kernel.h> +#include <sys/module.h> #include <machine/cpu.h> #include <i386/linux/linux.h> @@ -447,31 +448,49 @@ Elf32_Brandinfo *linux_brandlist[] = { NULL }; -#ifndef LKM /* * XXX: this is WRONG, it needs to be SI_SUB_EXEC, but this is just at the * "proof of concept" stage and will be fixed shortly */ -static void linux_elf_init __P((void *dummy)); +static int linux_elf_modevent __P((module_t mod, modeventtype_t type, void *data)); -static void -linux_elf_init(dummy) - void *dummy; +static int +linux_elf_modevent(module_t mod, modeventtype_t type, void *data) { Elf32_Brandinfo **brandinfo; int error; error = 0; - for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; ++brandinfo) - if (elf_insert_brand_entry(*brandinfo) < 0) - error = 1; - - if (error) - printf("cannot insert Linux elf brand handler\n"); - else if (bootverbose) - printf("Linux-ELF exec handler installed\n"); + switch(type) { + case MOD_LOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf_insert_brand_entry(*brandinfo) < 0) + error = EINVAL; + if (error) + printf("cannot insert Linux elf brand handler\n"); + else if (bootverbose) + printf("Linux-ELF exec handler installed\n"); + break; + case MOD_UNLOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf_remove_brand_entry(*brandinfo) < 0) + error = EINVAL; + if (error) + printf("Could not deinstall ELF interpreter entry\n"); + else if (bootverbose) + printf("Linux-elf exec handler removed\n"); + break; + default: + break; + } + return error; } - -SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, linux_elf_init, NULL); -#endif +static moduledata_t linux_elf_mod = { + "linuxelf", + linux_elf_modevent, + 0 +}; +DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index ffa914a..eae2f4f 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: elf_machdep.c,v 1.1 1998/10/09 20:35:45 peter Exp $ + * $Id: elf_machdep.c,v 1.2 1998/10/09 20:38:03 peter Exp $ */ #include <sys/param.h> @@ -38,38 +38,61 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) { Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); + Elf_Addr *where; Elf_Addr addr, tmp_value; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; - switch (ELF_R_TYPE(rela->r_info)) { + switch (type) { + case ELF_RELOC_REL: + rel = (Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("unknown reloc type %d\n", type); + } + + switch (rtype) { - case R_386_NONE: + case R_386_NONE: /* none */ break; - case R_386_32: + case R_386_32: /* S + A */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - - addr += rela->r_addend; + addr += addend; if (*where != addr) *where = addr; break; - case R_386_PC32: + case R_386_PC32: /* S + A - P */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - - addr += *where - (Elf_Addr)where + rela->r_addend; + addr += addend - (Elf_Addr)where; if (*where != addr) *where = addr; break; - case R_386_COPY: + case R_386_COPY: /* none */ /* * There shouldn't be copy relocations in kernel * objects. @@ -78,22 +101,25 @@ elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) return -1; break; - case R_386_GLOB_DAT: + case R_386_GLOB_DAT: /* S */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; break; - case R_386_RELATIVE: - *where += relocbase; + case R_386_RELATIVE: /* B + A */ + addr = relocbase + addend; + if (*where != addr) + *where = addr; break; default: printf("kldload: unexpected relocation type %d\n", - ELF_R_TYPE(rela->r_info)); + rtype); return -1; } return(0); diff --git a/sys/gnu/i386/fpemul/fpu_entry.c b/sys/gnu/i386/fpemul/fpu_entry.c index 1d8b44d..bde2ef6 100644 --- a/sys/gnu/i386/fpemul/fpu_entry.c +++ b/sys/gnu/i386/fpemul/fpu_entry.c @@ -55,7 +55,7 @@ * * W. Metzenthen June 1994. * - * $Id: fpu_entry.c,v 1.13 1997/07/20 08:46:23 bde Exp $ + * $Id: fpu_entry.c,v 1.14 1998/08/16 01:21:48 bde Exp $ * */ @@ -515,15 +515,35 @@ gnufpu_mod(struct lkm_table *lkmtp, int cmd, int ver) } #else /* !LKM */ -static void -gnufpu_init(void *unused) +static int +gnufpu_modevent(module_t mod, modeventtype_t type, void *unused) { - if (pmath_emulate) - printf("Another Math emulator already present\n"); - else - pmath_emulate = math_emulate; + switch (type) { + case MOD_LOAD: + if (pmath_emulate) { + printf("Another Math emulator already present\n"); + return EACCES; + } else + pmath_emulate = math_emulate; + break; + case MOD_UNLOAD: + if (pmath_emulate != math_emulate) { + printf("Cannot unload another math emulator\n"); + return EACCES; + } + pmath_emulate = 0; + break; + default: + break; + } + return 0; + } - -SYSINIT(gnufpu, SI_SUB_CPU, SI_ORDER_ANY, gnufpu_init, NULL); +moduledata_t gnufpumod = { + "gnufpu", + gnufpu_modevent, + 0 +}; +DECLARE_MODULE(gnufpu, gnufpu_modevent, SI_SUB_PSEUDO, SI_ORDER_ANY); #endif /* LKM */ diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index ffa914a..eae2f4f 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: elf_machdep.c,v 1.1 1998/10/09 20:35:45 peter Exp $ + * $Id: elf_machdep.c,v 1.2 1998/10/09 20:38:03 peter Exp $ */ #include <sys/param.h> @@ -38,38 +38,61 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) { Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); + Elf_Addr *where; Elf_Addr addr, tmp_value; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; - switch (ELF_R_TYPE(rela->r_info)) { + switch (type) { + case ELF_RELOC_REL: + rel = (Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("unknown reloc type %d\n", type); + } + + switch (rtype) { - case R_386_NONE: + case R_386_NONE: /* none */ break; - case R_386_32: + case R_386_32: /* S + A */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - - addr += rela->r_addend; + addr += addend; if (*where != addr) *where = addr; break; - case R_386_PC32: + case R_386_PC32: /* S + A - P */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - - addr += *where - (Elf_Addr)where + rela->r_addend; + addr += addend - (Elf_Addr)where; if (*where != addr) *where = addr; break; - case R_386_COPY: + case R_386_COPY: /* none */ /* * There shouldn't be copy relocations in kernel * objects. @@ -78,22 +101,25 @@ elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) return -1; break; - case R_386_GLOB_DAT: + case R_386_GLOB_DAT: /* S */ + if (sym == NULL) + return -1; addr = (Elf_Addr)linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; break; - case R_386_RELATIVE: - *where += relocbase; + case R_386_RELATIVE: /* B + A */ + addr = relocbase + addend; + if (*where != addr) + *where = addr; break; default: printf("kldload: unexpected relocation type %d\n", - ELF_R_TYPE(rela->r_info)); + rtype); return -1; } return(0); diff --git a/sys/i386/i386/math_emulate.c b/sys/i386/i386/math_emulate.c index 04f7377..df44b5f 100644 --- a/sys/i386/i386/math_emulate.c +++ b/sys/i386/i386/math_emulate.c @@ -6,7 +6,7 @@ * [expediant "port" of linux 8087 emulator to 386BSD, with apologies -wfj] * * from: 386BSD 0.1 - * $Id: math_emulate.c,v 1.26 1997/07/20 11:00:32 bde Exp $ + * $Id: math_emulate.c,v 1.27 1998/07/15 09:01:18 bde Exp $ */ /* @@ -1571,15 +1571,32 @@ fpu_mod(struct lkm_table *lkmtp, int cmd, int ver) } #else /* !LKM */ -static void -fpu_init(void *unused) +static int +fpu_modevent(module_t mod, modeventtype_t type, void *unused) { - if (pmath_emulate) - printf("Another Math emulator already present\n"); - else - pmath_emulate = math_emulate; + switch (type) { + case MOD_LOAD: + if (pmath_emulate) + printf("Another Math emulator already present\n"); + else + pmath_emulate = math_emulate; + break; + case MOD_UNLOAD: + if (pmath_emulate != math_emulate) { + printf("Cannot unload another math emulator\n"); + return EACCES; + } + pmath_emulate = 0; + default: + break; + } + return 0; } - -SYSINIT(fpu, SI_SUB_CPU, SI_ORDER_ANY, fpu_init, NULL); +moduledata_t fpumod = { + "fpu", + fpu_modevent, + 0 +}; +DECLARE_MODULE(fpu, fpumod, SI_SUB_PSEUDO, SI_ORDER_ANY); #endif /* LKM */ diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c index 23c1344..7793f4c 100644 --- a/sys/i386/ibcs2/imgact_coff.c +++ b/sys/i386/ibcs2/imgact_coff.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_coff.c,v 1.31 1998/08/16 01:21:49 bde Exp $ + * $Id: imgact_coff.c,v 1.32 1998/10/13 08:24:36 dg Exp $ */ #include <sys/param.h> @@ -478,4 +478,4 @@ exec_coff_imgact(imgp) * correct directive to use. Do not staticize; used by coff LKM. */ const struct execsw coff_execsw = { exec_coff_imgact, "coff" }; -TEXT_SET(execsw_set, coff_execsw); +EXEC_SET(coff, coff_execsw); diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c index b91b6ab..72f846c 100644 --- a/sys/i386/linux/imgact_linux.c +++ b/sys/i386/linux/imgact_linux.c @@ -28,7 +28,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_linux.c,v 1.28 1998/07/29 16:43:00 bde Exp $ + * $Id: imgact_linux.c,v 1.29 1998/08/16 01:21:50 bde Exp $ */ #include <sys/param.h> @@ -237,5 +237,5 @@ exec_linux_imgact(imgp) * correct directive to use. Do not staticize; used by Linux LKM. */ const struct execsw linux_execsw = { exec_linux_imgact, "linux a.out" }; -TEXT_SET(execsw_set, linux_execsw); +EXEC_SET(linuxaout, linux_execsw); diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 5600111..cf8c021 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.35 1998/10/05 16:37:36 jfieber Exp $ + * $Id: linux_sysvec.c,v 1.36 1998/10/11 21:08:02 alex Exp $ */ /* XXX we use functions that might not exist. */ @@ -52,6 +52,7 @@ #include <vm/vm_extern.h> #include <sys/exec.h> #include <sys/kernel.h> +#include <sys/module.h> #include <machine/cpu.h> #include <i386/linux/linux.h> @@ -447,31 +448,49 @@ Elf32_Brandinfo *linux_brandlist[] = { NULL }; -#ifndef LKM /* * XXX: this is WRONG, it needs to be SI_SUB_EXEC, but this is just at the * "proof of concept" stage and will be fixed shortly */ -static void linux_elf_init __P((void *dummy)); +static int linux_elf_modevent __P((module_t mod, modeventtype_t type, void *data)); -static void -linux_elf_init(dummy) - void *dummy; +static int +linux_elf_modevent(module_t mod, modeventtype_t type, void *data) { Elf32_Brandinfo **brandinfo; int error; error = 0; - for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; ++brandinfo) - if (elf_insert_brand_entry(*brandinfo) < 0) - error = 1; - - if (error) - printf("cannot insert Linux elf brand handler\n"); - else if (bootverbose) - printf("Linux-ELF exec handler installed\n"); + switch(type) { + case MOD_LOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf_insert_brand_entry(*brandinfo) < 0) + error = EINVAL; + if (error) + printf("cannot insert Linux elf brand handler\n"); + else if (bootverbose) + printf("Linux-ELF exec handler installed\n"); + break; + case MOD_UNLOAD: + for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; + ++brandinfo) + if (elf_remove_brand_entry(*brandinfo) < 0) + error = EINVAL; + if (error) + printf("Could not deinstall ELF interpreter entry\n"); + else if (bootverbose) + printf("Linux-elf exec handler removed\n"); + break; + default: + break; + } + return error; } - -SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, linux_elf_init, NULL); -#endif +static moduledata_t linux_elf_mod = { + "linuxelf", + linux_elf_modevent, + 0 +}; +DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index 7f1d6ec..446946e 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: imgact_aout.c,v 1.41 1998/07/15 05:00:26 bde Exp $ + * $Id: imgact_aout.c,v 1.42 1998/09/14 05:36:49 jdp Exp $ */ #include <sys/param.h> @@ -303,4 +303,4 @@ out: * correct directive to use. */ static const struct execsw aout_execsw = { exec_aout_imgact, "a.out" }; -TEXT_SET(execsw_set, aout_execsw); +EXEC_SET(aout, aout_execsw); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 26ba584..c33c6be 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_elf.c,v 1.38 1998/10/13 08:24:40 dg Exp $ + * $Id: imgact_elf.c,v 1.39 1998/10/15 09:52:19 dfr Exp $ */ #include "opt_rlimit.h" @@ -1042,4 +1042,4 @@ elf_putnote(void *dst, size_t *off, const char *name, int type, * correct directive to use. */ static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; -TEXT_SET(execsw_set, elf_execsw); +EXEC_SET(elf, elf_execsw); diff --git a/sys/kern/imgact_gzip.c b/sys/kern/imgact_gzip.c index df68edb..d666a87 100644 --- a/sys/kern/imgact_gzip.c +++ b/sys/kern/imgact_gzip.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: imgact_gzip.c,v 1.33 1998/06/16 14:36:40 bde Exp $ + * $Id: imgact_gzip.c,v 1.34 1998/07/15 05:00:26 bde Exp $ * * This module handles execution of a.out files which have been run through * "gzip". This saves diskspace, but wastes cpu-cycles and VM. @@ -375,4 +375,4 @@ Flush(void *vp, u_char * ptr, u_long siz) */ static const struct execsw gzip_execsw = {exec_gzip_imgact, "gzip"}; -TEXT_SET(execsw_set, gzip_execsw); +EXEC_SET(execgzip, gzip_execsw); diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c index c4d04b5..e72b86d 100644 --- a/sys/kern/imgact_shell.c +++ b/sys/kern/imgact_shell.c @@ -23,10 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: imgact_shell.c,v 1.15 1997/04/23 22:07:04 ache Exp $ + * $Id: imgact_shell.c,v 1.16 1997/08/02 14:31:23 bde Exp $ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/sysproto.h> #include <sys/exec.h> #include <sys/imgact.h> @@ -134,4 +135,4 @@ exec_shell_imgact(imgp) * correct directive to use. */ static const struct execsw shell_execsw = { exec_shell_imgact, "#!" }; -TEXT_SET(execsw_set, shell_execsw); +EXEC_SET(shell, shell_execsw); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a788629..d30d9c2 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_exec.c,v 1.85 1998/08/24 08:39:38 dfr Exp $ + * $Id: kern_exec.c,v 1.86 1998/09/04 08:06:55 dfr Exp $ */ #include <sys/param.h> @@ -41,6 +41,7 @@ #include <sys/wait.h> #include <sys/proc.h> #include <sys/pioctl.h> +#include <sys/malloc.h> #include <sys/namei.h> #include <sys/sysent.h> #include <sys/shm.h> @@ -71,11 +72,10 @@ SYSCTL_INTPTR(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, ""); static caddr_t usrstack = (caddr_t)USRSTACK; SYSCTL_INTPTR(_kern, KERN_USRSTACK, usrstack, 0, &usrstack, 0, ""); /* - * execsw_set is constructed for us by the linker. Each of the items - * is a pointer to a `const struct execsw', hence the double pointer here. + * Each of the items is a pointer to a `const struct execsw', hence the + * double pointer here. */ -static const struct execsw **execsw = - (const struct execsw **)&execsw_set.ls_items[0]; +static const struct execsw **execsw; #ifndef _SYS_SYSPROTO_H_ struct execve_args { @@ -695,3 +695,64 @@ exec_check_permissions(imgp) return (0); } + +/* + * Exec handler registration + */ +int +exec_register(execsw_arg) + const struct execsw *execsw_arg; +{ + const struct execsw **es, **xs, **newexecsw; + int count = 2; /* New slot and trailing NULL */ + + if (execsw) + for (es = execsw; *es; es++) + count++; + newexecsw = malloc(count * sizeof(*es), M_TEMP, M_WAITOK); + if (newexecsw == NULL) + return ENOMEM; + xs = newexecsw; + if (execsw) + for (es = execsw; *es; es++) + *xs++ = *es; + *xs++ = execsw_arg; + *xs = NULL; + if (execsw) + free(execsw, M_TEMP); + execsw = newexecsw; + return 0; +} + +int +exec_unregister(execsw_arg) + const struct execsw *execsw_arg; +{ + const struct execsw **es, **xs, **newexecsw; + int count = 1; + + if (execsw == NULL) + panic("unregister with no handlers left?\n"); + + for (es = execsw; *es; es++) { + if (*es == execsw_arg) + break; + } + if (*es == NULL) + return ENOENT; + for (es = execsw; *es; es++) + if (*es != execsw_arg) + count++; + newexecsw = malloc(count * sizeof(*es), M_TEMP, M_WAITOK); + if (newexecsw == NULL) + return ENOMEM; + xs = newexecsw; + for (es = execsw; *es; es++) + if (*es != execsw_arg) + *xs++ = *es; + *xs = NULL; + if (execsw) + free(execsw, M_TEMP); + execsw = newexecsw; + return 0; +} diff --git a/sys/kern/kern_lkm.c b/sys/kern/kern_lkm.c index 9061180..f7ca01d 100644 --- a/sys/kern/kern_lkm.c +++ b/sys/kern/kern_lkm.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_lkm.c,v 1.55 1998/09/05 17:13:27 bde Exp $ + * $Id: kern_lkm.c,v 1.56 1998/09/07 05:42:15 bde Exp $ */ #include "opt_devfs.h" @@ -650,11 +650,15 @@ _lkm_vfs(lkmtp, cmd) /* like in vfs_op_init */ for(i = 0; args->lkm_vnodeops->ls_items[i]; i++) { - const struct vnodeopv_desc *opv = + struct vnodeopv_desc *opv = (struct vnodeopv_desc *) args->lkm_vnodeops->ls_items[i]; *(opv->opv_desc_vector_p) = NULL; } - vfs_opv_init((struct vnodeopv_desc **)args->lkm_vnodeops->ls_items); + for(i = 0; args->lkm_vnodeops->ls_items[i]; i++) { + struct vnodeopv_desc *opv = (struct vnodeopv_desc *) + args->lkm_vnodeops->ls_items[i]; + vfs_opv_init(opv); + } /* * Call init function for this VFS... @@ -834,40 +838,21 @@ _lkm_exec(lkmtp, cmd) /* don't load twice! */ if (lkmexists(lkmtp)) return(EEXIST); - if ((i = args->lkm_offset) == LKM_ANON) { /* auto */ - /* - * Search the table looking for a slot... - */ - for (i = 0; execsw[i] != NULL; i++) - if (execsw[i]->ex_imgact == NULL) - break; /* found it! */ - /* out of allocable slots? */ - if (execsw[i] == NULL) { - err = ENFILE; - break; - } - } else { /* assign */ + if (args->lkm_offset != LKM_ANON) { /* auto */ err = EINVAL; break; } - /* save old */ - bcopy(&execsw[i], &(args->lkm_oldexec), sizeof(struct execsw*)); - - /* replace with new */ - bcopy(&(args->lkm_exec), &execsw[i], sizeof(struct execsw*)); + err = exec_register(args->lkm_exec); /* done! */ - args->lkm_offset = i; /* slot in execsw[] */ + args->lkm_offset = 0; /* slot in execsw[] */ break; case LKM_E_UNLOAD: - /* current slot... */ - i = args->lkm_offset; - /* replace current slot contents with old contents */ - bcopy(&(args->lkm_oldexec), &execsw[i], sizeof(struct execsw*)); + err = exec_unregister(args->lkm_exec); break; @@ -877,16 +862,6 @@ _lkm_exec(lkmtp, cmd) return(err); } -/* XXX: This is bogus. we should find a better method RSN! */ -static const struct execsw lkm_exec_dummy1 = { NULL, "lkm" }; -static const struct execsw lkm_exec_dummy2 = { NULL, "lkm" }; -static const struct execsw lkm_exec_dummy3 = { NULL, "lkm" }; -static const struct execsw lkm_exec_dummy4 = { NULL, "lkm" }; -TEXT_SET(execsw_set, lkm_exec_dummy1); -TEXT_SET(execsw_set, lkm_exec_dummy2); -TEXT_SET(execsw_set, lkm_exec_dummy3); -TEXT_SET(execsw_set, lkm_exec_dummy4); - /* * This code handles the per-module type "wiring-in" of loadable modules * into existing kernel tables. For "LM_MISC" modules, wiring and unwiring diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index b2d7b21..5555df3 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_module.c,v 1.9 1998/10/03 11:05:45 dfr Exp $ + * $Id: kern_module.c,v 1.10 1998/10/10 00:03:07 peter Exp $ */ #include <sys/param.h> @@ -64,7 +64,7 @@ module_init(void* arg) at_shutdown(module_shutdown, 0, SHUTDOWN_POST_SYNC); } -SYSINIT(module, SI_SUB_KLD, SI_ORDER_ANY, module_init, 0); +SYSINIT(module, SI_SUB_KLD, SI_ORDER_FIRST, module_init, 0); static void module_shutdown(int arg1, void* arg2) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index e154f4b..c3e221f 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -37,7 +37,7 @@ * SUCH DAMAGE. * * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 - * $Id: kern_sysctl.c,v 1.76 1998/09/05 14:30:10 bde Exp $ + * $Id: kern_sysctl.c,v 1.77 1998/09/05 17:13:27 bde Exp $ */ #include "opt_compat.h" @@ -82,6 +82,8 @@ sysctl_order_cmp(const void *a, const void *b) pa = (struct sysctl_oid const * const *)a; pb = (struct sysctl_oid const * const *)b; + if (*pa == NULL && *pb == NULL) + return 0; if (*pa == NULL) return (1); if (*pb == NULL) diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 5495e92..26b6213 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link_elf.c,v 1.5 1998/10/13 09:27:00 peter Exp $ + * $Id: link_elf.c,v 1.6 1998/10/15 17:16:24 peter Exp $ */ #include <sys/param.h> @@ -771,12 +771,12 @@ out: } static const char * -symbol_name(elf_file_t ef, const Elf_Rela *rela) +symbol_name(elf_file_t ef, Elf_Word r_info) { const Elf_Sym *ref; - if (ELF_R_SYM(rela->r_info)) { - ref = ef->symtab + ELF_R_SYM(rela->r_info); + if (ELF_R_SYM(r_info)) { + ref = ef->symtab + ELF_R_SYM(r_info); return ef->strtab + ref->st_name; } else return NULL; @@ -790,43 +790,54 @@ relocate_file(linker_file_t lf) const Elf_Rel *rel; const Elf_Rela *relalim; const Elf_Rela *rela; + const char *symname; /* Perform relocations without addend if there are any: */ - rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize); - for (rel = ef->rel; ef->rel != NULL && rel < rellim; rel++) { - Elf_Rela locrela; - - locrela.r_info = rel->r_info; - locrela.r_offset = rel->r_offset; - locrela.r_addend = 0; - if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela))) - return ENOENT; + rel = ef->rel; + if (rel) { + rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize); + while (rel < rellim) { + symname = symbol_name(ef, rel->r_info); + if (elf_reloc(lf, rel, ELF_RELOC_REL, symname)) + return ENOENT; + rel++; + } } /* Perform relocations with addend if there are any: */ - relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize); - for (rela = ef->rela; ef->rela != NULL && rela < relalim; rela++) { - if (elf_reloc(lf, rela, symbol_name(ef, rela))) - return ENOENT; + rela = ef->rela; + if (rela) { + relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize); + while (rela < relalim) { + symname = symbol_name(ef, rela->r_info); + if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname)) + return ENOENT; + rela++; + } } /* Perform PLT relocations without addend if there are any: */ - rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize); - for (rel = ef->pltrel; ef->pltrel != NULL && rel < rellim; rel++) { - Elf_Rela locrela; - - locrela.r_info = rel->r_info; - locrela.r_offset = rel->r_offset; - locrela.r_addend = 0; - if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela))) - return ENOENT; + rel = ef->pltrel; + if (rel) { + rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize); + while (rel < rellim) { + symname = symbol_name(ef, rel->r_info); + if (elf_reloc(lf, rel, ELF_RELOC_REL, symname)) + return ENOENT; + rel++; + } } /* Perform relocations with addend if there are any: */ - relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize); - for (rela = ef->pltrela; ef->pltrela != NULL && rela < relalim; rela++) { - if (elf_reloc(lf, rela, symbol_name(ef, rela))) - return ENOENT; + rela = ef->pltrela; + if (rela) { + relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize); + while (rela < relalim) { + symname = symbol_name(ef, rela->r_info); + if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname)) + return ENOENT; + rela++; + } } return 0; diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 5495e92..26b6213 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link_elf.c,v 1.5 1998/10/13 09:27:00 peter Exp $ + * $Id: link_elf.c,v 1.6 1998/10/15 17:16:24 peter Exp $ */ #include <sys/param.h> @@ -771,12 +771,12 @@ out: } static const char * -symbol_name(elf_file_t ef, const Elf_Rela *rela) +symbol_name(elf_file_t ef, Elf_Word r_info) { const Elf_Sym *ref; - if (ELF_R_SYM(rela->r_info)) { - ref = ef->symtab + ELF_R_SYM(rela->r_info); + if (ELF_R_SYM(r_info)) { + ref = ef->symtab + ELF_R_SYM(r_info); return ef->strtab + ref->st_name; } else return NULL; @@ -790,43 +790,54 @@ relocate_file(linker_file_t lf) const Elf_Rel *rel; const Elf_Rela *relalim; const Elf_Rela *rela; + const char *symname; /* Perform relocations without addend if there are any: */ - rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize); - for (rel = ef->rel; ef->rel != NULL && rel < rellim; rel++) { - Elf_Rela locrela; - - locrela.r_info = rel->r_info; - locrela.r_offset = rel->r_offset; - locrela.r_addend = 0; - if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela))) - return ENOENT; + rel = ef->rel; + if (rel) { + rellim = (const Elf_Rel *) ((caddr_t) ef->rel + ef->relsize); + while (rel < rellim) { + symname = symbol_name(ef, rel->r_info); + if (elf_reloc(lf, rel, ELF_RELOC_REL, symname)) + return ENOENT; + rel++; + } } /* Perform relocations with addend if there are any: */ - relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize); - for (rela = ef->rela; ef->rela != NULL && rela < relalim; rela++) { - if (elf_reloc(lf, rela, symbol_name(ef, rela))) - return ENOENT; + rela = ef->rela; + if (rela) { + relalim = (const Elf_Rela *) ((caddr_t) ef->rela + ef->relasize); + while (rela < relalim) { + symname = symbol_name(ef, rela->r_info); + if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname)) + return ENOENT; + rela++; + } } /* Perform PLT relocations without addend if there are any: */ - rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize); - for (rel = ef->pltrel; ef->pltrel != NULL && rel < rellim; rel++) { - Elf_Rela locrela; - - locrela.r_info = rel->r_info; - locrela.r_offset = rel->r_offset; - locrela.r_addend = 0; - if (elf_reloc(lf, &locrela, symbol_name(ef, &locrela))) - return ENOENT; + rel = ef->pltrel; + if (rel) { + rellim = (const Elf_Rel *) ((caddr_t) ef->pltrel + ef->pltrelsize); + while (rel < rellim) { + symname = symbol_name(ef, rel->r_info); + if (elf_reloc(lf, rel, ELF_RELOC_REL, symname)) + return ENOENT; + rel++; + } } /* Perform relocations with addend if there are any: */ - relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize); - for (rela = ef->pltrela; ef->pltrela != NULL && rela < relalim; rela++) { - if (elf_reloc(lf, rela, symbol_name(ef, rela))) - return ENOENT; + rela = ef->pltrela; + if (rela) { + relalim = (const Elf_Rela *) ((caddr_t) ef->pltrela + ef->pltrelasize); + while (rela < relalim) { + symname = symbol_name(ef, rela->r_info); + if (elf_reloc(lf, rela, ELF_RELOC_RELA, symname)) + return ENOENT; + rela++; + } } return 0; diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index ba9d001..39900c6 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 - * $Id: vfs_init.c,v 1.33 1998/09/05 17:13:27 bde Exp $ + * $Id: vfs_init.c,v 1.34 1998/10/05 11:10:55 obrien Exp $ */ @@ -67,15 +67,26 @@ MALLOC_DEFINE(M_VNODE, "vnodes", "Dynamically allocated vnodes"); static struct vfsconf void_vfsconf; +#ifdef unused extern struct linker_set vfs_opv_descs_; #define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items) - -extern struct linker_set vfs_set; +#endif extern struct vnodeop_desc *vfs_op_descs[]; /* and the operations they perform */ /* + * XXX this bloat just exands the sysctl__vfs linker set a little so that + * we can attach sysctls for VFS modules without expanding the linker set. + * Currently (1998/09/06), only one VFS uses sysctls, so 2 extra linker + * set slots are more than sufficient. + */ +extern struct linker_set sysctl__vfs; +static int mod_xx; +SYSCTL_INT(_vfs, OID_AUTO, mod0, CTLFLAG_RD, &mod_xx, 0, ""); +SYSCTL_INT(_vfs, OID_AUTO, mod1, CTLFLAG_RD, &mod_xx, 0, ""); + +/* * Zone for namei */ struct vm_zone *namei_zone; @@ -103,9 +114,9 @@ struct vm_zone *namei_zone; * it's not a very dynamic "feature". */ void -vfs_opv_init(struct vnodeopv_desc **them) +vfs_opv_init(struct vnodeopv_desc *opv) { - int i, j, k; + int j, k; vop_t ***opv_desc_vector_p; vop_t **opv_desc_vector; struct vnodeopv_entry_desc *opve_descp; @@ -113,76 +124,72 @@ vfs_opv_init(struct vnodeopv_desc **them) /* * Allocate the dynamic vectors and fill them in. */ - for (i=0; them[i]; i++) { - opv_desc_vector_p = them[i]->opv_desc_vector_p; + opv_desc_vector_p = opv->opv_desc_vector_p; + /* + * Allocate and init the vector, if it needs it. + * Also handle backwards compatibility. + */ + if (*opv_desc_vector_p == NULL) { + /* XXX - shouldn't be M_VNODE */ + MALLOC(*opv_desc_vector_p, vop_t **, + vfs_opv_numops * sizeof(vop_t *), M_VNODE, + M_WAITOK); + bzero(*opv_desc_vector_p, + vfs_opv_numops * sizeof(vop_t *)); + DODEBUG(printf("vector at %x allocated\n", + opv_desc_vector_p)); + } + opv_desc_vector = *opv_desc_vector_p; + for (j = 0; opv->opv_desc_ops[j].opve_op; j++) { + opve_descp = &(opv->opv_desc_ops[j]); + /* - * Allocate and init the vector, if it needs it. - * Also handle backwards compatibility. + * Sanity check: is this operation listed + * in the list of operations? We check this + * by seeing if its offest is zero. Since + * the default routine should always be listed + * first, it should be the only one with a zero + * offset. Any other operation with a zero + * offset is probably not listed in + * vfs_op_descs, and so is probably an error. + * + * A panic here means the layer programmer + * has committed the all-too common bug + * of adding a new operation to the layer's + * list of vnode operations but + * not adding the operation to the system-wide + * list of supported operations. */ - if (*opv_desc_vector_p == NULL) { - /* XXX - shouldn't be M_VNODE */ - MALLOC(*opv_desc_vector_p, vop_t **, - vfs_opv_numops * sizeof(vop_t *), M_VNODE, - M_WAITOK); - bzero(*opv_desc_vector_p, - vfs_opv_numops * sizeof(vop_t *)); - DODEBUG(printf("vector at %x allocated\n", - opv_desc_vector_p)); - } - opv_desc_vector = *opv_desc_vector_p; - for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) { - opve_descp = &(them[i]->opv_desc_ops[j]); - - /* - * Sanity check: is this operation listed - * in the list of operations? We check this - * by seeing if its offest is zero. Since - * the default routine should always be listed - * first, it should be the only one with a zero - * offset. Any other operation with a zero - * offset is probably not listed in - * vfs_op_descs, and so is probably an error. - * - * A panic here means the layer programmer - * has committed the all-too common bug - * of adding a new operation to the layer's - * list of vnode operations but - * not adding the operation to the system-wide - * list of supported operations. - */ - if (opve_descp->opve_op->vdesc_offset == 0 && - opve_descp->opve_op->vdesc_offset != - VOFFSET(vop_default)) { - printf("operation %s not listed in %s.\n", - opve_descp->opve_op->vdesc_name, - "vfs_op_descs"); - panic ("vfs_opv_init: bad operation"); - } - /* - * Fill in this entry. - */ - opv_desc_vector[opve_descp->opve_op->vdesc_offset] = - opve_descp->opve_impl; + if (opve_descp->opve_op->vdesc_offset == 0 && + opve_descp->opve_op->vdesc_offset != + VOFFSET(vop_default)) { + printf("operation %s not listed in %s.\n", + opve_descp->opve_op->vdesc_name, + "vfs_op_descs"); + panic ("vfs_opv_init: bad operation"); } + /* + * Fill in this entry. + */ + opv_desc_vector[opve_descp->opve_op->vdesc_offset] = + opve_descp->opve_impl; } /* * Finally, go back and replace unfilled routines * with their default. (Sigh, an O(n^3) algorithm. I * could make it better, but that'd be work, and n is small.) */ - for (i = 0; them[i]; i++) { - opv_desc_vector = *(them[i]->opv_desc_vector_p); - /* - * Force every operations vector to have a default routine. - */ - if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { - panic("vfs_opv_init: operation vector without default routine."); - } - for (k = 0; k<vfs_opv_numops; k++) - if (opv_desc_vector[k] == NULL) - opv_desc_vector[k] = - opv_desc_vector[VOFFSET(vop_default)]; + opv_desc_vector = *(opv->opv_desc_vector_p); + /* + * Force every operations vector to have a default routine. + */ + if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { + panic("vfs_opv_init: operation vector without default routine."); } + for (k = 0; k<vfs_opv_numops; k++) + if (opv_desc_vector[k] == NULL) + opv_desc_vector[k] = + opv_desc_vector[VOFFSET(vop_default)]; } /* @@ -195,11 +202,13 @@ vfs_op_init() DODEBUG(printf("Vnode_interface_init.\n")); DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); +#ifdef unused /* * Set all vnode vectors to a well known value. */ for (i = 0; vfs_opv_descs[i]; i++) *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL; +#endif /* * assign each op to its offset * @@ -212,6 +221,11 @@ vfs_op_init() */ for (i = 0; i < vfs_opv_numops; i++) vfs_op_descs[i]->vdesc_offset = i; +#ifdef unused + /* Finish the job */ + for (i = 0; vfs_opv_descs[i]; i++) + vfs_opv_init(vfs_opv_descs[i]); +#endif } /* @@ -246,26 +260,127 @@ vfsinit(dummy) * Build vnode operation vectors. */ vfs_op_init(); - vfs_opv_init(vfs_opv_descs); /* finish the job */ /* * Initialize each file system type. * Vfs type numbers must be distinct from VFS_GENERIC (and VFS_VFSCONF). */ vattr_null(&va_null); - maxtypenum = VFS_GENERIC + 1; - vfc = (struct vfsconf **)vfs_set.ls_items; - vfsconf = *vfc; - for (; *vfc != NULL; maxtypenum++, vfc++) { - vfsp = *vfc; - vfsp->vfc_next = *(vfc + 1); - vfsp->vfc_typenum = maxtypenum; - if (vfsp->vfc_vfsops->vfs_oid != NULL) { - vfsp->vfc_vfsops->vfs_oid->oid_number = maxtypenum; - sysctl_order_all(); + maxvfsconf = VFS_GENERIC + 1; +} + +int +vfs_register(vfc) + struct vfsconf *vfc; +{ + struct linker_set *l; + struct sysctl_oid **oidpp; + struct vfsconf *vfsp; + int error, i, maxtypenum, exists; + + vfsp = NULL; + exists = 0; + l = &sysctl__vfs; + if (vfsconf) + for (vfsp = vfsconf; vfsp->vfc_next; vfsp = vfsp->vfc_next) + if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) + return EEXIST; + + vfc->vfc_typenum = maxvfsconf++; + if (vfc->vfc_vfsops->vfs_oid != NULL) { + oidpp = (struct sysctl_oid **)l->ls_items; + for (i = l->ls_length; i-- && !exists; oidpp++) + if (*oidpp == vfc->vfc_vfsops->vfs_oid) + exists = 1; + } + if (exists == 0 && vfc->vfc_vfsops->vfs_oid != NULL) { + oidpp = (struct sysctl_oid **)l->ls_items; + for (i = l->ls_length; i--; oidpp++) { + if (*oidpp == NULL || + *oidpp == &sysctl___vfs_mod0 || + *oidpp == &sysctl___vfs_mod1) { + *oidpp = vfc->vfc_vfsops->vfs_oid; + (*oidpp)->oid_number = vfc->vfc_typenum; + sysctl_order_all(); + break; + } } - (*vfsp->vfc_vfsops->vfs_init)(vfsp); } - /* next vfc_typenum to be used */ - maxvfsconf = maxtypenum; + if (vfsp) + vfsp->vfc_next = vfc; + else + vfsconf = vfc; + vfc->vfc_next = NULL; + + /* + * Call init function for this VFS... + */ + (*(vfc->vfc_vfsops->vfs_init))(vfc); + + return 0; } + +/* + * To be called at SI_SUB_VFS, SECOND, for each VFS before any are registered. + */ +void +vfs_mod_opv_init(handle) + void *handle; +{ + int i; + struct vnodeopv_desc *opv; + + opv = (struct vnodeopv_desc *)handle; + *(opv->opv_desc_vector_p) = NULL; + vfs_opv_init(opv); +} + +int +vfs_unregister(vfc) + struct vfsconf *vfc; +{ + struct linker_set *l; + struct sysctl_oid **oidpp; + struct vfsconf *vfsp, *prev_vfsp; + int error, i, maxtypenum; + + i = vfc->vfc_typenum; + + prev_vfsp = NULL; + for (vfsp = vfsconf; vfsp; + prev_vfsp = vfsp, vfsp = vfsp->vfc_next) { + if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) + break; + } + if (vfsp == NULL) + return EINVAL; + if (vfsp->vfc_refcount) + return EBUSY; + if (vfc->vfc_vfsops->vfs_uninit != NULL) { + error = (*vfc->vfc_vfsops->vfs_uninit)(vfsp); + if (error) + return (error); + } + if (prev_vfsp) + prev_vfsp->vfc_next = vfsp->vfc_next; + else + vfsconf = vfsp->vfc_next; + if (vfsp->vfc_vfsops->vfs_oid != NULL) { + l = &sysctl__vfs; + for (i = l->ls_length, + oidpp = (struct sysctl_oid **)l->ls_items; + i--; oidpp++) { + if (*oidpp == vfsp->vfc_vfsops->vfs_oid) { + *oidpp = NULL; + sysctl_order_all(); + break; + } + } + } + maxtypenum = VFS_GENERIC; + for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next) + if (maxtypenum < vfsp->vfc_typenum) + maxtypenum = vfsp->vfc_typenum; + maxvfsconf = maxtypenum + 1; + return 0; +} diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 6376389..bf4beb4 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -12,14 +12,14 @@ * * This software is provided ``AS IS'' without any warranties of any kind. * - * $Id: ip_fw.c,v 1.95 1998/08/11 19:08:42 bde Exp $ + * $Id: ip_fw.c,v 1.96 1998/08/23 03:07:14 wollman Exp $ */ /* * Implement IP packet firewall */ -#ifndef IPFIREWALL_MODULE +#if !defined(KLD_MODULE) && !defined(IPFIREWALL_MODULE) #include "opt_ipfw.h" #include "opt_ipdivert.h" #include "opt_inet.h" @@ -100,11 +100,6 @@ static int icmptype_match __P((struct icmp * icmp, struct ip_fw * f)); static void ipfw_report __P((struct ip_fw *f, struct ip *ip, struct ifnet *rif, struct ifnet *oif)); -#ifdef IPFIREWALL_MODULE -static ip_fw_chk_t *old_chk_ptr; -static ip_fw_ctl_t *old_ctl_ptr; -#endif - static int ip_fw_chk __P((struct ip **pip, int hlen, struct ifnet *oif, u_int16_t *cookie, struct mbuf **m, struct sockaddr_in **next_hop)); @@ -1107,7 +1102,10 @@ ip_fw_init(void) #endif } -#ifdef IPFIREWALL_MODULE +static ip_fw_chk_t *old_chk_ptr; +static ip_fw_ctl_t *old_ctl_ptr; + +#if defined(IPFIREWALL_MODULE) && !defined(KLD_MODULE) #include <sys/exec.h> #include <sys/sysent.h> @@ -1154,4 +1152,48 @@ ipfw_mod(struct lkm_table *lkmtp, int cmd, int ver) MOD_DISPATCH(ipfw, lkmtp, cmd, ver, ipfw_load, ipfw_unload, lkm_nullcmd); } +#else +static int +ipfw_modevent(module_t mod, modeventtype_t type, void *unused) +{ + int s; + + switch (type) { + case MOD_LOAD: + s = splnet(); + + old_chk_ptr = ip_fw_chk_ptr; + old_ctl_ptr = ip_fw_ctl_ptr; + + ip_fw_init(); + splx(s); + return 0; + case MOD_UNLOAD: + s = splnet(); + + ip_fw_chk_ptr = old_chk_ptr; + ip_fw_ctl_ptr = old_ctl_ptr; + + while (LIST_FIRST(&ip_fw_chain) != NULL) { + struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain); + LIST_REMOVE(LIST_FIRST(&ip_fw_chain), chain); + free(fcp->rule, M_IPFW); + free(fcp, M_IPFW); + } + + splx(s); + printf("IP firewall unloaded\n"); + return 0; + default: + break; + } + return 0; +} + +moduledata_t ipfwmod = { + "ipfw", + ipfw_modevent, + 0 +}; +DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PSEUDO, SI_ORDER_ANY); #endif diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7a03423..18f9fe2 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 - * $Id: ip_input.c,v 1.100 1998/08/24 07:47:39 dfr Exp $ + * $Id: ip_input.c,v 1.101 1998/09/10 08:56:40 dfr Exp $ * $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $ */ @@ -224,9 +224,6 @@ ip_init() ip_id = time_second & 0xffff; ipintrq.ifq_maxlen = ipqmaxlen; -#ifdef IPFIREWALL - ip_fw_init(); -#endif #ifdef IPNAT ip_nat_init(); #endif diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index 1e7c86d..847ab2a 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: elf_machdep.c,v 1.1 1998/09/11 08:47:02 dfr Exp $ */ #include <sys/param.h> @@ -38,73 +38,81 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym) +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) { Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset); + Elf_Addr *where; + Elf_Addr addr, tmp_value; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; - switch (ELF_R_TYPE(rela->r_info)) { + switch (type) { + case ELF_RELOC_REL: + rel = (Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("elf_reloc: unknown relocation mode %d\n", type); + } - case R_ALPHA_REFQUAD: { - Elf_Addr addr; - Elf_Addr tmp_value; + switch (rtype) { + case R_ALPHA_REFQUAD: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; + addr += addend; + if (*where != addr) + *where = addr; + break; - tmp_value = addr + *where + rela->r_addend; - if (*where != tmp_value) - *where = tmp_value; - } - break; - - case R_ALPHA_GLOB_DAT: { - Elf_Addr addr; - + case R_ALPHA_GLOB_DAT: addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_JMP_SLOT: { + case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - Elf_Addr addr; - addr = (Elf_Addr) linker_file_lookup_symbol(lf, sym, 1); if (addr == NULL) return -1; - if (*where != addr) *where = addr; - } - break; + break; - case R_ALPHA_RELATIVE: { - *where += relocbase; - } - break; + case R_ALPHA_RELATIVE: + addr = relocbase + addend; + if (*where != addr) + *where = addr; + break; - case R_ALPHA_COPY: { + case R_ALPHA_COPY: /* * There shouldn't be copy relocations in kernel * objects. */ printf("kldload: unexpected R_COPY relocation\n"); return -1; - } - break; default: printf("kldload: unexpected relocation type %d\n", - ELF_R_TYPE(rela->r_info)); + rtype); return -1; } return(0); diff --git a/sys/sys/_posix.h b/sys/sys/_posix.h index 143596b..8996fd7 100644 --- a/sys/sys/_posix.h +++ b/sys/sys/_posix.h @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _posix.h,v 1.1 1998/03/08 17:25:27 dufault Exp $ + * $Id: _posix.h,v 1.2 1998/03/28 11:50:31 dufault Exp $ */ /* @@ -41,7 +41,7 @@ #ifdef KERNEL -#ifndef ACTUALLY_LKM_NOT_KERNEL +#if !defined(ACTUALLY_LKM_NOT_KERNEL) && !defined(KLD_MODULE) #include "opt_posix.h" #endif diff --git a/sys/sys/exec.h b/sys/sys/exec.h index 8a3ea0e..3df1b15 100644 --- a/sys/sys/exec.h +++ b/sys/sys/exec.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)exec.h 8.3 (Berkeley) 1/21/94 - * $Id: exec.h,v 1.17 1997/09/16 11:44:04 bde Exp $ + * $Id: exec.h,v 1.18 1998/03/02 05:47:40 peter Exp $ */ #ifndef _SYS_EXEC_H_ @@ -78,6 +78,43 @@ struct execsw { int exec_map_first_page __P((struct image_params *)); void exec_unmap_first_page __P((struct image_params *)); + +int exec_register __P((const struct execsw *)); +int exec_unregister __P((const struct execsw *)); + +#ifndef LKM +#include <sys/module.h> +#define EXEC_SET(name, execsw_arg) \ + static int name ## _modevent(module_t mod, modeventtype_t type, \ + void *data) \ + { \ + struct execsw *exec = (struct execsw *)data; \ + int error = 0; \ + switch (type) { \ + case MOD_LOAD: \ + /* printf(#name " module loaded\n"); */ \ + error = exec_register(exec); \ + if (error) \ + printf(#name "register failed\n"); \ + break; \ + case MOD_UNLOAD: \ + /* printf(#name " module unloaded\n"); */ \ + error = exec_unregister(exec); \ + if (error) \ + printf(#name " unregister failed\n"); \ + break; \ + default: \ + break; \ + } \ + return error; \ + } \ + static moduledata_t name ## _mod = { \ + #name, \ + name ## _modevent, \ + (void *)& execsw_arg \ + }; \ + DECLARE_MODULE(name, name ## _mod, SI_SUB_EXEC, SI_ORDER_ANY) +#endif #endif #endif diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index d5850bf..00aa430 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)kernel.h 8.3 (Berkeley) 1/21/94 - * $Id: kernel.h,v 1.41 1998/06/07 17:13:02 dfr Exp $ + * $Id: kernel.h,v 1.42 1998/10/09 23:03:27 peter Exp $ */ #ifndef _SYS_KERNEL_H_ @@ -173,6 +173,7 @@ enum sysinit_sub_id { SI_SUB_SYSV_MSG = 0x6C00000, /* System V message queues*/ SI_SUB_P1003_1B = 0x6E00000, /* P1003.1B realtime */ SI_SUB_PSEUDO = 0x7000000, /* pseudo devices*/ + SI_SUB_EXEC = 0x7400000, /* execve() handlers */ SI_SUB_PROTO_BEGIN = 0x8000000, /* XXX: set splimp (kludge)*/ SI_SUB_PROTO_IF = 0x8400000, /* interfaces*/ SI_SUB_PROTO_DOMAIN = 0x8800000, /* domains (address families?)*/ @@ -311,7 +312,29 @@ void sysinit_add __P((struct sysinit **set)); /* * Compatibility. To be deprecated after LKM is updated. */ -#define PSEUDO_SET(sym, name) SYSINIT(ps, SI_SUB_PSEUDO, SI_ORDER_ANY, sym, 0) +#include <sys/module.h> +#define PSEUDO_SET(sym, name) \ + static int name ## _modevent(module_t mod, modeventtype_t type, \ + void *data) \ + { \ + void (*initfunc)(void *) = (void (*)(void *))data; \ + switch (type) { \ + case MOD_LOAD: \ + /* printf(#name " module load\n"); */ \ + initfunc(NULL); \ + break; \ + case MOD_UNLOAD: \ + printf(#name " module unload - not possible for this module type\n"); \ + return EINVAL; \ + } \ + return 0; \ + } \ + static moduledata_t name ## _mod = { \ + #name, \ + name ## _modevent, \ + (void *)sym \ + }; \ + DECLARE_MODULE(name, name ## _mod, SI_SUB_PSEUDO, SI_ORDER_ANY) #endif /* PSEUDO_LKM */ diff --git a/sys/sys/linker.h b/sys/sys/linker.h index 0a96cf8..45a62da 100644 --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: linker.h,v 1.7 1998/10/09 07:06:43 msmith Exp $ + * $Id: linker.h,v 1.8 1998/10/09 23:07:27 peter Exp $ */ #ifndef _SYS_LINKER_H_ @@ -243,8 +243,10 @@ extern int kld_debug; #endif /* Support functions */ -int elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym); - +int elf_reloc(linker_file_t lf, const void *rel, int type, const char *sym); +/* values for type */ +#define ELF_RELOC_REL 1 +#define ELF_RELOC_RELA 2 #endif /* KERNEL */ diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 7f59f83..01686e6 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mount.h 8.21 (Berkeley) 5/20/95 - * $Id: mount.h,v 1.67 1998/09/07 13:17:05 bde Exp $ + * $Id: mount.h,v 1.68 1998/09/15 11:44:44 phk Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -326,7 +326,7 @@ struct vfsops { (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, NAM, VPP, EXFLG, CRED) #define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP) -#ifdef VFS_LKM +#if defined(VFS_LKM) && !defined(KLD_MODULE) #include <sys/conf.h> #include <sys/exec.h> #include <sys/sysent.h> @@ -350,15 +350,43 @@ struct vfsops { lkmtp, cmd, ver, lkm_nullcmd, lkm_nullcmd, lkm_nullcmd); } #else +#include <sys/module.h> #define VFS_SET(vfsops, fsname, flags) \ - static struct vfsconf _fs_vfsconf = { \ + static struct vfsconf fsname ## _vfsconf = { \ &vfsops, \ #fsname, \ -1, \ 0, \ flags | VFCF_STATIC, \ }; \ - DATA_SET(vfs_set,_fs_vfsconf) + static int fsname ## _modevent(module_t mod, modeventtype_t type, \ + void *data) \ + { \ + struct vfsconf *vfc = (struct vfsconf *)data; \ + int error = 0; \ + switch (type) { \ + case MOD_LOAD: \ + /* printf(#fsname " module load\n"); */ \ + error = vfs_register(vfc); \ + if (error) \ + printf(#fsname " register failed\n"); \ + break; \ + case MOD_UNLOAD: \ + /* printf(#fsname " module unload\n"); */ \ + error = vfs_register(vfc); \ + if (error) \ + printf(#fsname " register failed\n"); \ + break; \ + } \ + return error; \ + } \ + static moduledata_t fsname ## _mod = { \ + #fsname, \ + fsname ## _modevent, \ + & fsname ## _vfsconf \ + }; \ + DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE); + #endif /* VFS_LKM */ #endif /* KERNEL */ @@ -408,6 +436,8 @@ int vfs_mountedon __P((struct vnode *)); /* is a vfs mounted on vp */ int vfs_rootmountalloc __P((char *, char *, struct mount **)); void vfs_unbusy __P((struct mount *, struct proc *)); void vfs_unmountall __P((void)); +int vfs_register __P((struct vfsconf *)); +int vfs_unregister __P((struct vfsconf *)); extern CIRCLEQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ extern struct simplelock mountlist_slock; extern struct nfs_public nfs_pub; diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index d7b6550..5567a3a 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 - * $Id: vnode.h,v 1.73 1998/09/10 02:27:52 tegge Exp $ + * $Id: vnode.h,v 1.74 1998/09/11 18:50:16 rvb Exp $ */ #ifndef _SYS_VNODE_H_ @@ -256,10 +256,11 @@ extern int vttoif_tab[]; #define NULLVP ((struct vnode *)NULL) -#ifdef VFS_LKM +#if defined(VFS_LKM) && !defined(KLD_MODULE) #define VNODEOP_SET(f) DATA_SET(MODVNOPS,f) #else -#define VNODEOP_SET(f) DATA_SET(vfs_opv_descs_,f) +#define VNODEOP_SET(f) \ + SYSINIT(f##init, SI_SUB_VFS, SI_ORDER_SECOND, vfs_mod_opv_init, &f); #endif /* @@ -487,7 +488,8 @@ void vattr_null __P((struct vattr *vap)); int vcount __P((struct vnode *vp)); void vdrop __P((struct vnode *)); int vfinddev __P((dev_t dev, enum vtype type, struct vnode **vpp)); -void vfs_opv_init __P((struct vnodeopv_desc **them)); +void vfs_opv_init __P((struct vnodeopv_desc *opv)); +void vfs_mod_opv_init __P((void *handle)); int vflush __P((struct mount *mp, struct vnode *skipvp, int flags)); int vget __P((struct vnode *vp, int lockflag, struct proc *p)); void vgone __P((struct vnode *vp)); |