From e02c0a9398b12b037b6192a2ca57f2a9c4eefedf Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 8 Jun 2023 11:58:29 +0300 Subject: [PATCH 1/9] simplify main (not loading imgui and sdl for the moment) --- src/main.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fdb32ba..d59efd18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,17 +26,21 @@ #endif #include "Core/PS4/Linker.h" #include "Util/Singleton.h" - +#include +#include +#include // Main code int main(int argc, char* argv[]) { + + logging::init(true);//init logging - const char* const path = argv[1]; //argument 1 is the path of self file to boot + const char* const path = "videoout_basic.elf";// argv[1]; //argument 1 is the path of self file to boot auto* linker = Singleton::Instance(); auto *module =linker->LoadModule(path);//load main executable - +#if 0 // Setup SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0) { @@ -215,6 +219,7 @@ int main(int argc, char* argv[]) SDL_GL_DeleteContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); +#endif return 0; } From 672e2b2d77941b61dfaf753f80afae90241ee080 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 8 Jun 2023 12:51:11 +0300 Subject: [PATCH 2/9] initial dynamic loader , parsing DT_HASH atm --- src/Core/PS4/Linker.cpp | 19 +++++++++++++++++++ src/Core/PS4/Linker.h | 9 +++++++++ src/Loader/Elf.h | 13 +++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 0cc7e646..8476bdbb 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -47,6 +47,7 @@ Module* Linker::LoadModule(const std::string& elf_name) if (m->elf->isElfFile()) { LoadModuleToMemory(m); + LoadDynamicInfo(m); } else { @@ -157,4 +158,22 @@ void Linker::LoadModuleToMemory(Module* m) offset += instruction.info.length; runtime_address += instruction.info.length; } +} + +void Linker::LoadDynamicInfo(Module* m) +{ + m->dynamic_info = new DynamicModuleInfo; + + for (const auto* dyn = static_cast(m->m_dynamic); dyn->d_tag != DT_NULL; dyn++) + { + switch (dyn->d_tag) + { + case DT_OS_HASH: + m->dynamic_info->hash_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); + break; + default: + LOG_INFO_IF(debug_loader, "unsupported dynamic tag ..........: {:#018x}\n", dyn->d_tag); + } + + } } \ No newline at end of file diff --git a/src/Core/PS4/Linker.h b/src/Core/PS4/Linker.h index 002dc30f..7add71c2 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -2,6 +2,8 @@ #include "../../Loader/Elf.h" #include +struct DynamicModuleInfo; + /*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/ struct Module { @@ -11,6 +13,12 @@ struct Module void* m_dynamic = nullptr; void* m_dynamic_data = nullptr; + DynamicModuleInfo* dynamic_info = nullptr; +}; + +struct DynamicModuleInfo +{ + void* hash_table = nullptr; }; class Linker @@ -22,6 +30,7 @@ public: Module* LoadModule(const std::string& elf_name); Module* FindModule(/*u32 id*/); void LoadModuleToMemory(Module* m); + void LoadDynamicInfo(Module* program); private: std::vector m_modules; diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index dbe7c9c3..b425e794 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -323,6 +323,19 @@ struct elf_program_id_header u64 firmver; u08 digest[32]; }; + +constexpr s64 DT_NULL = 0; +constexpr s64 DT_OS_HASH = 0x61000025; + +struct elf_dynamic +{ + s64 d_tag; + union + { + u64 d_val; + u64 d_ptr; + } d_un; +}; class Elf { public: From 8932be618b155e9b33c60bf181d9c0eb64c046b5 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 8 Jun 2023 13:25:24 +0300 Subject: [PATCH 3/9] parsing DT_OS_HASHZ, DT_OS_STRTAB , DT_OS_STRSZ for dynamic loader --- src/Core/PS4/Linker.cpp | 9 +++++++++ src/Core/PS4/Linker.h | 4 ++++ src/Loader/Elf.h | 3 +++ 3 files changed, 16 insertions(+) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 8476bdbb..2365509d 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -171,6 +171,15 @@ void Linker::LoadDynamicInfo(Module* m) case DT_OS_HASH: m->dynamic_info->hash_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); break; + case DT_OS_HASHSZ: + m->dynamic_info->hash_table_size = dyn->d_un.d_val; + break; + case DT_OS_STRTAB: + m->dynamic_info->str_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); + break; + case DT_OS_STRSZ: + m->dynamic_info->str_table_size = 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 7add71c2..38fbd38b 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -19,6 +19,10 @@ struct Module struct DynamicModuleInfo { void* hash_table = nullptr; + u64 hash_table_size = 0; + + char* str_table = nullptr; + u64 str_table_size = 0; }; class Linker diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index b425e794..cf1e7df8 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -326,6 +326,9 @@ struct elf_program_id_header constexpr s64 DT_NULL = 0; constexpr s64 DT_OS_HASH = 0x61000025; +constexpr s64 DT_OS_HASHSZ = 0x6100003d; +constexpr s64 DT_OS_STRTAB = 0x61000035; +constexpr s64 DT_OS_STRSZ = 0x61000037; struct elf_dynamic { From d995a0e2866660f359c52f325672d3356bef3223 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 8 Jun 2023 19:05:03 +0300 Subject: [PATCH 4/9] added DT_INIT.DT_FINI,DT_OS_PLTGOT,DT_OS_SYMTAB,DT_OS_SYMTABSZ --- src/Core/PS4/Linker.cpp | 15 +++++++++++++++ src/Core/PS4/Linker.h | 8 ++++++++ src/Loader/Elf.h | 27 ++++++++++++++++++++++----- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 2365509d..a945acff 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -180,6 +180,21 @@ void Linker::LoadDynamicInfo(Module* m) case DT_OS_STRSZ: m->dynamic_info->str_table_size = dyn->d_un.d_val; break; + case DT_OS_SYMTAB: + m->dynamic_info->symbol_table = reinterpret_cast(static_cast(m->m_dynamic_data) + dyn->d_un.d_ptr); + break; + case DT_OS_SYMTABSZ: + m->dynamic_info->symbol_table_total_size = dyn->d_un.d_val; + break; + case DT_INIT: + m->dynamic_info->init_virtual_addr = dyn->d_un.d_ptr; + break; + case DT_FINI: + m->dynamic_info->fini_virtual_addr = dyn->d_un.d_ptr; + break; + case DT_OS_PLTGOT: + m->dynamic_info->pltgot_virtual_addr = dyn->d_un.d_ptr; + 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 38fbd38b..9370adc7 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -23,6 +23,14 @@ struct DynamicModuleInfo char* str_table = nullptr; u64 str_table_size = 0; + + elf_symbol* symbol_table = nullptr; + u64 symbol_table_total_size = 0; + + u64 init_virtual_addr = 0; + u64 fini_virtual_addr = 0; + u64 pltgot_virtual_addr = 0; + }; class Linker diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index cf1e7df8..f526a54c 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -324,11 +324,17 @@ struct elf_program_id_header u08 digest[32]; }; -constexpr s64 DT_NULL = 0; -constexpr s64 DT_OS_HASH = 0x61000025; -constexpr s64 DT_OS_HASHSZ = 0x6100003d; -constexpr s64 DT_OS_STRTAB = 0x61000035; -constexpr s64 DT_OS_STRSZ = 0x61000037; +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; + struct elf_dynamic { @@ -339,6 +345,17 @@ struct elf_dynamic u64 d_ptr; } d_un; }; + +struct elf_symbol +{ + u32 st_name; + u08 st_info; + u08 st_other; + u16 st_shndx; + u64 st_value; + u64 st_size; +}; + class Elf { public: From dd4dddded34d838c9f25cbe8b1e58914be0af046 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 9 Jun 2023 11:37:18 +0300 Subject: [PATCH 5/9] 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: From 94dff9b9808d2605ac1146030bc871413a32966c Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 9 Jun 2023 13:37:46 +0300 Subject: [PATCH 6/9] added DT_INIT_ARRAY, DT_FINI_ARRAY,DT_INIT_ARRAYSZ,DT_FINI_ARRAYSZ,DT_PREINIT_ARRAY,DT_PREINIT_ARRAYSZ,DT_SCE_SYMENT --- src/Core/PS4/Linker.cpp | 25 +++++++++++++++++++++++++ src/Core/PS4/Linker.h | 7 +++++++ src/Loader/Elf.h | 41 ++++++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 75fa89b1..95f877d4 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -221,6 +221,31 @@ void Linker::LoadDynamicInfo(Module* m) LOG_WARN_IF(debug_loader, "DT_SCE_RELAENT is NOT 0x18 should check!"); } break; + case DT_INIT_ARRAY: + m->dynamic_info->init_array_virtual_addr = dyn->d_un.d_ptr; + break; + case DT_FINI_ARRAY: + m->dynamic_info->fini_array_virtual_addr = dyn->d_un.d_ptr; + break; + case DT_INIT_ARRAYSZ: + m->dynamic_info->init_array_size = dyn->d_un.d_val; + break; + case DT_FINI_ARRAYSZ: + m->dynamic_info->fini_array_size = dyn->d_un.d_val; + break; + case DT_PREINIT_ARRAY: + m->dynamic_info->preinit_array_virtual_addr = dyn->d_un.d_ptr; + break; + case DT_PREINIT_ARRAYSZ: + m->dynamic_info->preinit_array_size = dyn->d_un.d_val; + break; + case DT_SCE_SYMENT: //The size of symbol table entries + m->dynamic_info->symbol_table_entries_size = dyn->d_un.d_val; + if (m->dynamic_info->symbol_table_entries_size != 0x18) //this value should always be 0x18 + { + LOG_WARN_IF(debug_loader, "DT_SCE_SYMENT 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 09c6a2f3..09abe4b4 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -26,10 +26,17 @@ struct DynamicModuleInfo elf_symbol* symbol_table = nullptr; u64 symbol_table_total_size = 0; + u64 symbol_table_entries_size = 0; u64 init_virtual_addr = 0; u64 fini_virtual_addr = 0; u64 pltgot_virtual_addr = 0; + u64 init_array_virtual_addr = 0; + u64 fini_array_virtual_addr = 0; + u64 preinit_array_virtual_addr = 0; + u64 init_array_size = 0; + u64 fini_array_size = 0; + u64 preinit_array_size = 0; elf_relocation* jmp_relocation_table = nullptr; u64 jmp_relocation_table_size = 0; diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index 9568b2d7..558c9748 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -324,23 +324,30 @@ struct elf_program_id_header u08 digest[32]; }; -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; +constexpr s64 DT_NULL = 0; +constexpr s64 DT_RELA = 0x00000007; +constexpr s64 DT_INIT = 0x0000000c; +constexpr s64 DT_FINI = 0x0000000d; +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_PREINIT_ARRAY = 0x00000020; +constexpr s64 DT_PREINIT_ARRAYSZ = 0x00000021; +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 From 6e0cf378d289f690227fd9a4e8e0b2dac8a209a6 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 9 Jun 2023 18:10:40 +0300 Subject: [PATCH 7/9] Added DT_DEBUG, DT_TEXTREL,DT_FLAGS,DT_NEEDED --- src/Core/PS4/Linker.cpp | 23 +++++++++++++++++++++++ src/Core/PS4/Linker.h | 7 +++++++ src/Loader/Elf.h | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index 95f877d4..b25e8c4a 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -246,6 +246,29 @@ void Linker::LoadDynamicInfo(Module* m) LOG_WARN_IF(debug_loader, "DT_SCE_SYMENT is NOT 0x18 should check!"); } break; + case DT_DEBUG: + m->dynamic_info->debug = dyn->d_un.d_val; + break; + case DT_TEXTREL: + m->dynamic_info->textrel = dyn->d_un.d_val; + break; + case DT_FLAGS: + m->dynamic_info->flags = dyn->d_un.d_val; + if (m->dynamic_info->flags != 0x04) //this value should always be DF_TEXTREL (0x04) + { + LOG_WARN_IF(debug_loader, "DT_FLAGS is NOT 0x04 should check!"); + } + break; + case DT_NEEDED://Offset of the library string in the string table to be linked in. + if (m->dynamic_info->str_table != nullptr)//in theory this should already be filled from about just make a test case + { + m->dynamic_info->needed.push_back(m->dynamic_info->str_table + dyn->d_un.d_val); + } + else + { + LOG_ERROR_IF(debug_loader, "DT_NEEDED str table is not loaded 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 09abe4b4..76aa8aea 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -45,6 +45,13 @@ struct DynamicModuleInfo elf_relocation* relocation_table = nullptr; u64 relocation_table_size = 0; u64 relocation_table_entries_size = 0; + + u64 debug = 0; + u64 textrel = 0; + u64 flags = 0; + + std::vector needed; + }; class Linker diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index 558c9748..97a92cf8 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -325,13 +325,17 @@ struct elf_program_id_header }; 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_HASH = 0x61000025; From 6fcfe38e26f2d6ed185f421ba93bcd9d1e691281 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 11 Jun 2023 15:35:04 +0300 Subject: [PATCH 8/9] Added DT_OS_NEEDED_MODULE --- src/Core/PS4/Linker.cpp | 21 +++++++++++++++------ src/Core/PS4/Linker.h | 16 ++++++++++++++++ src/Loader/Elf.h | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index b25e8c4a..03bd89d6 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -163,6 +163,7 @@ 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++) { @@ -221,22 +222,22 @@ void Linker::LoadDynamicInfo(Module* m) LOG_WARN_IF(debug_loader, "DT_SCE_RELAENT is NOT 0x18 should check!"); } break; - case DT_INIT_ARRAY: + case DT_INIT_ARRAY:// Address of the array of pointers to initialization functions m->dynamic_info->init_array_virtual_addr = dyn->d_un.d_ptr; break; - case DT_FINI_ARRAY: + case DT_FINI_ARRAY: // Address of the array of pointers to termination functions m->dynamic_info->fini_array_virtual_addr = dyn->d_un.d_ptr; break; - case DT_INIT_ARRAYSZ: + case DT_INIT_ARRAYSZ://Size in bytes of the array of initialization functions m->dynamic_info->init_array_size = dyn->d_un.d_val; break; - case DT_FINI_ARRAYSZ: + case DT_FINI_ARRAYSZ://Size in bytes of the array of terminationfunctions m->dynamic_info->fini_array_size = dyn->d_un.d_val; break; - case DT_PREINIT_ARRAY: + case DT_PREINIT_ARRAY://Address of the array of pointers to pre - initialization functions m->dynamic_info->preinit_array_virtual_addr = dyn->d_un.d_ptr; break; - case DT_PREINIT_ARRAYSZ: + case DT_PREINIT_ARRAYSZ://Size in bytes of the array of pre - initialization functions m->dynamic_info->preinit_array_size = dyn->d_un.d_val; break; case DT_SCE_SYMENT: //The size of symbol table entries @@ -269,6 +270,14 @@ 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: + { + ModuleInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info->str_table + info.name_offset; + needed_modules.push_back(info); + } + 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 76aa8aea..ac8c9e93 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -16,6 +16,22 @@ struct Module DynamicModuleInfo* dynamic_info = nullptr; }; +struct ModuleInfo +{ + std::string name; + union + { + u64 value; + struct + { + u32 name_offset; + u08 version_minor; + u08 version_major; + u16 id; + }; + }; +}; + struct DynamicModuleInfo { void* hash_table = nullptr; diff --git a/src/Loader/Elf.h b/src/Loader/Elf.h index 97a92cf8..de7d61d5 100644 --- a/src/Loader/Elf.h +++ b/src/Loader/Elf.h @@ -338,6 +338,7 @@ 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; From 0682830e2f314d1c53e414dec7961f46c2d4a11b Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 12 Jun 2023 08:16:20 +0300 Subject: [PATCH 9/9] DT_SCE_IMPORT_LIB,DT_SCE_ORIGINAL_FILENAME,DT_SCE_MODULE_INFO added. Dynamic loader should be ok for now --- src/Core/PS4/Linker.cpp | 38 ++++++++++++++++++++++-- src/Core/PS4/Linker.h | 20 +++++++++++++ src/Loader/Elf.h | 64 ++++++++++++++++++++++------------------- 3 files changed, 90 insertions(+), 32 deletions(-) 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