/********************************************//** * \brief Frees memory of where we want to load * * Finds the max and min addresses we want to * load to using program headers and frees * any module taking up those spaces. * \returns Zero on success, otherwise error ***********************************************/ int uvl_elf_free_memory (Elf32_Phdr_t *prog_hdrs, ///< Array of program headers int count) ///< Number of program headers { void *min_addr = (void*)0xFFFFFFFF; void *max_addr = (void*)0x00000000; loaded_module_info_t m_mod_info; PsvUID mod_list[MAX_LOADED_MODS]; u32_t num_loaded = MAX_LOADED_MODS; int i, j; u32_t length; int temp[2]; IF_VERBOSE LOG ("Reading %u program headers.", count); for (i = 0; i < count; i++) { if (prog_hdrs[i].p_vaddr < min_addr) { min_addr = prog_hdrs[i].p_vaddr; } if ((u32_t)prog_hdrs[i].p_vaddr + prog_hdrs[i].p_memsz > (u32_t)max_addr) { max_addr = (void*)((u32_t)prog_hdrs[i].p_vaddr + prog_hdrs[i].p_memsz); } } IF_DEBUG LOG ("Lowest load address: 0x%08X, highest: 0x%08X", (u32_t)min_addr, (u32_t)max_addr);\ IF_DEBUG LOG ("Getting list of loaded modules."); if (sceKernelGetModuleList (0xFF, mod_list, &num_loaded) < 0) { LOG ("Failed to get module list."); return -1; } IF_DEBUG LOG ("Found %u loaded modules.", num_loaded); for (i = 0; i < num_loaded; i++) { m_mod_info.size = sizeof (loaded_module_info_t); // should be 440 IF_VERBOSE LOG ("Getting information for module #%u, UID: 0x%X.", i, mod_list[i]); if (sceKernelGetModuleInfo (mod_list[i], &m_mod_info) < 0) { LOG ("Error getting info for mod 0x%08X, continuing", mod_list[i]); continue; } for (j = 0; j < 3; j++) { //if (m_mod_info.segments[j].vaddr > min_addr || (u32_t)m_mod_info.segments[j].vaddr + m_mod_info.segments[j].memsz > (u32_t)min_addr) if (m_mod_info.segments[j].vaddr == (void*)0x81000000) { IF_DEBUG LOG ("Module %s segment %u (0x%08X, size %u) is in our address space. Attempting to unload.", m_mod_info.module_name, j, (u32_t)m_mod_info.segments[j].vaddr, m_mod_info.segments[j].memsz); if (sceKernelStopUnloadModule (mod_list[i], 0, 0, 0, &temp[0], &temp[1]) < 0) { LOG ("Error unloading %s.", m_mod_info.module_name); return -1; } break; } } } return 0; }
/********************************************//** * \brief Unloads loaded modules * * \returns Zero on success, otherwise error ***********************************************/ int uvl_unload_all_modules () { loaded_module_info_t m_mod_info; PsvUID mod_list[MAX_LOADED_MODS]; u32_t num_loaded = MAX_LOADED_MODS; int status; int i; if (sceKernelGetModuleList (0xFF, mod_list, &num_loaded) < 0) { LOG ("Failed to get module list."); return -1; } for (i = 0; i < num_loaded; i++) { if (sceKernelStopUnloadModule (mod_list[i], 0, NULL, &status, NULL) < 0) { LOG ("Failed to unload module %X, continuing...", mod_list[i]); continue; } } return 0; }