diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/caps/caps_a.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/jit/jit_context.cpp | 36 |
3 files changed, 44 insertions, 12 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a1134b7e2..cb025c3d6 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -373,7 +373,7 @@ struct KernelCore::Impl { static inline thread_local u8 host_thread_id = UINT8_MAX; /// Sets the host thread ID for the caller. - u32 SetHostThreadId(std::size_t core_id) { + LTO_NOINLINE u32 SetHostThreadId(std::size_t core_id) { // This should only be called during core init. ASSERT(host_thread_id == UINT8_MAX); @@ -384,13 +384,13 @@ struct KernelCore::Impl { } /// Gets the host thread ID for the caller - u32 GetHostThreadId() const { + LTO_NOINLINE u32 GetHostThreadId() const { return host_thread_id; } // Gets the dummy KThread for the caller, allocating a new one if this is the first time - KThread* GetHostDummyThread(KThread* existing_thread) { - const auto initialize{[](KThread* thread) { + LTO_NOINLINE KThread* GetHostDummyThread(KThread* existing_thread) { + const auto initialize{[](KThread* thread) LTO_NOINLINE { ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); return thread; }}; @@ -424,11 +424,11 @@ struct KernelCore::Impl { static inline thread_local bool is_phantom_mode_for_singlecore{false}; - bool IsPhantomModeForSingleCore() const { + LTO_NOINLINE bool IsPhantomModeForSingleCore() const { return is_phantom_mode_for_singlecore; } - void SetIsPhantomModeForSingleCore(bool value) { + LTO_NOINLINE void SetIsPhantomModeForSingleCore(bool value) { ASSERT(!is_multicore); is_phantom_mode_for_singlecore = value; } @@ -439,14 +439,14 @@ struct KernelCore::Impl { static inline thread_local KThread* current_thread{nullptr}; - KThread* GetCurrentEmuThread() { + LTO_NOINLINE KThread* GetCurrentEmuThread() { if (!current_thread) { current_thread = GetHostDummyThread(nullptr); } return current_thread; } - void SetCurrentEmuThread(KThread* thread) { + LTO_NOINLINE void SetCurrentEmuThread(KThread* thread) { current_thread = thread; } diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp index e22f72bf6..9925720a3 100644 --- a/src/core/hle/service/caps/caps_a.cpp +++ b/src/core/hle/service/caps/caps_a.cpp @@ -128,9 +128,9 @@ void IAlbumAccessorService::GetAlbumFileListEx0(HLERequestContext& ctx) { ctx.WriteBuffer(entries); } - IPC::ResponseBuilder rb{ctx, 3}; + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(result); - rb.Push(entries.size()); + rb.Push<u64>(entries.size()); } void IAlbumAccessorService::GetAutoSavingStorage(HLERequestContext& ctx) { diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 4ed3f02e2..0090e8568 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -156,6 +156,8 @@ public: bool LoadNRO(std::span<const u8> data) { local_memory.clear(); + + relocbase = local_memory.size(); local_memory.insert(local_memory.end(), data.begin(), data.end()); if (FixupRelocations()) { @@ -181,8 +183,8 @@ public: // https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html // https://refspecs.linuxbase.org/elf/gabi4+/ch4.reloc.html VAddr dynamic_offset{mod_offset + callbacks->MemoryRead32(mod_offset + 4)}; - VAddr rela_dyn = 0; - size_t num_rela = 0; + VAddr rela_dyn = 0, relr_dyn = 0; + size_t num_rela = 0, num_relr = 0; while (true) { const auto dyn{callbacks->ReadMemory<Elf64_Dyn>(dynamic_offset)}; dynamic_offset += sizeof(Elf64_Dyn); @@ -196,6 +198,12 @@ public: if (dyn.d_tag == ElfDtRelasz) { num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela); } + if (dyn.d_tag == ElfDtRelr) { + relr_dyn = dyn.d_un.d_ptr; + } + if (dyn.d_tag == ElfDtRelrsz) { + num_relr = dyn.d_un.d_val / sizeof(Elf64_Relr); + } } for (size_t i = 0; i < num_rela; i++) { @@ -207,6 +215,29 @@ public: callbacks->MemoryWrite64(rela.r_offset, contents + rela.r_addend); } + VAddr relr_where = 0; + for (size_t i = 0; i < num_relr; i++) { + const auto relr{callbacks->ReadMemory<Elf64_Relr>(relr_dyn + i * sizeof(Elf64_Relr))}; + const auto incr{[&](VAddr where) { + callbacks->MemoryWrite64(where, callbacks->MemoryRead64(where) + relocbase); + }}; + + if ((relr & 1) == 0) { + // where pointer + relr_where = relocbase + relr; + incr(relr_where); + relr_where += sizeof(Elf64_Addr); + } else { + // bitmap + for (int bit = 1; bit < 64; bit++) { + if ((relr & (1ULL << bit)) != 0) { + incr(relr_where + i * sizeof(Elf64_Addr)); + } + } + relr_where += 63 * sizeof(Elf64_Addr); + } + } + return true; } @@ -313,6 +344,7 @@ public: Core::Memory::Memory& memory; VAddr top_of_stack; VAddr heap_pointer; + VAddr relocbase; }; void DynarmicCallbacks64::CallSVC(u32 swi) { |