Beispiel #1
0
/*
 * kobj_affix:
 *
 *	Set an object's name and perform global relocs.  May only be
 *	called after the module and any requisite modules are loaded.
 */
int
kobj_affix(kobj_t ko, const char *name)
{
	int error;

	KASSERT(ko->ko_ksyms == false);
	KASSERT(ko->ko_loaded == false);

	kobj_setname(ko, name);

	/* Cache addresses of undefined symbols. */
	error = kobj_checksyms(ko, true);

	/* Now do global relocations. */
	if (error == 0)
		error = kobj_relocate(ko, false);

	/*
	 * Now that we know the name, register the symbol table.
	 * Do after global relocations because ksyms will pack
	 * the table.
	 */
	if (error == 0) {
		ksyms_modload(ko->ko_name, ko->ko_symtab, ko->ko_symcnt *
		    sizeof(Elf_Sym), ko->ko_strtab, ko->ko_strtabsz);
		ko->ko_ksyms = true;
	}

	/* Jettison unneeded memory post-link. */
	kobj_jettison(ko);

	/*
	 * Notify MD code that a module has been loaded.
	 *
	 * Most architectures use this opportunity to flush their caches.
	 */
	if (error == 0) {
		error = kobj_machdep(ko, (void *)ko->ko_address, ko->ko_size,
		    true);
		if (error != 0)
			kobj_error(__func__, __LINE__, ko,
			    "machine dependent init failed %d", error);
		ko->ko_loaded = true;
	}

	/* If there was an error, destroy the whole object. */
	if (error != 0) {
		kobj_unload(ko);
	}

	return error;
}
/*
 * 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);
}
Beispiel #3
0
/*
 * 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);
}