Merge pull request #5483 from neobrain/fix_guest_wrapper_code_cache

CodeCache: Delay cache loading for guest library wrappers until after LoadLib
This commit is contained in:
Ryan Houdek authored and GitHub committed 2026-05-06 18:04:55 -07:00
commit 7506cb4ea1
4 files changed
+32 -2

No files matched your search

@@ -597,9 +597,12 @@ int main(int argc, char** argv, char** const envp) {
SyscallHandler->DefaultProgramBreak(BRKInfo.Base, BRKInfo.Size);
// Request code cache generation
if (FEXCore::Config::Get_ENABLECODECACHINGWIP()) {
// Request code cache generation
FEXServerClient::PopulateCodeCache(FEXServerClient::GetServerFD(), Loader.GetMainElfFD(), FEXCore::Config::Get_MULTIBLOCK());
// Finalize code cache for libVDSO-guest.so. This needs to be done explicitly since VDSO doesn't use LoadLib.
SyscallHandler->TriggerGuestLibWrapperCodeCacheLoad(*ParentThread->Thread, reinterpret_cast<uintptr_t>(VDSOMapping.VDSOBase));
}
// Pull RIP and stack pointer from loader and set the thread data to it.
@@ -292,6 +292,7 @@ public:
std::optional<FEXCore::ExecutableFileSectionInfo>
LookupExecutableFileSection(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestAddr) final override;
void TriggerGuestLibWrapperCodeCacheLoad(FEXCore::Core::InternalThreadState&, uint64_t AnyAddr);
int OpenCodeMapFile() override;
FEXCore::HLE::ExecutableRangeInfo QueryGuestExecutableRange(FEXCore::Core::InternalThreadState* Thread, uint64_t Address) override;
@@ -366,6 +366,26 @@ uint64_t SyscallHandler::GuestMremap(bool Is64Bit, FEXCore::Core::InternalThread
return Result;
}
void SyscallHandler::TriggerGuestLibWrapperCodeCacheLoad(FEXCore::Core::InternalThreadState& Thread, uint64_t AnyAddr) {
if (!EnableCodeCaching) {
return;
}
// TODO: Instead of deferring the entire cache load, only delay applicance of sha256 relocations!
auto lk = FEXCore::GuardSignalDeferringSection<std::shared_lock>(VMATracking.Mutex, &Thread);
auto VMAEntry = VMATracking.FindVMAEntry(reinterpret_cast<uint64_t>(AnyAddr));
for (auto* VMA = VMAEntry->second.Resource->FirstVMA; VMA; VMA = VMA->ResourceNextVMA) {
if (!VMA->Prot.Executable) {
continue;
}
auto SectionInfo = BuildSectionInfo(*VMAEntry->second.Resource, VMA->Base, VMA->Length);
LoadCodeCache(Thread, SectionInfo, CodeCacheConfigId);
}
}
int SyscallHandler::OpenCodeMapFile() {
// Query from FEXServer whether this is the first instance of this executable; if it is, also enable code dumping!
FEX_CONFIG_OPT(RootFSPath, ROOTFS);
@@ -623,7 +643,11 @@ SyscallHandler::TrackMmap(FEXCore::Core::InternalThreadState* Thread, uint64_t a
// Load code cache if present.
// FEXServer was requested to generate library caches on program launch.
if (EnableCodeCaching && Resource && Resource->MappedFile && VMATracking::VMAProt::fromProt(prot).Executable) {
if (Thread) {
if (Resource->MappedFile->Filename.ends_with("-guest.so")) {
// For guest library wrappers, cache loading must be delayed until LoadLib is called.
// Before that, we can't patch up the SHA256 function identifiers.
LogMan::Msg::IFmt("Delaying code cache load for {}", Resource->MappedFile->Filename);
} else if (Thread) {
if (!Resource->RequiresDelayedCacheLoad) {
CachedSection.emplace(BuildSectionInfo(*Resource, addr, Size));
} else {
+2
View File
@@ -259,6 +259,8 @@ void ThunkHandler_impl::LoadLib(std::string_view Name) {
LogMan::Msg::DFmt("Loaded {} syms", i);
}
_SyscallHandler->TriggerGuestLibWrapperCodeCacheLoad(*ThreadObject->Thread, ThreadObject->Thread->CurrentFrame->State.rip);
}
/**