Skip to content

Commit 5902b17

Browse files
committed
SyscallsSMCTracking: Workaround assert in ELF mapping
The ELF tracking thing has an expectation that only portions of ELF files that are described in the program headers will be mapped executable. This doesn't hold true as programs will remap random portions of ELF files as executable. In the case that this occurs, don't assert out and instead print a warning. This was discovered as Node.js remaps a portion of itself executable that isn't described as such in the program headers. I also have a local unittest that exposes the same problem. I had discovered same problem in some other program with #5038. Also fixes a bug where sometimes completely anonymously mapped executable sneak in and cause a crash, which is kind of silly.
1 parent d0e47f9 commit 5902b17

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,22 +479,30 @@ std::optional<SyscallHandler::LateApplyExtendedVolatileMetadata> SyscallHandler:
479479
(ProtMapping.Executable ? PF_X : 0) | (ProtMapping.Writable ? PF_W : 0) | (ProtMapping.Readable ? PF_R : 0));
480480
return std::ranges::find(ExpectedBases, Resource.FirstVMA->Base) != ExpectedBases.end();
481481
});
482-
LOGMAN_THROW_A_FMT(ResourceIt != ResourceEnd, "ERROR: Could not find base for file mapping at {:#x} (offset {:#x})", addr, offset);
483-
Resource = &ResourceIt->second;
482+
if (ResourceIt == ResourceEnd) {
483+
// This isn't necessarily a fatal exception. It just means the ELF section isn't a part of the ELF Program headers.
484+
// Node.js hits this as it maps a section of itself that isn't a part of the program headers.
485+
LogMan::Msg::IFmt("Warning: Could not find base for file mapping at {:#x} (offset {:#x}): {}", addr, offset,
486+
std::string_view(Tmp, PathLength));
487+
} else {
488+
Resource = &ResourceIt->second;
489+
}
484490
}
485491

486-
const fextl::string Filename = FHU::Filesystem::GetFilename(Resource->MappedFile->Filename);
492+
if (Resource->MappedFile) {
493+
const fextl::string Filename = FHU::Filesystem::GetFilename(Resource->MappedFile->Filename);
487494

488-
// We now have the filename and the offset in the filename getting mapped.
489-
// Check for extended volatile metadata.
490-
auto it = ExtendedMetaData.find(Filename);
491-
if (it != ExtendedMetaData.end()) {
492-
SyscallHandler::LateApplyExtendedVolatileMetadata LateMetadata;
493-
FEX::VolatileMetadata::ApplyFEXExtendedVolatileMetadata(
494-
it->second, LateMetadata.VolatileInstructions, LateMetadata.VolatileValidRanges, addr, addr + length, offset, offset + length);
495+
// We now have the filename and the offset in the filename getting mapped.
496+
// Check for extended volatile metadata.
497+
auto it = ExtendedMetaData.find(Filename);
498+
if (it != ExtendedMetaData.end()) {
499+
SyscallHandler::LateApplyExtendedVolatileMetadata LateMetadata;
500+
FEX::VolatileMetadata::ApplyFEXExtendedVolatileMetadata(
501+
it->second, LateMetadata.VolatileInstructions, LateMetadata.VolatileValidRanges, addr, addr + length, offset, offset + length);
495502

496-
if (!LateMetadata.VolatileInstructions.empty() || !LateMetadata.VolatileValidRanges.Empty()) {
497-
VolatileMetadata.emplace(std::move(LateMetadata));
503+
if (!LateMetadata.VolatileInstructions.empty() || !LateMetadata.VolatileValidRanges.Empty()) {
504+
VolatileMetadata.emplace(std::move(LateMetadata));
505+
}
498506
}
499507
}
500508
}

0 commit comments

Comments
 (0)