From dd4dddded34d838c9f25cbe8b1e58914be0af046 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 9 Jun 2023 11:37:18 +0300 Subject: [PATCH] Added DT_SCE_JMPREL,DT_SCE_PLTRELSZ,DT_SCE_PLTREL,DT_SCE_RELA,DT_SCE_RELASZ,DT_SCE_RELAENT --- src/Core/PS4/Linker.cpp | 40 +++++++++++++++++++++++++++++++++------- src/Core/PS4/Linker.h | 7 +++++++ src/Loader/Elf.h | 34 ++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index a945acff..75fa89b1 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -168,22 +168,22 @@ void Linker::LoadDynamicInfo(Module* m) { switch (dyn->d_tag) { - case DT_OS_HASH: + case DT_SCE_HASH: //Offset of the hash table. m->dynamic_info->hash_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); break; - case DT_OS_HASHSZ: + case DT_SCE_HASHSZ: //Size of the hash table m->dynamic_info->hash_table_size = dyn->d_un.d_val; break; - case DT_OS_STRTAB: + case DT_SCE_STRTAB://Offset of the string table. m->dynamic_info->str_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); break; - case DT_OS_STRSZ: + case DT_SCE_STRSZ: //Size of the string table. m->dynamic_info->str_table_size = dyn->d_un.d_val; break; - case DT_OS_SYMTAB: + case DT_SCE_SYMTAB://Offset of the symbol table. m->dynamic_info->symbol_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); break; - case DT_OS_SYMTABSZ: + case DT_SCE_SYMTABSZ://Size of the symbol table. m->dynamic_info->symbol_table_total_size = dyn->d_un.d_val; break; case DT_INIT: @@ -192,9 +192,35 @@ void Linker::LoadDynamicInfo(Module* m) case DT_FINI: m->dynamic_info->fini_virtual_addr = dyn->d_un.d_ptr; break; - case DT_OS_PLTGOT: + case DT_SCE_PLTGOT: //Offset of the global offset table. m->dynamic_info->pltgot_virtual_addr = dyn->d_un.d_ptr; break; + case DT_SCE_JMPREL: //Offset of the table containing jump slots. + m->dynamic_info->jmp_relocation_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); + break; + case DT_SCE_PLTRELSZ: //Size of the global offset table. + m->dynamic_info->jmp_relocation_table_size = dyn->d_un.d_val; + break; + case DT_SCE_PLTREL: //The type of relocations in the relocation table. Should be DT_RELA + m->dynamic_info->jmp_relocation_type = dyn->d_un.d_val; + if (m->dynamic_info->jmp_relocation_type != DT_RELA) + { + LOG_WARN_IF(debug_loader, "DT_SCE_PLTREL is NOT DT_RELA should check!"); + } + break; + case DT_SCE_RELA: //Offset of the relocation table. + m->dynamic_info->relocation_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); + break; + case DT_SCE_RELASZ: //Size of the relocation table. + m->dynamic_info->relocation_table_size = dyn->d_un.d_val; + break; + case DT_SCE_RELAENT : //The size of relocation table entries. + m->dynamic_info->relocation_table_entries_size = dyn->d_un.d_val; + if (m->dynamic_info->relocation_table_entries_size != 0x18) //this value should always be 0x18 + { + LOG_WARN_IF(debug_loader, "DT_SCE_RELAENT is NOT 0x18 should check!"); + } + 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 9370adc7..09c6a2f3 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -31,6 +31,13 @@ struct DynamicModuleInfo u64 fini_virtual_addr = 0; u64 pltgot_virtual_addr = 0; + elf_relocation* jmp_relocation_table = nullptr; + u64 jmp_relocation_table_size = 0; + s64 jmp_relocation_type = 0; + + elf_relocation* relocation_table = nullptr; + u64 relocation_table_size = 0; + u64 relocation_table_entries_size = 0; }; class Linker diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index f526a54c..9568b2d7 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -324,16 +324,23 @@ struct elf_program_id_header u08 digest[32]; }; -constexpr s64 DT_NULL = 0; -constexpr s64 DT_INIT = 0x0000000c; -constexpr s64 DT_FINI = 0x0000000d; -constexpr s64 DT_OS_HASH = 0x61000025; -constexpr s64 DT_OS_PLTGOT = 0x61000027; -constexpr s64 DT_OS_HASHSZ = 0x6100003d; -constexpr s64 DT_OS_STRTAB = 0x61000035; -constexpr s64 DT_OS_STRSZ = 0x61000037; -constexpr s64 DT_OS_SYMTAB = 0x61000039; -constexpr s64 DT_OS_SYMTABSZ = 0x6100003f; +constexpr s64 DT_NULL = 0; +constexpr s64 DT_RELA = 0x00000007; +constexpr s64 DT_INIT = 0x0000000c; +constexpr s64 DT_FINI = 0x0000000d; +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_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 @@ -356,6 +363,13 @@ struct elf_symbol u64 st_size; }; +struct elf_relocation +{ + u64 rel_offset; + u64 rel_info; + s64 rel_addend; +}; + class Elf { public: