/* * kobj_load_file: * * Load an object located in the file system. */ int kobj_load_file(kobj_t *kop, const char *filename, const char *base, bool autoload) { struct nameidata nd; kauth_cred_t cred; char *path; int error; kobj_t ko; cred = kauth_cred_get(); ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); if (ko == NULL) { return ENOMEM; } if (autoload) { error = ENOENT; } else { NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename); error = vn_open(&nd, FREAD, 0); } if (error != 0) { if (error != ENOENT) { goto out; } path = PNBUF_GET(); snprintf(path, MAXPATHLEN - 1, "%s/%s/%s.kmod", base, filename, filename); NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, UIO_SYSSPACE, path); error = vn_open(&nd, FREAD, 0); if (error != 0) { strlcat(path, ".o", MAXPATHLEN); NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, UIO_SYSSPACE, path); error = vn_open(&nd, FREAD, 0); } PNBUF_PUT(path); if (error != 0) { goto out; } } out: 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, * the complete size of the object is known. */ int kobj_load_mem(kobj_t *kop, void *base, ssize_t size) { kobj_t ko; ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); if (ko == NULL) { return ENOMEM; } ko->ko_type = KT_MEMORY; ko->ko_source = base; ko->ko_memsize = size; *kop = ko; return kobj_load(ko); }
/* * kobj_load_vfs: * * Load an object located in the file system. */ int kobj_load_vfs(kobj_t *kop, const char *path, const bool nochroot) { struct nameidata nd; struct pathbuf *pb; kauth_cred_t cred; int error; kobj_t ko; KASSERT(path != NULL); if (strchr(path, '/') == NULL) return ENOENT; cred = kauth_cred_get(); ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); if (ko == NULL) { return ENOMEM; } pb = pathbuf_create(path); if (pb == NULL) { kmem_free(ko, sizeof(*ko)); return ENOMEM; } NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0), pb); error = vn_open(&nd, FREAD, 0); if (error != 0) { pathbuf_destroy(pb); kmem_free(ko, sizeof(*ko)); return error; } ko->ko_type = KT_VNODE; kobj_setname(ko, path); ko->ko_source = nd.ni_vp; ko->ko_read = kobj_read_vfs; ko->ko_close = kobj_close_vfs; pathbuf_destroy(pb); *kop = ko; return kobj_load(ko); }
/* * kobj_load_mem: * * Load an object already resident in memory. If size is not -1, * the complete size of the object is known. */ int kobj_load_mem(kobj_t *kop, const char *name, void *base, ssize_t size) { kobj_t ko; ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); if (ko == NULL) { return ENOMEM; } ko->ko_type = KT_MEMORY; kobj_setname(ko, name); 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); }