mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
LinuxSyscalls: Use a multimap to store MappedResources
This allows for creating separate MappedResources when an ELF file is mapped multiple times at different base addresses.
This commit is contained in:
1 parent
02c00a87dd
commit
92428e5cbc
2 files changed
+34
-12
No files matched your search
@@ -388,11 +388,15 @@ std::optional<SyscallHandler::LateApplyExtendedVolatileMetadata> SyscallHandler:
|
||||
char Tmp[PATH_MAX];
|
||||
auto PathLength = FEX::get_fdpath(fd, Tmp);
|
||||
|
||||
auto [Iter, Inserted] = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, 0});
|
||||
Resource = &Iter->second;
|
||||
if (Inserted) {
|
||||
Resource->Iterator = Iter;
|
||||
auto [ResourceIt, ResourceEnd] = VMATracking.FindResources(mrid);
|
||||
bool Inserted = false;
|
||||
if (ResourceIt == ResourceEnd) {
|
||||
// Create a new MappedResource for previously unseen file
|
||||
ResourceIt = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, 0});
|
||||
ResourceIt->second.Iterator = ResourceIt;
|
||||
Inserted = true;
|
||||
}
|
||||
Resource = &ResourceIt->second;
|
||||
|
||||
// Only handle FDs that are backed by regular files that are executable
|
||||
if (PathLength != -1 && S_ISREG(buf.st_mode) && (buf.st_mode & S_IXUSR)) {
|
||||
@@ -419,8 +423,10 @@ std::optional<SyscallHandler::LateApplyExtendedVolatileMetadata> SyscallHandler:
|
||||
} else if (flags & MAP_SHARED) {
|
||||
VMATracking::MRID mrid {VMATracking::SpecialDev::Anon, AnonSharedId++};
|
||||
|
||||
auto [Iter, Inserted] = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, 0});
|
||||
LOGMAN_THROW_A_FMT(Inserted == true, "VMA tracking error");
|
||||
auto [Iter, IterEnd] = VMATracking.FindResources(mrid);
|
||||
LOGMAN_THROW_A_FMT(Iter == IterEnd, "VMA tracking error");
|
||||
|
||||
Iter = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, 0});
|
||||
Resource = &Iter->second;
|
||||
Resource->Iterator = Iter;
|
||||
} else {
|
||||
@@ -480,11 +486,12 @@ void SyscallHandler::TrackMremap(FEXCore::Core::InternalThreadState* Thread, uin
|
||||
void SyscallHandler::TrackShmat(FEXCore::Core::InternalThreadState* Thread, int shmid, uint64_t shmaddr, int shmflg, uint64_t Length) {
|
||||
VMATracking::MRID mrid {VMATracking::SpecialDev::SHM, static_cast<uint64_t>(shmid)};
|
||||
|
||||
auto [Iter, Inserted] = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, Length});
|
||||
auto Resource = &Iter->second;
|
||||
if (Inserted) {
|
||||
Resource->Iterator = Iter;
|
||||
auto [Iter, IterEnd] = VMATracking.FindResources(mrid);
|
||||
if (Iter == IterEnd) {
|
||||
Iter = VMATracking.InsertMappedResource(mrid, {nullptr, nullptr, Length});
|
||||
Iter->second.Iterator = Iter;
|
||||
}
|
||||
auto Resource = &Iter->second;
|
||||
VMATracking.TrackVMARange(CTX, Resource, shmaddr, 0, Length, VMATracking::VMAFlags::fromFlags(MAP_SHARED), VMATracking::VMAProt::fromSHM(shmflg));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,16 @@ struct MRID {
|
||||
|
||||
struct VMAEntry;
|
||||
|
||||
// Used to all MAP_SHARED VMAs of a system resource.
|
||||
/**
|
||||
* Meta data associated to one system resource.
|
||||
*
|
||||
* Typically there is one instance of this type per ELF/PE file or special device.
|
||||
* However if an ELF/PE file is mapped multiple times at different base addresses,
|
||||
* there will be one separate MappedResource for each base address. The MRID
|
||||
* is the same in this case.
|
||||
*/
|
||||
struct MappedResource {
|
||||
using ContainerType = fextl::map<MRID, MappedResource>;
|
||||
using ContainerType = fextl::multimap<MRID, MappedResource>;
|
||||
|
||||
fextl::unique_ptr<FEXCore::ExecutableFileInfo> MappedFile;
|
||||
// Pointer to lowest memory range this file is mapped to
|
||||
@@ -116,6 +123,14 @@ struct VMATracking {
|
||||
return MappedResources.emplace(mrid, std::move(Resource));
|
||||
}
|
||||
|
||||
// Returns an iterator pair spanning the range of all MappedResources matching the given MRID.
|
||||
// Typically there is only one associated resource, however sometimes the same file gets mapped
|
||||
// multiple times at different base addresses. In that case, each MappedResource will cover an
|
||||
// exclusive set of VMAEntries that refer to a consistent base mapping address.
|
||||
inline auto FindResources(const MRID& mrid) {
|
||||
return MappedResources.equal_range(mrid);
|
||||
}
|
||||
|
||||
private:
|
||||
MappedResource::ContainerType MappedResources;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user