Пример #1
0
static void
link_elf_unload_file(linker_file_t file)
{
	elf_file_t ef = (elf_file_t) file;
	int i;

	/* Notify MD code that a module is being unloaded. */
	elf_cpu_unload_file(file);

	if (ef->progtab) {
		for (i = 0; i < ef->nprogtab; i++) {
			if (ef->progtab[i].size == 0)
				continue;
			if (ef->progtab[i].name == NULL)
				continue;
			if (!strcmp(ef->progtab[i].name, DPCPU_SETNAME))
				dpcpu_free(ef->progtab[i].addr,
				    ef->progtab[i].size);
#ifdef VIMAGE
			else if (!strcmp(ef->progtab[i].name, VNET_SETNAME))
				vnet_data_free(ef->progtab[i].addr,
				    ef->progtab[i].size);
#endif
		}
	}
	if (ef->preloaded) {
		free(ef->reltab, M_LINKER);
		free(ef->relatab, M_LINKER);
		free(ef->progtab, M_LINKER);
		free(ef->ctftab, M_LINKER);
		free(ef->ctfoff, M_LINKER);
		free(ef->typoff, M_LINKER);
		if (file->filename != NULL)
			preload_delete_name(file->filename);
		/* XXX reclaim module memory? */
		return;
	}

	for (i = 0; i < ef->nreltab; i++)
		free(ef->reltab[i].rel, M_LINKER);
	for (i = 0; i < ef->nrelatab; i++)
		free(ef->relatab[i].rela, M_LINKER);
	free(ef->reltab, M_LINKER);
	free(ef->relatab, M_LINKER);
	free(ef->progtab, M_LINKER);

	if (ef->object) {
		vm_map_remove(kernel_map, (vm_offset_t) ef->address,
		    (vm_offset_t) ef->address +
		    (ef->object->size << PAGE_SHIFT));
	}
	free(ef->e_shdr, M_LINKER);
	free(ef->ddbsymtab, M_LINKER);
	free(ef->ddbstrtab, M_LINKER);
	free(ef->shstrtab, M_LINKER);
	free(ef->ctftab, M_LINKER);
	free(ef->ctfoff, M_LINKER);
	free(ef->typoff, M_LINKER);
}
Пример #2
0
static void
link_elf_obj_unload_file(linker_file_t file)
{
	elf_file_t	ef = file->priv;
	int i;

	if (ef->progtab) {
		for (i = 0; i < ef->nprogtab; i++) {
			if (ef->progtab[i].size == 0)
				continue;
			if (ef->progtab[i].name == NULL)
				continue;
#if 0
			if (!strcmp(ef->progtab[i].name, "set_pcpu"))
				dpcpu_free(ef->progtab[i].addr,
				    ef->progtab[i].size);
#ifdef VIMAGE
			else if (!strcmp(ef->progtab[i].name, VNET_SETNAME))
				vnet_data_free(ef->progtab[i].addr,
				    ef->progtab[i].size);
#endif
#endif
		}
	}
	if (ef->preloaded) {
		if (ef->reltab)
			kfree(ef->reltab, M_LINKER);
		if (ef->relatab)
			kfree(ef->relatab, M_LINKER);
		if (ef->progtab)
			kfree(ef->progtab, M_LINKER);
		if (ef->ctftab)
			kfree(ef->ctftab, M_LINKER);
		if (ef->ctfoff)
			kfree(ef->ctfoff, M_LINKER);
		if (ef->typoff)
			kfree(ef->typoff, M_LINKER);
		if (file->filename != NULL)
			preload_delete_name(file->filename);
		kfree(ef, M_LINKER);
		/* XXX reclaim module memory? */
		return;
	}

	for (i = 0; i < ef->nreltab; i++)
		if (ef->reltab[i].rel)
			kfree(ef->reltab[i].rel, M_LINKER);
	for (i = 0; i < ef->nrelatab; i++)
		if (ef->relatab[i].rela)
			kfree(ef->relatab[i].rela, M_LINKER);
	if (ef->reltab)
		kfree(ef->reltab, M_LINKER);
	if (ef->relatab)
		kfree(ef->relatab, M_LINKER);
	if (ef->progtab)
		kfree(ef->progtab, M_LINKER);

	if (ef->object) {
#if defined(__x86_64__) && defined(_KERNEL_VIRTUAL)
		vkernel_module_memory_free((vm_offset_t)ef->address, ef->bytes);
#else
		vm_map_remove(&kernel_map, (vm_offset_t) ef->address,
		    (vm_offset_t) ef->address +
		    (ef->object->size << PAGE_SHIFT));
#endif
		vm_object_deallocate(ef->object);
		ef->object = NULL;
	}
	if (ef->e_shdr)
		kfree(ef->e_shdr, M_LINKER);
	if (ef->ddbsymtab)
		kfree(ef->ddbsymtab, M_LINKER);
	if (ef->ddbstrtab)
		kfree(ef->ddbstrtab, M_LINKER);
	if (ef->shstrtab)
		kfree(ef->shstrtab, M_LINKER);
	if (ef->ctftab)
		kfree(ef->ctftab, M_LINKER);
	if (ef->ctfoff)
		kfree(ef->ctfoff, M_LINKER);
	if (ef->typoff)
		kfree(ef->typoff, M_LINKER);
	kfree(ef, M_LINKER);
}