diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index cd4da77..d5a3e96 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -79,7 +79,7 @@ if (KYTY_LINKER STREQUAL LD) set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000") endif() -project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.5) +project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.6) include(src_script.cmake) diff --git a/source/emulator/include/Emulator/Elf.h b/source/emulator/include/Emulator/Elf.h index 89f2faf..dd2c137 100644 --- a/source/emulator/include/Emulator/Elf.h +++ b/source/emulator/include/Emulator/Elf.h @@ -130,27 +130,47 @@ constexpr uint8_t STB_LOCAL = 0; constexpr uint8_t STB_GLOBAL = 1; constexpr uint8_t STB_WEAK = 2; +constexpr uint8_t STT_NOTYPE = 0; constexpr uint8_t STT_OBJECT = 1; constexpr uint8_t STT_FUNC = 2; #pragma pack(1) +struct SelfHeader +{ + uint8_t ident[12]; + uint16_t size1; + uint16_t size2; + uint64_t file_size; + uint16_t segments_num; + uint16_t unknown; + uint32_t pad; +}; + +struct SelfSegment +{ + uint64_t type; + uint64_t offset; + uint64_t compressed_size; + uint64_t decompressed_size; +}; + struct Elf64_Ehdr // NOLINT(readability-identifier-naming) { - unsigned char e_ident[EI_NIDENT]; /* ELF identification */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Machine type */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point address */ - Elf64_Off e_phoff; /* Program header offset */ - Elf64_Off e_shoff; /* Section header offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size */ - Elf64_Half e_phentsize; /* Size of program header entry */ - Elf64_Half e_phnum; /* Number of program header entries */ - Elf64_Half e_shentsize; /* Size of section header entry */ - Elf64_Half e_shnum; /* Number of section header entries */ - Elf64_Half e_shstrndx; /* Section name string table index */ + uint8_t e_ident[EI_NIDENT]; /* ELF identification */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Machine type */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point address */ + Elf64_Off e_phoff; /* Program header offset */ + Elf64_Off e_shoff; /* Section header offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size */ + Elf64_Half e_phentsize; /* Size of program header entry */ + Elf64_Half e_phnum; /* Number of program header entries */ + Elf64_Half e_shentsize; /* Size of section header entry */ + Elf64_Half e_shnum; /* Number of section header entries */ + Elf64_Half e_shstrndx; /* Section name string table index */ }; struct Elf64_Phdr // NOLINT(readability-identifier-naming) @@ -239,6 +259,7 @@ public: const char* GetSectionName(int index) { return m_str_table + m_shdr[index].sh_name; } + [[nodiscard]] bool IsSelf() const; [[nodiscard]] bool IsValid() const; [[nodiscard]] bool IsShared() const; [[nodiscard]] bool IsNextGen() const; @@ -268,13 +289,15 @@ public: private: void Clear(); - Core::File* m_f = nullptr; - Elf64_Ehdr* m_ehdr = nullptr; - Elf64_Phdr* m_phdr = nullptr; - Elf64_Shdr* m_shdr = nullptr; - void* m_dynamic = nullptr; - void* m_dynamic_data = nullptr; - char* m_str_table = nullptr; + Core::File* m_f = nullptr; + SelfHeader* m_self = nullptr; + SelfSegment* m_self_segments = nullptr; + Elf64_Ehdr* m_ehdr = nullptr; + Elf64_Phdr* m_phdr = nullptr; + Elf64_Shdr* m_shdr = nullptr; + void* m_dynamic = nullptr; + void* m_dynamic_data = nullptr; + char* m_str_table = nullptr; // uint64_t m_base_vaddr = 0; }; diff --git a/source/emulator/include/Emulator/SymbolDatabase.h b/source/emulator/include/Emulator/SymbolDatabase.h index 62d9cd9..a27c50e 100644 --- a/source/emulator/include/Emulator/SymbolDatabase.h +++ b/source/emulator/include/Emulator/SymbolDatabase.h @@ -17,7 +17,8 @@ enum class SymbolType Unknown, Func, Object, - TlsModule + TlsModule, + NoType, }; struct SymbolRecord diff --git a/source/emulator/src/Elf.cpp b/source/emulator/src/Elf.cpp index 50bd200..fd926c9 100644 --- a/source/emulator/src/Elf.cpp +++ b/source/emulator/src/Elf.cpp @@ -7,8 +7,36 @@ namespace Kyty::Loader { +static SelfHeader* load_self(Core::File& f) +{ + if (f.Remaining() < sizeof(SelfHeader)) + { + return nullptr; + } + + auto* self = new SelfHeader; + + f.Read(self, sizeof(SelfHeader)); + + return self; +} + +static SelfSegment* load_self_segments(Core::File& f, uint16_t num) +{ + auto* segs = new SelfSegment[num]; + + f.Read(segs, sizeof(SelfSegment) * num); + + return segs; +} + static Elf64_Ehdr* load_ehdr_64(Core::File& f) { + if (f.Remaining() < sizeof(Elf64_Ehdr)) + { + return nullptr; + } + auto* ehdr = new Elf64_Ehdr; f.Read(ehdr, sizeof(Elf64_Ehdr)); @@ -41,12 +69,14 @@ static Elf64_Shdr* load_shdr_64(Core::File& f, uint64_t offset, Elf64_Half num) return shdr; } -static void* load_dynamic_64(Core::File& f, uint64_t offset, uint64_t size) +static void* load_dynamic_64(Elf64* f, uint64_t offset, uint64_t size) { void* dynamic_data = new uint8_t[size]; - f.Seek(offset); - f.Read(dynamic_data, size); + // f.Seek(offset); + // f.Read(dynamic_data, size); + + f->LoadSegment(reinterpret_cast(dynamic_data), offset, size); return dynamic_data; } @@ -187,8 +217,51 @@ void Elf64::LoadSegment(uint64_t vaddr, uint64_t file_offset, uint64_t size) { EXIT_IF(m_f == nullptr); - m_f->Seek(file_offset); - m_f->Read(reinterpret_cast(static_cast(vaddr)), size); + if (m_self != nullptr) + { + EXIT_IF(m_self_segments == nullptr); + EXIT_IF(m_phdr == nullptr); + + for (uint16_t i = 0; i < m_self->segments_num; i++) + { + const auto& seg = m_self_segments[i]; + if ((seg.type & 0x800u) != 0) + { + auto phdr_id = ((seg.type >> 20u) & 0xFFFu); + + const auto& phdr = m_phdr[phdr_id]; + + if (file_offset >= phdr.p_offset && file_offset < phdr.p_offset + phdr.p_filesz) + { + EXIT_NOT_IMPLEMENTED(seg.decompressed_size != phdr.p_filesz); + EXIT_NOT_IMPLEMENTED(seg.compressed_size != seg.decompressed_size); + + auto offset = file_offset - phdr.p_offset; + + EXIT_NOT_IMPLEMENTED(offset + size > seg.decompressed_size); + + m_f->Seek(offset + seg.offset); + m_f->Read(reinterpret_cast(static_cast(vaddr)), size); + + return; + } + } + } + + if (m_f->Size() - m_self->file_size == size) + { + m_f->Seek(m_self->file_size); + m_f->Read(reinterpret_cast(static_cast(vaddr)), size); + + return; + } + + EXIT("missing self segment\n"); + } else + { + m_f->Seek(file_offset); + m_f->Read(reinterpret_cast(static_cast(vaddr)), size); + } } const Elf64_Dyn* Elf64::GetDynValue(Elf64_Sxword tag) const @@ -233,19 +306,23 @@ void Elf64::Clear() m_f->Close(); delete m_f; } + delete m_self; delete m_ehdr; + delete[] m_self_segments; delete[] m_phdr; delete[] m_shdr; delete[] m_str_table; delete[] static_cast(m_dynamic); delete[] static_cast(m_dynamic_data); - m_ehdr = nullptr; - m_phdr = nullptr; - m_shdr = nullptr; - m_str_table = nullptr; - m_dynamic = nullptr; - m_dynamic_data = nullptr; + m_self = nullptr; + m_self_segments = nullptr; + m_ehdr = nullptr; + m_phdr = nullptr; + m_shdr = nullptr; + m_str_table = nullptr; + m_dynamic = nullptr; + m_dynamic_data = nullptr; } void Elf64::DbgDump(const String& folder) @@ -269,8 +346,11 @@ void Elf64::DbgDump(const String& folder) auto* buf = new char[static_cast(m_phdr[i].p_filesz)]; - m_f->Seek(m_phdr[i].p_offset); - m_f->Read(buf, static_cast(m_phdr[i].p_filesz)); + // m_f->Seek(m_phdr[i].p_offset); + // m_f->Read(buf, static_cast(m_phdr[i].p_filesz)); + + LoadSegment(reinterpret_cast(buf), m_phdr[i].p_offset, m_phdr[i].p_filesz); + fout.Write(buf, static_cast(m_phdr[i].p_filesz)); delete[] buf; @@ -337,10 +417,46 @@ uint64_t Elf64::GetEntry() return m_ehdr->e_entry; } +bool Elf64::IsSelf() const +{ + if (m_f == nullptr || m_f->IsInvalid()) + { + return false; + } + + if (m_self == nullptr) + { + return false; + } + + if (m_self->ident[0] != 0x4f || m_self->ident[1] != 0x15 || m_self->ident[2] != 0x3d || m_self->ident[3] != 0x1d) + { + return false; + } + + if (m_self->ident[4] != 0x00 || m_self->ident[5] != 0x01 || m_self->ident[6] != 0x01 || m_self->ident[7] != 0x12) + { + printf("Unknown SELF file\n"); + return false; + } + + if (m_self->ident[8] != 0x01 || m_self->ident[9] != 0x01 || m_self->ident[10] != 0x00 || m_self->ident[11] != 0x00) + { + printf("Unknown SELF file\n"); + return false; + } + + if (m_self->unknown != 0x22) + { + printf("Unknown SELF file\n"); + return false; + } + + return true; +} + bool Elf64::IsValid() const { - bool ret = true; - if (m_f == nullptr || m_f->IsInvalid()) { return false; @@ -418,7 +534,7 @@ bool Elf64::IsValid() const return false; } - return ret; + return true; } void Elf64::Open(const String& file_name) @@ -433,25 +549,52 @@ void Elf64::Open(const String& file_name) EXIT("Can't open %s\n", file_name.C_Str()); } - m_ehdr = load_ehdr_64(*m_f); - m_phdr = load_phdr_64(*m_f, m_ehdr->e_phoff, m_ehdr->e_phnum); - m_shdr = load_shdr_64(*m_f, m_ehdr->e_shoff, m_ehdr->e_shnum); + m_self = load_self(*m_f); - if (m_shdr != nullptr) + if (!IsSelf()) { - m_str_table = load_str_table(*m_f, m_shdr[m_ehdr->e_shstrndx].sh_offset, static_cast(m_shdr[m_ehdr->e_shstrndx].sh_size)); + delete m_self; + m_self = nullptr; + m_f->Seek(0); + } else + { + m_self_segments = load_self_segments(*m_f, m_self->segments_num); } - for (Elf64_Half i = 0; i < m_ehdr->e_phnum; i++) + auto ehdr_pos = m_f->Tell(); + + m_ehdr = load_ehdr_64(*m_f); + + if (!IsValid()) { - if (m_phdr[i].p_type == PT_DYNAMIC) + delete m_ehdr; + m_ehdr = nullptr; + } + + if (m_ehdr != nullptr /*&& m_self == nullptr*/) + { + m_phdr = load_phdr_64(*m_f, ehdr_pos + m_ehdr->e_phoff, m_ehdr->e_phnum); + m_shdr = load_shdr_64(*m_f, ehdr_pos + m_ehdr->e_shoff, m_ehdr->e_shnum); + + EXIT_NOT_IMPLEMENTED(m_shdr != nullptr && m_self != nullptr); + + if (m_shdr != nullptr) { - m_dynamic = load_dynamic_64(*m_f, m_phdr[i].p_offset, m_phdr[i].p_filesz); + m_str_table = + load_str_table(*m_f, m_shdr[m_ehdr->e_shstrndx].sh_offset, static_cast(m_shdr[m_ehdr->e_shstrndx].sh_size)); } - if (m_phdr[i].p_type == PT_OS_DYNLIBDATA) + for (Elf64_Half i = 0; i < m_ehdr->e_phnum; i++) { - m_dynamic_data = load_dynamic_64(*m_f, m_phdr[i].p_offset, m_phdr[i].p_filesz); + if (m_phdr[i].p_type == PT_DYNAMIC) + { + m_dynamic = load_dynamic_64(this, m_phdr[i].p_offset, m_phdr[i].p_filesz); + } + + if (m_phdr[i].p_type == PT_OS_DYNLIBDATA) + { + m_dynamic_data = load_dynamic_64(this, m_phdr[i].p_offset, m_phdr[i].p_filesz); + } } } } diff --git a/source/emulator/src/Kyty.cpp b/source/emulator/src/Kyty.cpp index 8f418cc..6c0fa26 100644 --- a/source/emulator/src/Kyty.cpp +++ b/source/emulator/src/Kyty.cpp @@ -34,6 +34,8 @@ namespace LuaFunc { static void load_symbols(const String& id, Loader::RuntimeLinker* rt) { + KYTY_PROFILER_FUNCTION(); + EXIT_IF(rt == nullptr); if (!Libs::Init(id, rt->Symbols())) { diff --git a/source/emulator/src/RuntimeLinker.cpp b/source/emulator/src/RuntimeLinker.cpp index fb82637..be75361 100644 --- a/source/emulator/src/RuntimeLinker.cpp +++ b/source/emulator/src/RuntimeLinker.cpp @@ -126,10 +126,11 @@ static void dbg_dump_rela(const String& folder, Elf64_Rela* records, uint64_t si for (auto* r = records; reinterpret_cast(r) < reinterpret_cast(records) + size; r++) { - f.Printf("----\n"); - f.Printf("r_offset = 0x%016" PRIx64 "\n", r->r_offset); - f.Printf("r_info = 0x%016" PRIx64 "\n", r->r_info); - f.Printf("r_addend = %" PRId64 "\n", r->r_addend); + f.Printf("----\n" + "r_offset = 0x%016" PRIx64 "\n" + "r_info = 0x%016" PRIx64 "\n" + "r_addend = %" PRId64 "\n", + r->r_offset, r->r_info, r->r_addend); } f.Close(); @@ -270,8 +271,16 @@ static void get_dyn_libs(Elf64* elf, T* out, const char* names, Elf64_Sxword tag static RelocationInfo GetRelocationInfo(Elf64_Rela* r, Program* program) { + KYTY_PROFILER_FUNCTION(); + + // KYTY_PROFILER_BLOCK("1"); + RelocationInfo ret; - SymbolRecord sr {}; + // SymbolRecord sr {}; + + // KYTY_PROFILER_END_BLOCK; + + // KYTY_PROFILER_BLOCK("2"); auto type = r->GetType(); auto symbol = r->GetSymbol(); @@ -282,18 +291,24 @@ static RelocationInfo GetRelocationInfo(Elf64_Rela* r, Program* program) ret.vaddr = ret.base_vaddr + r->r_offset; ret.bind_self = false; + // KYTY_PROFILER_END_BLOCK; + + // KYTY_PROFILER_BLOCK("3"); + switch (type) { case R_X86_64_GLOB_DAT: case R_X86_64_JUMP_SLOT: addend = 0; [[fallthrough]]; case R_X86_64_64: { - auto sym = symbols[symbol]; - auto bind = sym.GetBind(); - auto sym_type = sym.GetType(); - uint64_t symbol_vaddr = 0; + auto sym = symbols[symbol]; + auto bind = sym.GetBind(); + auto sym_type = sym.GetType(); + uint64_t symbol_vaddr = 0; + SymbolRecord sr {}; switch (sym_type) { + case STT_NOTYPE: ret.type = SymbolType::NoType; break; case STT_FUNC: ret.type = SymbolType::Func; break; case STT_OBJECT: ret.type = SymbolType::Object; break; default: EXIT("unknown symbol type: %d\n", (int)sym_type); @@ -334,19 +349,22 @@ static RelocationInfo GetRelocationInfo(Elf64_Rela* r, Program* program) break; default: EXIT("unknown type: %d\n", (int)type); } + + // KYTY_PROFILER_END_BLOCK; + return ret; } static void relocate(uint32_t index, Elf64_Rela* r, Program* program, bool jmprela_table) { + KYTY_PROFILER_FUNCTION(); + auto ri = GetRelocationInfo(r, program); - auto dbg_str = String::FromPrintf("[%016" PRIx64 "] <- %s%016" PRIx64 "%s, %s, %s, %s, %s", ri.vaddr, - ri.value == 0 ? FG_BRIGHT_RED : FG_BRIGHT_GREEN, ri.value, DEFAULT, ri.name.C_Str(), - Core::EnumName(ri.type).C_Str(), Core::EnumName(ri.bind).C_Str(), ri.dbg_name.C_Str()); - [[maybe_unused]] bool patched = false; + // KYTY_PROFILER_BLOCK("patch"); + if (ri.resolved) { patched = VirtualMemory::PatchReplace(ri.vaddr, ri.value); @@ -367,7 +385,7 @@ static void relocate(uint32_t index, Elf64_Rela* r, Program* program, bool jmpre { value = RuntimeLinker::ReadFromElf(program, ri.vaddr) + ri.base_vaddr; } - } else if (ri.type == SymbolType::Func && !jmprela_table && weak) + } else if ((ri.type == SymbolType::Func && !jmprela_table && weak) || (ri.type == SymbolType::NoType && weak)) { value = RuntimeLinker::ReadFromElf(program, ri.vaddr) + ri.base_vaddr; } @@ -377,15 +395,25 @@ static void relocate(uint32_t index, Elf64_Rela* r, Program* program, bool jmpre patched = VirtualMemory::PatchReplace(ri.vaddr, value); } else { + auto dbg_str = String::FromPrintf("[%016" PRIx64 "] <- %s%016" PRIx64 "%s, %s, %s, %s, %s", ri.vaddr, + ri.value == 0 ? FG_BRIGHT_RED : FG_BRIGHT_GREEN, ri.value, DEFAULT, ri.name.C_Str(), + Core::EnumName(ri.type).C_Str(), Core::EnumName(ri.bind).C_Str(), ri.dbg_name.C_Str()); + EXIT("Can't resolve: %s\n", (Log::IsColoredPrintf() ? dbg_str : Log::RemoveColors(dbg_str)).C_Str()); } } + // KYTY_PROFILER_END_BLOCK; + if (program->dbg_print_reloc) { if (/* !dbg_str.ContainsStr(U"libc_") && */ patched && !ri.bind_self && (ri.bind == BindType::Global || ri.bind == BindType::Weak || ri.type == SymbolType::TlsModule)) { + auto dbg_str = String::FromPrintf("[%016" PRIx64 "] <- %s%016" PRIx64 "%s, %s, %s, %s, %s", ri.vaddr, + ri.value == 0 ? FG_BRIGHT_RED : FG_BRIGHT_GREEN, ri.value, DEFAULT, ri.name.C_Str(), + Core::EnumName(ri.type).C_Str(), Core::EnumName(ri.bind).C_Str(), ri.dbg_name.C_Str()); + printf("Relocate: %s\n", dbg_str.C_Str()); } } @@ -393,6 +421,8 @@ static void relocate(uint32_t index, Elf64_Rela* r, Program* program, bool jmpre static void relocate_all(Elf64_Rela* records, uint64_t size, Program* program, bool jmprela_table) { + KYTY_PROFILER_FUNCTION(); + uint32_t index = 0; for (auto* r = records; reinterpret_cast(r) < reinterpret_cast(records) + size; r++, index++) { @@ -500,6 +530,8 @@ uint64_t RuntimeLinker::GetProcParam() void RuntimeLinker::DbgDump(const String& folder) { + KYTY_PROFILER_FUNCTION(); + EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); Core::LockGuard lock(m_mutex); @@ -598,7 +630,7 @@ RuntimeLinker::~RuntimeLinker() Program* RuntimeLinker::LoadProgram(const String& elf_name) { - // EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); + KYTY_PROFILER_FUNCTION(); Core::LockGuard lock(m_mutex); @@ -698,7 +730,7 @@ void RuntimeLinker::Execute() void RuntimeLinker::Resolve(const String& name, SymbolType type, Program* program, SymbolRecord* out_info, bool* bind_self) { - // EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); + KYTY_PROFILER_FUNCTION(); Core::LockGuard lock(m_mutex); @@ -770,8 +802,6 @@ void RuntimeLinker::Resolve(const String& name, SymbolType type, Program* progra uint64_t RuntimeLinker::ReadFromElf(Program* program, uint64_t vaddr) { - // EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); - EXIT_IF(program == nullptr); EXIT_IF(program->base_vaddr == 0 || program->base_size == 0); EXIT_IF(program->elf == nullptr); @@ -963,6 +993,8 @@ static uint64_t calc_base_size(const Elf64_Ehdr* ehdr, const Elf64_Phdr* phdr) void RuntimeLinker::LoadProgramToMemory(Program* program) { + KYTY_PROFILER_FUNCTION(); + EXIT_IF(program == nullptr || program->base_vaddr != 0 || program->base_size != 0 || program->elf == nullptr || program->exception_handler != nullptr); @@ -981,16 +1013,16 @@ void RuntimeLinker::LoadProgramToMemory(Program* program) uint64_t exception_handler_size = VirtualMemory::ExceptionHandler::GetSize(); uint64_t tls_handler_size = is_shared ? 0 : Jit::SafeCall::GetSize(); + uint64_t alloc_size = program->base_size_aligned + exception_handler_size + tls_handler_size; - program->base_vaddr = VirtualMemory::Alloc(desired_base_addr, program->base_size_aligned + exception_handler_size + tls_handler_size, - VirtualMemory::Mode::ExecuteReadWrite); + program->base_vaddr = VirtualMemory::Alloc(desired_base_addr, alloc_size, VirtualMemory::Mode::ExecuteReadWrite); if (!is_shared) { program->tls.handler_vaddr = program->base_vaddr + program->base_size_aligned + exception_handler_size; } - desired_base_addr += DESIRED_BASE_ADDR; + desired_base_addr += DESIRED_BASE_ADDR * (1 + alloc_size / DESIRED_BASE_ADDR); EXIT_IF(program->base_vaddr == 0); EXIT_IF(program->base_size_aligned < program->base_size); @@ -1107,34 +1139,10 @@ void RuntimeLinker::DeleteProgram(Program* p) delete p; } -// void RuntimeLinker::Initialize() const -//{ -// EXIT_NOT_IMPLEMENTED(m_program.dynamic_info != nullptr && m_program.dynamic_info->init_array_size != 0); -// EXIT_NOT_IMPLEMENTED(m_program.dynamic_info != nullptr && m_program.dynamic_info->preinit_array_size != 0); -// -// if (auto addr = GetInit(); addr != 0) -// { -// run_init(addr); -// } -//} - -// static void KYTY_SYSV_ABI ProgramFunctionNotFoundHandler() -//{ -// EXIT("Function not found\n"); -//} - -// void RuntimeLinker::Terminate() const -//{ -// EXIT_NOT_IMPLEMENTED(m_program.dynamic_info != nullptr && m_program.dynamic_info->fini_array_size != 0); -// -// if (auto addr = GetFini(); addr != 0) -// { -// run_fini(addr); -// } -//} - void RuntimeLinker::ParseProgramDynamicInfo(Program* program) { + KYTY_PROFILER_FUNCTION(); + EXIT_IF(program == nullptr); EXIT_IF(program->elf == nullptr); EXIT_IF(program->dynamic_info != nullptr); @@ -1236,6 +1244,8 @@ void RuntimeLinker::ParseProgramDynamicInfo(Program* program) static void InstallRelocateHandler(Program* program) { + KYTY_PROFILER_FUNCTION(); + uint64_t pltgot_vaddr = program->dynamic_info->pltgot_vaddr + program->base_vaddr; uint64_t pltgot_size = 3 * 8; void** pltgot = reinterpret_cast(pltgot_vaddr); @@ -1268,6 +1278,8 @@ static void InstallRelocateHandler(Program* program) void RuntimeLinker::Relocate(Program* program) { + KYTY_PROFILER_FUNCTION(); + EXIT_IF(program == nullptr); printf("--- Relocate program: " FG_WHITE BOLD "%s" DEFAULT " ---\n", program->file_name.C_Str()); @@ -1344,6 +1356,8 @@ const LibraryId* RuntimeLinker::FindLibrary(const Program& program, const String void RuntimeLinker::CreateSymbolDatabase(Program* program) { + KYTY_PROFILER_FUNCTION(); + EXIT_IF(program == nullptr); EXIT_IF(program->export_symbols != nullptr); EXIT_IF(program->import_symbols != nullptr); @@ -1385,6 +1399,7 @@ void RuntimeLinker::CreateSymbolDatabase(Program* program) sr.module_version_minor = m->version_minor; switch (type) { + case STT_NOTYPE: sr.type = SymbolType::NoType; break; case STT_FUNC: sr.type = SymbolType::Func; break; case STT_OBJECT: sr.type = SymbolType::Object; break; default: sr.type = SymbolType::Unknown; break; diff --git a/source/emulator/src/VirtualMemory.cpp b/source/emulator/src/VirtualMemory.cpp index f29189b..b4961f2 100644 --- a/source/emulator/src/VirtualMemory.cpp +++ b/source/emulator/src/VirtualMemory.cpp @@ -4,6 +4,7 @@ #include "Emulator/Common.h" #include "Emulator/Jit.h" +#include "Emulator/Profiler.h" #include @@ -315,6 +316,8 @@ bool FlushInstructionCache(uint64_t address, uint64_t size) bool PatchReplace(uint64_t vaddr, uint64_t value) { + KYTY_PROFILER_FUNCTION(); + VirtualMemory::Mode old_mode {}; VirtualMemory::Protect(vaddr, 8, VirtualMemory::Mode::ReadWrite, &old_mode);