#pragma once #include #include #include "Loader/Elf.h" #include "Loader/SymbolsResolver.h" struct DynamicModuleInfo; class Linker; struct EntryParams { int argc; u32 padding; const char* argv[3]; }; /*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/ struct Module { Elf* elf = nullptr; u64 aligned_base_size = 0; u64 base_virtual_addr = 0; //base virtual address Linker* linker = nullptr; void* m_dynamic = nullptr; void* m_dynamic_data = nullptr; DynamicModuleInfo* dynamic_info = nullptr; SymbolsResolver* export_sym = nullptr; SymbolsResolver* import_sym = nullptr; }; struct ModuleInfo { std::string name; union { u64 value; struct { u32 name_offset; u08 version_minor; u08 version_major; u16 id; }; }; std::string enc_id; }; struct LibraryInfo { std::string name; union { u64 value; struct { u32 name_offset; u16 version; u16 id; }; }; std::string enc_id; }; struct DynamicModuleInfo { void* hash_table = nullptr; u64 hash_table_size = 0; char* str_table = nullptr; u64 str_table_size = 0; 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; s64 jmp_relocation_type = 0; 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; std::vector import_modules; std::vector export_modules; std::vector import_libs; std::vector export_libs; std::string filename;//filename with absolute path }; class Linker { public: Linker(); virtual ~Linker(); Module* LoadModule(const std::string& elf_name); Module* FindModule(/*u32 id*/); void LoadModuleToMemory(Module* m); void LoadDynamicInfo(Module* m); void LoadSymbols(Module* m); SymbolsResolver* getHLESymbols() { return m_HLEsymbols; } void Relocate(Module* m); void Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info); void Execute(); private: const ModuleInfo* FindModule(const Module& m, const std::string& id); const LibraryInfo* FindLibrary(const Module& program, const std::string& id); std::vector m_modules; SymbolsResolver* m_HLEsymbols = nullptr; std::mutex m_mutex; };