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
s11RISC-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 $gpin JIT code,p/x ThreadState::Get()->ripoutside 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=1environment 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
ThreadStateobject usingp/x ThreadState::Get() - The
FELIX86_STRACE=1environment variable makes the emulator produce a trace of all emulated syscalls it runs - Logs are saved in
/tmp/felix86-<PID>-XXXXXX.logfor every run - Verbose logging can be helpful sometimes, set
FELIX86_VERBOSE=1 - The
FELIX86_SLEEP_ERRORenvironment variable or thesleep_on_erroroption inconfig.tomlcan 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 manyforkandexecveinstructions, 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_SYMBOLSin combination withFELIX86_PERF_BLOCKSto 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.