示例#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;
}
示例#2
0
/*
 * kobj_unload:
 *
 *	Unload an object previously loaded by kobj_load().
 */
void
kobj_unload(kobj_t ko)
{
	int error;

	kobj_close(ko);
	kobj_jettison(ko);

	/*
	 * Notify MD code that a module has been unloaded.
	 */
	if (ko->ko_loaded) {
		error = kobj_machdep(ko, (void *)ko->ko_address, ko->ko_size,
		    false);
		if (error != 0)
			kobj_error(__func__, __LINE__, ko,
			    "machine dependent deinit failed %d", error);
	}
	if (ko->ko_address != 0 && ko->ko_type != KT_MEMORY) {
		uvm_km_free(module_map, ko->ko_address, round_page(ko->ko_size),
		    UVM_KMF_WIRED);
	}
	if (ko->ko_ksyms == true) {
		ksyms_modunload(ko->ko_name);
	}
	if (ko->ko_symtab != NULL) {
		kobj_free(ko, ko->ko_symtab, ko->ko_symcnt * sizeof(Elf_Sym));
	}
	if (ko->ko_strtab != NULL) {
		kobj_free(ko, ko->ko_strtab, ko->ko_strtabsz);
	}
	if (ko->ko_progtab != NULL) {
		kobj_free(ko, ko->ko_progtab, ko->ko_nprogtab *
		    sizeof(*ko->ko_progtab));
		ko->ko_progtab = NULL;
	}
	if (ko->ko_shstrtab) {
		kobj_free(ko, ko->ko_shstrtab, ko->ko_shstrtabsz);
		ko->ko_shstrtab = NULL;
	}

	kmem_free(ko, sizeof(*ko));
}
示例#3
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);

	strlcpy(ko->ko_name, name, sizeof(ko->ko_name));

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

	/*
	 * Now that we know the name, register the symbol table.
	 * Do after global relocations because ksyms will pack it.
	 */
	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. */
	if (error == 0) {
		error = kobj_machdep(ko, (void *)ko->ko_address, ko->ko_size,
		    true);
		if (error != 0) {
			kobj_error("machine dependent init failed");
		}
		ko->ko_loaded = true;
	}

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

	return error;
}