mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 21:00:17 +02:00
The constraints introduced by shared code buffers make supporting calls with the previous layout impossible. The main additional constraint imposed by call-ret that if a host location is ever pushed onto the call-ret stack, then it must forever be a valid jump target. While this is reasonable in the: unlinked, direct linked, unlinked, direct linked case; it's almost impossible to achieve in the: unlinked, indirect linked, unlinked, direct linked case while ensuring all backpatching cases are valid with the current approach. To solve this introduce an additional layer of indirection, jump thunks, these are emitted at the end of a multiblock and are used to handle the two cases of calling the initial linker, and calling an indirect linked block. Initially at the ExitFunction location a branch/call to a unique jump thunk will be emitted, which will have the code layout: 00: b 0x8 04: br TMP1 08: ldr TMP1, <Shared exit linker> 0c: blr TMP1 10: HostCode 18: GuestRIP 20: CallerOffset If a direct link can be performed, then the initial branch/call to the jump thunk can be linked/unlinked to point to the jump thunk in a single 32-bit atomic operation. For an indirect link, the HostCode member is updated with a 64 bit atomic operation, and then a 32 bit atomic operation is used to replace the branch at 00 with a load of HostCode. Indirect unlinks are done by placing back the b 0x8 at 00. Safety: (1) Sequential link (e.g. one waiting to lock, one locked and linking): Linking is idempotent, would just rewrite the same data atomically. (2) Simultaneous link or simultaneous delink: Impossible due to LookupCache locking. (3) Simultaneous link and execute: (3.1) Direct link: Either the direct link is observed at the thunk callsite, or it is not observed and the linker is entered - this is then just (1). (3.2) Indirect link: Either the branch at 00 in the thunk is observed to be replaced with an ldr, in which case the modified HostCode must be observed due to the cache flush. Alternatively the branch replacement isn't observed and it's just (1). (4) Simultaneous unlink and execute: (4.1) Direct link: Either the jump to the jump thunk is seen, which must be in its base unlinked state with the branch at 00 as that would be inserted by any previous indirect unlink. In such a case the linker would just be entered, giving (5). Alternatively the modified jump isn't seen and it calls the original host code (which is fine). (4.2) Indirect link: If an ldr is seen at 00, then the rest of that sequence will function fine as HostCode is left untouched. If a branch is seen at 00, then it will just call the linker giving (5). (5) Sequential unlink then link: Unlinking restores the callsite and jump thunk to their original contents (aside from a modified HostCode). Linking then works as usual.
FEXCore - Fast x86 Core emulation library
This is the core emulation library that is used for the FEX emulator project. This project aims to provide a fast and functional x86-64 emulation library that can meet and surpass other x86-64 emulation libraries.
Goals
- Be as fast as possible, beating and exceeding current options for x86-64 emulation
- 25% - 50% lower performance than native code would be desired target
- Use an IR to efficiently translate x86-64 to our host architecture
- Support a tiered recompiler to allow for fast runtime performance
- Support offline compilation and offline tooling for inspection and performance analysis
- Support threaded emulation. Including emulating x86-64's strong memory model on weak memory model architectures
- Support a significant portion of the x86-64 instruction space.
- Including MMX, SSE, SSE2, SSE3, SSSE3, and SSE4*
- Support fallback routines for uncommonly used x86-64 instructions
- Including x87 and 3DNow!
- Only support userspace emulation.
- All x86-64 instructions run as if they are under CPL-3(userland) security layer
- Minimal Linux Syscall emulation for testing purposes
- Portable library implementation in order to support easy integration in to applications
Target Host Architecture
The target host architecture for this library is AArch64. Specifically the ARMv8.1 version or newer. The CPU IR is designed with AArch64 in mind but should allow for other architectures as well. x86-64 host support is available for ease of development, but is not a priority.
Not desired
- Kernel space emulation
- CPL0-2 emulation
- Real Mode, Protected Mode, Virtual-8086 Mode, System Management Mode
- IRQs
- SVM
- "Cycle Accurate" emulation