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); }
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); }