Module Name:    src
Committed By:   pooka
Date:           Fri Nov 27 17:54:11 UTC 2009

Modified Files:
        src/sys/conf: files
        src/sys/kern: subr_kobj.c
        src/sys/sys: kobj_impl.h
Added Files:
        src/sys/kern: subr_kobj_vfs.c

Log Message:
Due to the schizophrenic nature of kobj (mem + vfs source),
split the module in twain to subj_kobj.c (master + mem) and
subr_kobj_vfs.c (vfs).


To generate a diff of this commit:
cvs rdiff -u -r1.965 -r1.966 src/sys/conf/files
cvs rdiff -u -r1.39 -r1.40 src/sys/kern/subr_kobj.c
cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_kobj_vfs.c
cvs rdiff -u -r1.1 -r1.2 src/sys/sys/kobj_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.965 src/sys/conf/files:1.966
--- src/sys/conf/files:1.965	Wed Nov 25 08:52:38 2009
+++ src/sys/conf/files	Fri Nov 27 17:54:11 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.965 2009/11/25 08:52:38 kiyohara Exp $
+#	$NetBSD: files,v 1.966 2009/11/27 17:54:11 pooka Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20090313
@@ -1490,6 +1490,7 @@
 file	kern/subr_iostat.c
 file	kern/subr_kmem.c
 file	kern/subr_kobj.c
+file	kern/subr_kobj_vfs.c
 file	kern/subr_lockdebug.c
 file	kern/subr_log.c
 file	kern/subr_once.c

Index: src/sys/kern/subr_kobj.c
diff -u src/sys/kern/subr_kobj.c:1.39 src/sys/kern/subr_kobj.c:1.40
--- src/sys/kern/subr_kobj.c:1.39	Wed Jun 17 21:04:25 2009
+++ src/sys/kern/subr_kobj.c	Fri Nov 27 17:54:11 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_kobj.c,v 1.39 2009/06/17 21:04:25 dyoung Exp $	*/
+/*	$NetBSD: subr_kobj.c,v 1.40 2009/11/27 17:54:11 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.39 2009/06/17 21:04:25 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.40 2009/11/27 17:54:11 pooka Exp $");
 
 #include "opt_modular.h"
 
@@ -75,9 +75,6 @@
 #include <sys/kernel.h>
 #include <sys/kmem.h>
 #include <sys/proc.h>
-#include <sys/namei.h>
-#include <sys/vnode.h>
-#include <sys/fcntl.h>
 #include <sys/ksyms.h>
 #include <sys/module.h>
 
@@ -88,51 +85,15 @@
 static int	kobj_relocate(kobj_t, bool);
 static int	kobj_checksyms(kobj_t, bool);
 static void	kobj_error(const char *, ...);
-static int	kobj_read(kobj_t, void **, size_t, off_t);
-static int	kobj_read_bits(kobj_t, void *, size_t, off_t);
 static void	kobj_jettison(kobj_t);
 static void	kobj_free(kobj_t, void *, size_t);
 static void	kobj_close(kobj_t);
-static int	kobj_load(kobj_t);
+static int	kobj_read_mem(kobj_t, void **, size_t, off_t, bool);
+static void	kobj_close_mem(kobj_t);
 
 extern struct vm_map *module_map;
 
 /*
- * kobj_load_file:
- *
- *	Load an object located in the file system.
- */
-int
-kobj_load_file(kobj_t *kop, const char *path, const bool nochroot)
-{
-	struct nameidata nd;
-	kauth_cred_t cred;
-	int error;
-	kobj_t ko;
-
-	cred = kauth_cred_get();
-
-	ko = kmem_zalloc(sizeof(*ko), KM_SLEEP);
-	if (ko == NULL) {
-		return ENOMEM;
-	}
-
-	NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0),
-	    UIO_SYSSPACE, path);
-	error = vn_open(&nd, FREAD, 0);
-
- 	if (error != 0) {
-	 	kmem_free(ko, sizeof(*ko));
-	 	return error;
-	}
-
-	ko->ko_type = KT_VNODE;
-	ko->ko_source = nd.ni_vp;
-	*kop = ko;
-	return kobj_load(ko);
-}
-
-/*
  * kobj_load_mem:
  *
  *	Load an object already resident in memory.  If size is not -1,
@@ -151,6 +112,9 @@
 	ko->ko_type = KT_MEMORY;
 	ko->ko_source = base;
 	ko->ko_memsize = size;
+	ko->ko_read = kobj_read_mem;
+	ko->ko_close = kobj_close_mem;
+
 	*kop = ko;
 	return kobj_load(ko);
 }
@@ -168,29 +132,24 @@
 		return;
 	}
 
-	switch (ko->ko_type) {
-	case KT_VNODE:
-		VOP_UNLOCK(ko->ko_source, 0);
-		vn_close(ko->ko_source, FREAD, kauth_cred_get());
-		break;
-	case KT_MEMORY:
-		/* nothing */
-		break;
-	default:
-		panic("kobj_close: unknown type");
-		break;
-	}
-
+	ko->ko_close(ko);
 	ko->ko_source = NULL;
 }
 
+static void
+kobj_close_mem(kobj_t ko)
+{
+
+	return;
+}
+
 /*
  * kobj_load:
  *
  *	Load an ELF object and prepare to link into the running kernel
  *	image.
  */
-static int
+int
 kobj_load(kobj_t ko)
 {
 	Elf_Ehdr *hdr;
@@ -218,7 +177,7 @@
 	/*
 	 * Read the elf header from the file.
 	 */
-	error = kobj_read(ko, (void **)&hdr, sizeof(*hdr), 0);
+	error = ko->ko_read(ko, (void **)&hdr, sizeof(*hdr), 0, true);
 	if (error != 0)
 		goto out;
 	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) {
@@ -264,7 +223,8 @@
 		error = ENOEXEC;
 		goto out;
 	}
-	error = kobj_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff);
+	error = ko->ko_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff,
+	    true);
 	if (error != 0) {
 		goto out;
 	}
@@ -355,9 +315,9 @@
 		kobj_error("no symbol table");
 		goto out;
 	}
-	error = kobj_read(ko, (void **)&ko->ko_symtab,
+	error = ko->ko_read(ko, (void **)&ko->ko_symtab,
 	    ko->ko_symcnt * sizeof(Elf_Sym),
-	    shdr[symtabindex].sh_offset);
+	    shdr[symtabindex].sh_offset, true);
 	if (error != 0) {
 		goto out;
 	}
@@ -370,8 +330,8 @@
 		kobj_error("no symbol strings");
 		goto out;
 	}
-	error = kobj_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz,
-	    shdr[symstrindex].sh_offset);
+	error = ko->ko_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz,
+	    shdr[symstrindex].sh_offset, true);
 	if (error != 0) {
 		goto out;
 	}
@@ -382,9 +342,9 @@
 	if (hdr->e_shstrndx != 0 && shdr[hdr->e_shstrndx].sh_size != 0 &&
 	    shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
 		ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size;
-		error = kobj_read(ko, (void **)&ko->ko_shstrtab,
+		error = ko->ko_read(ko, (void **)&ko->ko_shstrtab,
 		    shdr[hdr->e_shstrndx].sh_size,
-		    shdr[hdr->e_shstrndx].sh_offset);
+		    shdr[hdr->e_shstrndx].sh_offset, true);
 		if (error != 0) {
 			goto out;
 		}
@@ -461,8 +421,8 @@
 			ko->ko_progtab[pb].addr = addr;
 			if (shdr[i].sh_type == SHT_PROGBITS) {
 				ko->ko_progtab[pb].name = "<<PROGBITS>>";
-				error = kobj_read_bits(ko, addr,
-				    shdr[i].sh_size, shdr[i].sh_offset);
+				error = ko->ko_read(ko, &addr,
+				    shdr[i].sh_size, shdr[i].sh_offset, false);
 				if (error != 0) {
 					goto out;
 				}
@@ -501,10 +461,10 @@
 				ko->ko_reltab[rl].nrel =
 				    shdr[i].sh_size / sizeof(Elf_Rel);
 				ko->ko_reltab[rl].sec = shdr[i].sh_info;
-				error = kobj_read(ko,
+				error = ko->ko_read(ko,
 				    (void **)&ko->ko_reltab[rl].rel,
 				    ko->ko_reltab[rl].size,
-				    shdr[i].sh_offset);
+				    shdr[i].sh_offset, true);
 				if (error != 0) {
 					goto out;
 				}
@@ -519,10 +479,10 @@
 				ko->ko_relatab[ra].nrela =
 				    shdr[i].sh_size / sizeof(Elf_Rela);
 				ko->ko_relatab[ra].sec = shdr[i].sh_info;
-				error = kobj_read(ko,
+				error = ko->ko_read(ko,
 				    (void **)&ko->ko_relatab[ra].rela,
 				    shdr[i].sh_size,
-				    shdr[i].sh_offset);
+				    shdr[i].sh_offset, true);
 				if (error != 0) {
 					goto out;
 				}
@@ -995,98 +955,32 @@
 	va_end(ap);
 }
 
-/*
- * kobj_read:
- *
- *	Utility function: read from the object.
- */
 static int
-kobj_read(kobj_t ko, void **basep, size_t size, off_t off)
+kobj_read_mem(kobj_t ko, void **basep, size_t size, off_t off,
+	bool allocate)
 {
-	size_t resid;
-	void *base;
+	void *base = *basep;
 	int error;
 
-	KASSERT(ko->ko_source != NULL);
-
-	switch (ko->ko_type) {
-	case KT_VNODE:
-		base = kmem_alloc(size, KM_SLEEP);
-		if (base == NULL) {
-			error = ENOMEM;
-			break;
-		}
-		error = vn_rdwr(UIO_READ, ko->ko_source, base, size, off,
-		    UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid,
-		    curlwp);
-		if (error == 0 && resid != 0) {
-			error = EINVAL;
-		}
-		if (error != 0) {
-			kmem_free(base, size);
-			base = NULL;
-		}
-		break;
-	case KT_MEMORY:
-		if (ko->ko_memsize != -1 && off + size > ko->ko_memsize) {
-			kobj_error("kobj_read: preloaded object short");
-			error = EINVAL;
-			base = NULL;
-		} else {
-			base = (uint8_t *)ko->ko_source + off;
-			error = 0;
-		}
-		break;
-	default:
-		panic("kobj_read: invalid type");
+	if (ko->ko_memsize != -1 && off + size > ko->ko_memsize) {
+		kobj_error("kobj_read_mem: preloaded object short");
+		error = EINVAL;
+		base = NULL;
+	} else if (allocate) {
+		base = (uint8_t *)ko->ko_source + off;
+		error = 0;
+	} else if ((uint8_t *)base != (uint8_t *)ko->ko_source + off) {
+		kobj_error("kobj_read_mem: object not aligned");
+		kobj_error("source=%p base=%p off=%d size=%zd",
+		    ko->ko_source, base, (int)off, size);
+		error = EINVAL;
+	} else {
+		/* Nothing to do.  Loading in-situ. */
+		error = 0;
 	}
 
-	*basep = base;
-	return error;
-}
-
-/*
- * kobj_read_bits:
- *
- *	Utility function: load a section from the object.
- */
-static int
-kobj_read_bits(kobj_t ko, void *base, size_t size, off_t off)
-{
-	size_t resid;
-	int error;
-
-	KASSERT(ko->ko_source != NULL);
-
-	switch (ko->ko_type) {
-	case KT_VNODE:
-		KASSERT((uintptr_t)base >= (uintptr_t)ko->ko_address);
-		KASSERT((uintptr_t)base + size <=
-		    (uintptr_t)ko->ko_address + ko->ko_size);
-		error = vn_rdwr(UIO_READ, ko->ko_source, base, size, off,
-		    UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid,
-		    curlwp);
-		if (error == 0 && resid != 0) {
-			error = EINVAL;
-		}
-		break;
-	case KT_MEMORY:
-		if (ko->ko_memsize != -1 && off + size > ko->ko_memsize) {
-			kobj_error("kobj_read_bits: preloaded object short");
-			error = EINVAL;
-		} else if ((uint8_t *)base != (uint8_t *)ko->ko_source + off) {
-			kobj_error("kobj_read_bits: object not aligned");
-			kobj_error("source=%p base=%p off=%d size=%zd",
-			    ko->ko_source, base, (int)off, size);
-			error = EINVAL;
-		} else {
-			/* Nothing to do.  Loading in-situ. */
-			error = 0;
-		}
-		break;
-	default:
-		panic("kobj_read: invalid type");
-	}
+	if (allocate)
+		*basep = base;
 
 	return error;
 }
@@ -1107,13 +1001,6 @@
 #else	/* MODULAR */
 
 int
-kobj_load_file(kobj_t *kop, const char *name, const bool nochroot)
-{
-
-	return ENOSYS;
-}
-
-int
 kobj_load_mem(kobj_t *kop, void *base, ssize_t size)
 {
 

Index: src/sys/sys/kobj_impl.h
diff -u src/sys/sys/kobj_impl.h:1.1 src/sys/sys/kobj_impl.h:1.2
--- src/sys/sys/kobj_impl.h:1.1	Sun May 24 15:00:24 2009
+++ src/sys/sys/kobj_impl.h	Fri Nov 27 17:54:11 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_impl.h,v 1.1 2009/05/24 15:00:24 ad Exp $	*/
+/*	$NetBSD: kobj_impl.h,v 1.2 2009/11/27 17:54:11 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -99,6 +99,9 @@
 	KT_MEMORY
 } kobjtype_t;
 
+typedef int (*kobj_read_fn)(kobj_t, void **, size_t, off_t, bool);
+typedef void (*kobj_close_fn)(kobj_t);
+
 struct kobj {
 	char		ko_name[MAXMODNAME];
 	kobjtype_t	ko_type;
@@ -122,6 +125,12 @@
 	int		ko_nprogtab;
 	bool		ko_ksyms;
 	bool		ko_loaded;
+	kobj_read_fn	ko_read;
+	kobj_close_fn	ko_close;
 };
 
+#ifdef _KERNEL
+int	kobj_load(kobj_t);
+#endif
+
 #endif	/* _SYS_KOBJ_IMPL_H_ */

Added files:

Index: src/sys/kern/subr_kobj_vfs.c
diff -u /dev/null src/sys/kern/subr_kobj_vfs.c:1.1
--- /dev/null	Fri Nov 27 17:54:12 2009
+++ src/sys/kern/subr_kobj_vfs.c	Fri Nov 27 17:54:11 2009
@@ -0,0 +1,175 @@
+/*	$NetBSD: subr_kobj_vfs.c,v 1.1 2009/11/27 17:54:11 pooka Exp $	*/
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software developed for The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1998-2000 Doug Rabson
+ * Copyright (c) 2004 Peter Wemm
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Kernel loader vfs routines.
+ */
+
+#include <sys/kobj_impl.h>
+#include "opt_modular.h"
+
+#ifdef MODULAR
+
+#include <sys/param.h>
+#include <sys/fcntl.h>
+#include <sys/module.h>
+#include <sys/namei.h>
+#include <sys/vnode.h>
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj_vfs.c,v 1.1 2009/11/27 17:54:11 pooka Exp $");
+
+static void
+kobj_close_file(kobj_t ko)
+{
+
+	VOP_UNLOCK(ko->ko_source, 0);
+	vn_close(ko->ko_source, FREAD, kauth_cred_get());
+}
+
+/*
+ * kobj_read:
+ *
+ *	Utility function: read from the object.
+ */
+static int
+kobj_read_file(kobj_t ko, void **basep, size_t size, off_t off,
+	bool allocate)
+{
+	size_t resid;
+	void *base;
+	int error;
+
+	KASSERT(ko->ko_source != NULL);
+
+	if (allocate) {
+		base = kmem_alloc(size, KM_SLEEP);
+	} else {
+		base = *basep;
+		KASSERT((uintptr_t)base >= (uintptr_t)ko->ko_address);
+		KASSERT((uintptr_t)base + size <=
+		    (uintptr_t)ko->ko_address + ko->ko_size);
+	}
+
+	error = vn_rdwr(UIO_READ, ko->ko_source, base, size, off,
+	    UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid,
+	    curlwp);
+
+	if (error == 0 && resid != 0) {
+		error = EINVAL;
+	}
+
+	if (allocate && error != 0) {
+		kmem_free(base, size);
+		base = NULL;
+	}
+
+	if (allocate)
+		*basep = base;
+
+	return error;
+}
+
+/*
+ * kobj_load_file:
+ *
+ *	Load an object located in the file system.
+ */
+int
+kobj_load_file(kobj_t *kop, const char *path, const bool nochroot)
+{
+	struct nameidata nd;
+	kauth_cred_t cred;
+	int error;
+	kobj_t ko;
+
+	cred = kauth_cred_get();
+
+	ko = kmem_zalloc(sizeof(*ko), KM_SLEEP);
+	if (ko == NULL) {
+		return ENOMEM;
+	}
+
+	NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0),
+	    UIO_SYSSPACE, path);
+	error = vn_open(&nd, FREAD, 0);
+
+ 	if (error != 0) {
+	 	kmem_free(ko, sizeof(*ko));
+	 	return error;
+	}
+
+	ko->ko_type = KT_VNODE;
+	ko->ko_source = nd.ni_vp;
+	ko->ko_read = kobj_read_file;
+	ko->ko_close = kobj_close_file;
+
+	*kop = ko;
+	return kobj_load(ko);
+}
+
+#else /* MODULAR */
+
+int
+kobj_load_file(kobj_t *kop, const char *path, const bool nochroot)
+{
+
+	return ENOSYS;
+}
+
+#endif

Reply via email to