*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:
parent
df481e793f
commit
aa855a598d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=40435
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user