A decent amount of this was broken.
To the point that the ABI was incorrect even, causing 32-bit signals to completely crash in most instances.
This is enough to get my 32-bit signal handler test application to work and basic SIGUSR behaviour
vsyscall is a legacy interface to expose three syscalls in a faster fashion.
Most applications should have moved to vDSO but this isn't entirely the case.
golang specifically still used vsyscall in the case that vdso isn't available.
Which that isn't completely safe since vsyscall can be completely disabled.
This is fixed in a newer version of their runtime but we must support legacy behaviour.
This makes it so FEX checks if the incoming RIP is a "special" region and adjusts where it
loads instructions from accordingly. Lying to the guest application about the instruction stream
while maintaining the illusion that its RIP is in the correct location.
This was fairly straightforward since we already decoupled the instruction stream from the RIP location.
This fixes golang execution as long as you also disable their preempt signaling.
environment variable to do so is `GODEBUG=asyncpreemptoff=1`
These are some fairly large separate files still.
Don't want these to be too terribly small but helps significantly with compile time when working
in the OpcodeDispatcher
Prior to the introduction of fmt, there wasn't a nice and easy way to
format std::string_view, but now that we have it in place, we can modify
relevant log calls to make use of it and get rid of the need to
construct a string around the view.
While we're in the same area, we can make the rest of the modified file
use fmt where appropriate.
The entire object didn't need to be an Allocator.
Additionally there was an overwrite happening on the Size variable.
This was causing the shutdown to free a size of zero.
MUL is handled in a different function, so this isn't needed there anymore.
This was causing a problem where if you force enabled LOCK on all capable ops it was causing a crash.
Issue #1164 is set to track getting unit tests for these.
This needs to end up 32-bit space which means we shouldn't use the FEXCore Allocator.
FEXCore allocator has a hack in it for fixed offset in 32-bit space, but we shouldn't rely on it
In the case that paranoid TSO is enabled, we can force all unaligned loadstores
down this path.
Instead of backpatching, just do the unaligned loadstore in the handler
This allows us to capture LDAXR* instructions which appear in ARMv8.0 memory ops.
These scan the memory space to see what the loop is doing and then make an atomic decision to handle
the loadstore exclusive loop with our signal handler based CAS atomics.
This will be necessary to support `LOCK NEG` on ARMv8.1+
If we want to do atomic memory loads that are unaligned then we need some helpers to do these.
LoadAcquire128 needs to specifically avoid the std::atomic helper because it can try storing to read only memory
It does this to clear the exclusive lock from its ldaxp but we can just use clrex.
The unaligned signal handler will backpatch these with DMBs.
Previously generating corrupted code. This will fix that corruption but not the atomicity problem
This cuts start up time from 8.962ms to 3.949ms and lets us use less physical memory.
We pay a small amortized cost from the faulting to populate pages which will be fairly low
These are in place to let applications know that we do our own thermal management
TM was introduced with Pentium M, it would dispatch idle uops to counter thermals.
TM2 was later and is what allows the CPU to dynamically change its multiplier and frequency.
All in an effort to not cook themselves.
Our ARM CPUs also do all this. Claim it as well.
There were two bugs in here.
The first bug here is with with the CMPXCHG emulation.
1) If the *Expected* value did *NOT* match what was in memory
2) *AND* The *Desired* value matched the memory value
3) The CAS would incorrectly return success for this CMPXCHG
4) Thus setting ZF incorrectly
The second bug comes from atomic memory operations (Add, CLR, EOR, SET, SWAP).
This operation is a Load + <Op> + CAS
1) If the memory backing between the Load and CAS changes
2) The CAS would then fail
3) On Atomic memory operations this should then retry to ensure it completes successfully
4) We were not retrying on failure in this case
5) Thus something like `LOCK INC` would have never atomically incremented correctly
6) We can't use our ASM unit tests to test this, since it needs thread contention.
This makes it a little more straightforward to see what these return
values mean without needing to look at the implementation.
These tuples were also getting a little bit large.
Same behavior, but allows clang to elide pushing all of these values on
and off the stack, particularly given these are called quite frequently
throughout the opcode dispatcher.
Don't print how many instructions are installed in the tables.
This isn't useful anymore
Not installing signal 32 and 33 are something we don't support right now. Stop complaining in that case.
Stop printing when a thread is starting up and shutting down. If you want to see this then gdb shows it well.
Don't print clone flags unless we are hitting a case where we are printing another log message.
si_addr will still be incorrect. What matters more here is that SIGCHLD gets correct information.
The guest needs SIGCHLD ifnromation to be filled out correctly, otherwise TTY handoff hangs
with the child process stopped.
I saw a red herring that I thought the high cpu usage in steamwebhelper could come from signal handlers.
This turned out to not be the case, but now I've got this implemented.
Installs the few signal handlers that we need upfront but for everything that isn't a mandatory signal
we instead now wait until the guest also installs that signal handler.
This fixes#1107