*gulp*. Jordan specifically OK'ed this..

This is the bulk of the support for doing kld modules.  Two linker_sets
were replaced by SYSINIT()'s.  VFS's and exec handlers are self registered.
kld is now a superset of lkm.  I have converted most of them, they will
follow as a seperate commit as samples.
This all still works as a static a.out kernel using LKM's.
This commit is contained in:
Peter Wemm 1998-10-16 03:55:01 +00:00
parent df481e793f
commit aa855a598d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=40435
29 changed files with 838 additions and 386 deletions

View File

@ -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)) {
case R_ALPHA_REFQUAD: {
Elf_Addr addr;
Elf_Addr tmp_value;
addr = (Elf_Addr)
linker_file_lookup_symbol(lf, sym, 1);
if (addr == NULL)
return -1;
tmp_value = addr + *where + rela->r_addend;
if (*where != tmp_value)
*where = tmp_value;
}
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_GLOB_DAT: {
Elf_Addr addr;
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;
break;
case R_ALPHA_JMP_SLOT: {
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;
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);

View File

@ -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);

View File

@ -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);
}
case R_386_NONE:
switch (rtype) {
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);

View File

@ -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 */

View File

@ -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);
}
case R_386_NONE:
switch (rtype) {
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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 @@ aout_coredump(p)
* 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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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 @@ load_dependancies(linker_file_t lf)
}
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;

View File

@ -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 @@ load_dependancies(linker_file_t lf)
}
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;

View File

@ -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,14 +67,25 @@ 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
*/
@ -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;
/*
* 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; them[i]->opv_desc_ops[j].opve_op; j++) {
opve_descp = &(them[i]->opv_desc_ops[j]);
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]);
/*
* 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;
/*
* 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;
}
/*
* 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();
}
(*vfsp->vfc_vfsops->vfs_init)(vfsp);
}
/* next vfc_typenum to be used */
maxvfsconf = maxtypenum;
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;
}
}
}
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;
}

View File

@ -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

View File

@ -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

View File

@ -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)) {
case R_ALPHA_REFQUAD: {
Elf_Addr addr;
Elf_Addr tmp_value;
addr = (Elf_Addr)
linker_file_lookup_symbol(lf, sym, 1);
if (addr == NULL)
return -1;
tmp_value = addr + *where + rela->r_addend;
if (*where != tmp_value)
*where = tmp_value;
}
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_GLOB_DAT: {
Elf_Addr addr;
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;
break;
case R_ALPHA_JMP_SLOT: {
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;
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);

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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));