Contributions are much needed! Emulators are big projects and there’s always a lot of work to do!
I want to optimize instructions
You can get an idea of what sort of RISC-V instructions we emit for an x86-64 instruction by looking in counts/
. If some instruction looks like it could be implemented in a more efficient way, feel free to optimize its respective handler in handlers.cpp
or handlers_x87.cpp
.
If an instruction could be optimized when no flags need to be emitted or under specific circumstances, that’s also welcome!
I want to debug a game
There’s some things to make your life easier. Currently due to a gdb bug our JIT reader gdb implementation is not ready.
Still, here’s some tips:
- When in JIT code, the
s11
RISC-V register holds the x86-64 state- You can view the value individual registers like so:
p/x ((ThreadState*)$s11)->gprs[0]
orp/x ((ThreadState*)$s11)->xmm[0]
- You can view the RIP value:
info reg $gp
in JIT code,p/x ThreadState::Get()->rip
outside of JIT code
- You can view the value individual registers like so:
- Need to know at what offset and which library an address corresponds to? Use print_address from gdb, example:
call print_address(0x10050c)
- The
FELIX86_CALLTRACE=1
environment variable is very useful when debugging. You can executecall dump_states()
from gdb to print the calltraces. It should have symbols if it can find them and should tell you what binary the code is in - If you are not in JIT code, you can get the
ThreadState
object usingp/x ThreadState::Get()
- The
FELIX86_STRACE=1
environment variable makes the emulator produce a trace of all emulated syscalls it runs - Logs are saved in
/tmp/felix86-<PID>-XXXXXX.log
for every run - Verbose logging can be helpful sometimes, set
FELIX86_VERBOSE=1
- The
FELIX86_SLEEP_ERROR
environment variable or thesleep_on_error
option inconfig.toml
can make it so a crashing program sleeps for 40 seconds after printing its PID, giving enough time to attach a debugger. This is particularily useful in situations with manyfork
andexecve
instructions, where debugging with gdb attached from the start can get messy
Feel free to report any findings in the compatibility list!
I want to profile
There’s symbol support for perf
!
Three different modes exist:
- Name each block – enable via
FELIX86_PERF_BLOCKS
- Can be used to identify hot blocks
- You can also use
FELIX86_PERF_SYMBOLS
in combination withFELIX86_PERF_BLOCKS
to export symbols for each block if available
- Name the entire code cache – enable via
FELIX86_PERF_GLOBAL
- Can be used to identify if the hotspot is in the code cache or in C++ code
- Name each library – enable via
FELIX86_PERF_LIBS
- Can be used to identify hot libraries
I use perf top -e cpu-clock -d5 -p <PID>
to get a constantly refreshing view of hotspots.
I want to report an issue with a game
Check out https://github.com/felix86-emu/compatibility-list. Try to follow the format of other issues and use the template!
https://felix86.com/compat/ is manually updated when new issues are added.