Not 100% correct because the Linux kernel has some cheeky false data
return value when an LDT gets installed. But FEX can't really do it
properly today so whatever.
We want to have two distinct control knobs here. CPU features that don't
change between Linux, Wow64, Arm64ec, and additional options that change
depending on the process environment.
This distinction was a /bit/ muddy where I added
`SupportsFaultFreeSynchronousFaults` to the wrong side of that. Make it
more distinct by logically splitting it out so that HostType, the
fault-free-faults, and added Is64BitMode all lives together.
This lets the DiskCache code which is hashing these variables look a bit
nicer and also correctly logically separate the two halves.
Useful debug feature to make sure FEX returns consistent flag data for
instructions that have undefined flags. Just sets everything that is
undefined to zero always.
Manually walked through all the instructions in the architecture manual
to check for ones doing undefined flag setting, then glued the handler
on to the end.
Also fixes a comment that has incorrect information about undefined
flags.
Found this through introspection, only a real problem with -O0.
We were moving a fextl::vector in to a shared pointer so it can be long
living, this causes a change in ownership which was causing the
`BlobData` pointer to be stale. This was then passed to the work queue
to be consumed. In -O1 and above a std::move of a fextl::vector is a
proper move, but -O0 it turns in to a copy.
Easy fix is to just create the shared_ptr early and reference that, so
the pointer is long lived and no references become stale.
This peephole removes unnecessary masking operations when the mask is
provably all 1s. This improves performance in GB7 'Asset Compression' by
about 2% with SVE and about 4% without SVE.
This doesn't fully fix#5912 but gets a step closer. Instead of just
hashing the filename, hash in the build-id as well when it exists.
This isn't all encompassing because the build-id may not exist in all
cases. Crypt Of the Necrodancer for example doesn't ship with the
build-id on their 64-bit build. Although their legacy 32-bit build had
it.
The build-id is always a hash, depending on tool it is either 64-bit or
160-bit in all the executables I found. Although it can be anything so
make sure to be flexible enough to support everything.
StealMemoryRegion guards the open() with LogMan::Throw::AFmt, which
compiles out in release builds. With no procfs mounted the fd is -1 and
CollectMemoryGaps then loops on read(-1) forever at 100% CPU.
This is hit whenever FEX is the x86_64 binfmt handler and something runs
an x86 binary in a root without /proc. BuildKit does exactly that: its
emulator probe execs a static x86_64 binary in an empty chroot, so every
BuildKit start on an Arm host with FEX registered hangs.
Reserve nothing instead: StealMemoryRegion returns no regions and
Setup48BitAllocatorIfExists skips the 48-bit allocator. The guest then
runs without the upper VA hidden, which only matters in environments
that previously never got past startup.
A bit messy but it basically duplicates the Linux side. We don't have a
way to include NT internal defines in to FEXCore currently so the two
required symbols are just forward declared.
Adds a config option to disable pruning if desired.
Had to change FEXCore::HostFeatures slightly to remove the HostType from
the Hash for caching, as we don't want the bucket to inadvertently
delete wow64,arm64ec,linux buckets when executing in the same namespace.
Minor changes to the DiskCache::Init code to handle returning two
values, moving the HostType to be a part of the "ProcessBucketHash"
instead of the "MachineBucketHash".
Then uses the directory walking function added in the previous commit to
find mismatched/old "MachineBucketHash" directories and remove them.
The base directory is now the machine bucket, which is everything that affects
codegen that you can ask FEX about offline: FEX compiler version, host features.
The DB files now carry a process bucket, which is everything else that can
affect codegen, on the user/process side: 32-bitness and config.
Both together are still the bucket hash that gets laced into every lookup key,
so we still won't load mismatching code because a file is in the wrong spot.