diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 03bd89d6..0d08e840 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -163,7 +163,6 @@ void Linker::LoadModuleToMemory(Module* m) void Linker::LoadDynamicInfo(Module* m) { m->dynamic_info = new DynamicModuleInfo; - std::vector needed_modules; for (const auto* dyn = static_cast(m->m_dynamic); dyn->d_tag != DT_NULL; dyn++) { @@ -270,14 +269,47 @@ void Linker::LoadDynamicInfo(Module* m) LOG_ERROR_IF(debug_loader, "DT_NEEDED str table is not loaded should check!"); } break; - case DT_OS_NEEDED_MODULE: + case DT_SCE_NEEDED_MODULE: { ModuleInfo info{}; info.value = dyn->d_un.d_val; info.name = m->dynamic_info->str_table + info.name_offset; - needed_modules.push_back(info); + m->dynamic_info->import_modules.push_back(info); } break; + case DT_SCE_IMPORT_LIB: + { + LibraryInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info->str_table + info.name_offset; + m->dynamic_info->import_libs.push_back(info); + } + break; + case DT_SCE_FINGERPRINT: + //The fingerprint is a 24 byte (0x18) size buffer that contains a unique identifier for the given app. + //How exactly this is generated isn't known, however it is not necessary to have a valid fingerprint. + //While an invalid fingerprint will cause a warning to be printed to the kernel log, the ELF will still load and run. + LOG_INFO_IF(debug_loader, "unsupported DT_SCE_FINGERPRINT value = ..........: {:#018x}\n", dyn->d_un.d_val); + break; + case DT_SCE_IMPORT_LIB_ATTR: + //The upper 32-bits should contain the module index multiplied by 0x10000. The lower 32-bits should be a constant 0x9. + LOG_INFO_IF(debug_loader, "unsupported DT_SCE_IMPORT_LIB_ATTR value = ..........: {:#018x}\n", dyn->d_un.d_val); + break; + case DT_SCE_ORIGINAL_FILENAME: + m->dynamic_info->filename = m->dynamic_info->str_table + dyn->d_un.d_val; + break; + case DT_SCE_MODULE_INFO://probably only useable in shared modules + { + ModuleInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info->str_table + info.name_offset; + m->dynamic_info->export_modules.push_back(info); + } + break; + case DT_SCE_MODULE_ATTR: + //TODO? + LOG_INFO_IF(debug_loader, "unsupported DT_SCE_MODULE_ATTR value = ..........: {:#018x}\n", dyn->d_un.d_val); + break; default: LOG_INFO_IF(debug_loader, "unsupported dynamic tag ..........: {:#018x}\n", dyn->d_tag); } diff --git a/src/Core/PS4/Linker.h b/src/Core/PS4/Linker.h index ac8c9e93..4b01a0c4 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -32,6 +32,21 @@ struct ModuleInfo }; }; +struct LibraryInfo +{ + std::string name; + union + { + u64 value; + struct + { + u32 name_offset; + u16 version; + u16 id; + }; + }; +}; + struct DynamicModuleInfo { void* hash_table = nullptr; @@ -67,6 +82,11 @@ struct DynamicModuleInfo u64 flags = 0; std::vector needed; + std::vector import_modules; + std::vector export_modules; + std::vector import_libs; + + std::string filename;//filename with absolute path }; diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index de7d61d5..4c5686f4 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -324,35 +324,41 @@ struct elf_program_id_header u08 digest[32]; }; -constexpr s64 DT_NULL = 0; -constexpr s64 DT_NEEDED = 0x00000001; -constexpr s64 DT_RELA = 0x00000007; -constexpr s64 DT_INIT = 0x0000000c; -constexpr s64 DT_FINI = 0x0000000d; -constexpr s64 DT_DEBUG = 0x00000015; -constexpr s64 DT_TEXTREL = 0x00000016; -constexpr s64 DT_INIT_ARRAY = 0x00000019; -constexpr s64 DT_FINI_ARRAY = 0x0000001a; -constexpr s64 DT_INIT_ARRAYSZ = 0x0000001b; -constexpr s64 DT_FINI_ARRAYSZ = 0x0000001c; -constexpr s64 DT_FLAGS = 0x0000001e; -constexpr s64 DT_PREINIT_ARRAY = 0x00000020; -constexpr s64 DT_PREINIT_ARRAYSZ = 0x00000021; -constexpr s64 DT_OS_NEEDED_MODULE= 0x6100000f; -constexpr s64 DT_SCE_HASH = 0x61000025; -constexpr s64 DT_SCE_PLTGOT = 0x61000027; -constexpr s64 DT_SCE_JMPREL = 0x61000029; -constexpr s64 DT_SCE_PLTREL = 0x6100002b; -constexpr s64 DT_SCE_PLTRELSZ = 0x6100002d; -constexpr s64 DT_SCE_RELA = 0x6100002f; -constexpr s64 DT_SCE_RELASZ = 0x61000031; -constexpr s64 DT_SCE_RELAENT = 0x61000033; -constexpr s64 DT_SCE_SYMENT = 0x6100003b; -constexpr s64 DT_SCE_HASHSZ = 0x6100003d; -constexpr s64 DT_SCE_STRTAB = 0x61000035; -constexpr s64 DT_SCE_STRSZ = 0x61000037; -constexpr s64 DT_SCE_SYMTAB = 0x61000039; -constexpr s64 DT_SCE_SYMTABSZ = 0x6100003f; +constexpr s64 DT_NULL = 0; +constexpr s64 DT_NEEDED = 0x00000001; +constexpr s64 DT_RELA = 0x00000007; +constexpr s64 DT_INIT = 0x0000000c; +constexpr s64 DT_FINI = 0x0000000d; +constexpr s64 DT_DEBUG = 0x00000015; +constexpr s64 DT_TEXTREL = 0x00000016; +constexpr s64 DT_INIT_ARRAY = 0x00000019; +constexpr s64 DT_FINI_ARRAY = 0x0000001a; +constexpr s64 DT_INIT_ARRAYSZ = 0x0000001b; +constexpr s64 DT_FINI_ARRAYSZ = 0x0000001c; +constexpr s64 DT_FLAGS = 0x0000001e; +constexpr s64 DT_PREINIT_ARRAY = 0x00000020; +constexpr s64 DT_PREINIT_ARRAYSZ = 0x00000021; +constexpr s64 DT_SCE_FINGERPRINT = 0x61000007; +constexpr s64 DT_SCE_ORIGINAL_FILENAME = 0x61000009; +constexpr s64 DT_SCE_MODULE_INFO = 0x6100000d; +constexpr s64 DT_SCE_NEEDED_MODULE = 0x6100000f; +constexpr s64 DT_SCE_MODULE_ATTR = 0x61000011; +constexpr s64 DT_SCE_IMPORT_LIB = 0x61000015; +constexpr s64 DT_SCE_IMPORT_LIB_ATTR = 0x61000019; +constexpr s64 DT_SCE_HASH = 0x61000025; +constexpr s64 DT_SCE_PLTGOT = 0x61000027; +constexpr s64 DT_SCE_JMPREL = 0x61000029; +constexpr s64 DT_SCE_PLTREL = 0x6100002b; +constexpr s64 DT_SCE_PLTRELSZ = 0x6100002d; +constexpr s64 DT_SCE_RELA = 0x6100002f; +constexpr s64 DT_SCE_RELASZ = 0x61000031; +constexpr s64 DT_SCE_RELAENT = 0x61000033; +constexpr s64 DT_SCE_SYMENT = 0x6100003b; +constexpr s64 DT_SCE_HASHSZ = 0x6100003d; +constexpr s64 DT_SCE_STRTAB = 0x61000035; +constexpr s64 DT_SCE_STRSZ = 0x61000037; +constexpr s64 DT_SCE_SYMTAB = 0x61000039; +constexpr s64 DT_SCE_SYMTABSZ = 0x6100003f; struct elf_dynamic