-/*********************************************************************
-* This function clears out all references to the in-kernel linker,
-* frees the list of startup extensions in extensionDict, and
-* deallocates the kernel's __KLD segment to reclaim that memory.
-*********************************************************************/
-kern_return_t IOCatalogue::removeKernelLinker(void) {
- kern_return_t result = KERN_SUCCESS;
- struct segment_command * segment;
- char * dt_segment_name;
- void * segment_paddress;
- int segment_size;
-
- /* This must be the very first thing done by this function.
- */
- IOLockLock(kld_lock);
-
-
- /* If the kernel linker isn't here, that's automatically
- * a success.
- */
- if (!kernelLinkerPresent) {
- result = KERN_SUCCESS;
- goto finish;
- }
-
- IOLog("Jettisoning kernel linker.\n");
-
- kernelLinkerPresent = 0;
-
- /* Set the kmod_load_extension function as the means for loading
- * a kernel extension.
- */
- kmod_load_function = &kmod_load_extension;
-
- record_startup_extensions_function = 0;
- add_from_mkext_function = 0;
- remove_startup_extension_function = 0;
-
-
- /* Invoke destructors for the __KLD and __LINKEDIT segments.
- * Do this for all segments before actually freeing their
- * memory so that any cross-dependencies (not that there
- * should be any) are handled.
- */
- segment = getsegbyname("__KLD");
- if (!segment) {
- IOLog("error removing kernel linker: can't find %s segment\n",
- "__KLD");
- result = KERN_FAILURE;
- goto finish;
- }
- OSRuntimeUnloadCPPForSegment(segment);
-
- segment = getsegbyname("__LINKEDIT");
- if (!segment) {
- IOLog("error removing kernel linker: can't find %s segment\n",
- "__LINKEDIT");
- result = KERN_FAILURE;
- goto finish;
- }
- OSRuntimeUnloadCPPForSegment(segment);
-
-
- /* Free the memory that was set up by bootx.
- */
- dt_segment_name = "Kernel-__KLD";
- if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
- IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
- (int)segment_size);
- }
-
- dt_segment_name = "Kernel-__LINKEDIT";
- if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
- IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
- (int)segment_size);
- }
-
- struct section * sect;
- sect = getsectbyname("__PRELINK", "__symtab");
- if (sect && sect->addr)
- {
- vm_offset_t
- virt = ml_static_ptovirt(sect->addr);
- if( virt) {
- ml_static_mfree(virt, sect->size);