diff --git a/src/core/module.cpp b/src/core/module.cpp index 36255a8bb..f52d1c654 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -256,6 +256,71 @@ void Module::LoadModuleToMemory(u32& max_tls_index) { case PT_SCE_MODULE_PARAM: module_param_virtual_addr = elf_pheader[i].p_vaddr + base_virtual_addr; break; + case PT_INTERP: { + if (elf_pheader[i].p_filesz != 0) { + interpreter_path.resize(elf_pheader[i].p_filesz); + elf.LoadSegment(std::bit_cast(interpreter_path.data()), + elf_pheader[i].p_offset, elf_pheader[i].p_filesz); + while (!interpreter_path.empty() && interpreter_path.back() == '\0') { + interpreter_path.pop_back(); + } + LOG_INFO(Core_Linker, "Module interpreter: '{}'", interpreter_path); + } + break; + } + case PT_SCE_COMMENT: { + if (elf_pheader[i].p_filesz != 0) { + comment.resize(elf_pheader[i].p_filesz); + elf.LoadSegment(std::bit_cast(comment.data()), elf_pheader[i].p_offset, + elf_pheader[i].p_filesz); + if (comment.starts_with("PATH") && comment.size() > 12) { + comment = comment.substr(12); + comment = comment.substr(0, comment.find('\0')); + } else { + for (char& c : comment) { + if (c == '\0') { + c = ' '; + } + } + while (!comment.empty() && (comment.back() == ' ' || comment.back() == '\0')) { + comment.pop_back(); + } + } + LOG_INFO(Core_Linker, "Module comment: '{}'", comment); + } + break; + } + case PT_SCE_LIBVERSION: { + if (elf_pheader[i].p_filesz != 0) { + std::vector libver_data(elf_pheader[i].p_filesz); + elf.LoadSegment(std::bit_cast(libver_data.data()), elf_pheader[i].p_offset, + elf_pheader[i].p_filesz); + if (!libver_data.empty()) { + const u8 rec_len = libver_data[0]; + if (rec_len > 4 && 1u + rec_len <= libver_data.size()) { + const std::string_view rec( + reinterpret_cast(libver_data.data() + 1), rec_len); + const auto colon = rec.find(':'); + if (colon != std::string_view::npos && colon + 5 <= rec_len) { + const u8* ver_bytes = + reinterpret_cast(rec.data() + colon + 1); + const u32 sdk_ver = (u32(ver_bytes[0]) << 24) | + (u32(ver_bytes[1]) << 16) | + (u32(ver_bytes[2]) << 8) | u32(ver_bytes[3]); + LOG_INFO(Core_Linker, "SCE SDK version: {:x}.{:02x} [{:#010x}]", + ver_bytes[0], ver_bytes[1], sdk_ver); + } + } + } + } + break; + } + case PT_GNU_STACK: + case PT_GNU_RELRO: + case PT_NOTE: + case PT_PHDR: + // Non-loadable metadata/flags segments; nothing to map + break; case PT_GNU_EH_FRAME: { eh_frame_hdr_addr = elf_pheader[i].p_vaddr; eh_frame_hdr_size = elf_pheader[i].p_memsz; diff --git a/src/core/module.h b/src/core/module.h index 6b14faaa7..bd8c913c9 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -238,6 +238,8 @@ public: VAddr base_virtual_addr{}; VAddr proc_param_virtual_addr{}; VAddr module_param_virtual_addr{}; + std::string interpreter_path{}; + std::string comment{}; VAddr eh_frame_hdr_addr{}; VAddr eh_frame_addr{}; u32 eh_frame_hdr_size{};