<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.fex-emu.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Neobrain</id>
	<title>FEX-Emu Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.fex-emu.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Neobrain"/>
	<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php/Special:Contributions/Neobrain"/>
	<updated>2026-04-28T18:00:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1498</id>
		<title>Development:Setting up RootFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1498"/>
		<updated>2026-01-13T14:47:15Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Setting up a RootFS =&lt;br /&gt;
'''For AArch64 hosts you are required to have an x86-64 rootfs'''. With or without 32bit compatibility libraries.&lt;br /&gt;
&lt;br /&gt;
This isn't strictly required for testing on x86-64 host environments but is useful for ensuring correct behaviour there.&lt;br /&gt;
&lt;br /&gt;
= Quick Setup with FEXRootFSFetcher =&lt;br /&gt;
FEX comes with a FEXRootFSFetcher tool that can download an official preconfigured rootfs from the FEX servers.&lt;br /&gt;
This tool operates as either a terminal application or a Zenity application depending on if it is launched from terminal or not.&lt;br /&gt;
&lt;br /&gt;
This tool will walk you through selecting a RootFS for FEX:&lt;br /&gt;
* If your host OS matches one in the download list then it will recommend that one&lt;br /&gt;
* After selecting the RootFS, it will download it&lt;br /&gt;
** This downloads to the default location in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
* After downloading the RootFS the tool will ask if you want to use the SquashFS file directly or extract it&lt;br /&gt;
* It will then ask if you want to set the downloaded RootFS as your default&lt;br /&gt;
** This writes to the default configuration in '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
You can skip the rest of the guide if you used FEXRootFSFetcher to download the rootfs.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
* The squashfs image will fail to extract if you don't have unsquashfs installed&lt;br /&gt;
** Install the squashfs-tools package to get this application&lt;br /&gt;
&lt;br /&gt;
* '''SquashFS RootFS file corrupted?'''&lt;br /&gt;
** Rerun the tool, select the rootfs from the list, and if the rootfs already exists it will ask to verify&lt;br /&gt;
** If verification fails it will ask if you want to redownload&lt;br /&gt;
* '''Want to manually check the hash?'''&lt;br /&gt;
** Run the rootfs file directly through the tool to get a hash&lt;br /&gt;
** '''FEXRootFSFetcher $HOME/.fex-emu/RootFS/Ubuntu_21_10.sqsh'''&lt;br /&gt;
** Ubuntu_21_10.sqsh has hash: bf9507fbdbaec2cf&lt;br /&gt;
* '''Want to use the Zenity UI but still launch through terminal?'''&lt;br /&gt;
** Force Zenity from terminal with '''FEXRootFSFetcher 1&amp;gt; /dev/null'''&lt;br /&gt;
* '''What if my Linux distro isn't listed?'''&lt;br /&gt;
** Don't worry, select one that is most similar to yours or newest&lt;br /&gt;
** This will work in most cases&lt;br /&gt;
* '''How can I trust these images?'''&lt;br /&gt;
** These images are generated by scripts living in our public repo&lt;br /&gt;
** If you want to rebuild them yourself, you are free to do so.&lt;br /&gt;
** https://github.com/FEX-Emu/RootFS&lt;br /&gt;
* '''I want to add a distro'''&lt;br /&gt;
** Follow how our current rootfs is generated and add your own&lt;br /&gt;
** Open a pull request to add the rootfs setup&lt;br /&gt;
** Contact us on the official FEX-Emu Discord to get the RootFS added to the server.&lt;br /&gt;
* '''Where is the raw list of images at?'''&lt;br /&gt;
** The image links live on our website at the following link&lt;br /&gt;
** https://rootfs.fex-emu.gg/RootFS_links.json&lt;br /&gt;
** This file is in a format that our tool understands&lt;br /&gt;
** Generally the format is:&lt;br /&gt;
*** Distro Name&lt;br /&gt;
*** Distro Version&lt;br /&gt;
*** Human readable name&lt;br /&gt;
*** Raw rootfs link&lt;br /&gt;
*** xxhash based file hash&lt;br /&gt;
&lt;br /&gt;
= Making a custom rootfs prerequisites =&lt;br /&gt;
An x86-64 PC or FEX-Emu installed for chrooting&lt;br /&gt;
&lt;br /&gt;
= Getting Started =&lt;br /&gt;
The easiest way to get started is to just download a prebuilt x86-64 rootfs from your favourite distribution and extract it to where you want.&lt;br /&gt;
* Ubuntu - http://cdimage.ubuntu.com/ubuntu-base/releases/&lt;br /&gt;
* Debian Debootstrap guide - https://wiki.debian.org/Debootstrap&lt;br /&gt;
** Debootstrap is more involved and not explained here.&lt;br /&gt;
&lt;br /&gt;
Using chroot you can then enter the rootfs and install applications that you desire for testing purposes.&lt;br /&gt;
It's easiest to set this up on an x86-64 host and then copy it to an AArch64 device.&lt;br /&gt;
&lt;br /&gt;
== Cross architecture chroot ==&lt;br /&gt;
'''You need to have binfmt_misc setup for x86-64 support on your host system.'''&lt;br /&gt;
* ls /proc/sys/fs/binfmt_misc &lt;br /&gt;
** If there are files in this folder then your host supports binfmt_misc&lt;br /&gt;
* Once you have binfmt_misc running and FEX-Emu installed in to it, you can chroot in to an x86-64 rootfs&lt;br /&gt;
&lt;br /&gt;
== Chrooting into FEX-provided RootFS ==&lt;br /&gt;
* If you're using a FEX-provided RootFS, we provide a script to handle this:&lt;br /&gt;
** To enter, use '''./chroot.py chroot''' inside the root directory of the RootFS&lt;br /&gt;
** When you finish, make sure to exit the chroot cleanly&lt;br /&gt;
If the chroot is working, the remaining steps of this guide can safely be skipped.&lt;br /&gt;
&lt;br /&gt;
* Issues&lt;br /&gt;
** As of January 12th, 2026, Fedora packages for FEX-Emu are a few months out of date. &lt;br /&gt;
** This causes the chroot script to fail, saying &amp;quot;Host program 'FEX' isn't available and is required!&amp;quot;.&lt;br /&gt;
** The solution is to copy &amp;quot;/usr/bin/FEXInterpreter&amp;quot; to &amp;quot;/usr/bin/FEX&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Chrooting into custom RootFS ==&lt;br /&gt;
* If you're setting up your own rootfs then you need to follow the binding steps that are following.&lt;br /&gt;
** We have a script that if you know what you're doing you can cherry pick parts from [https://github.com/FEX-Emu/RootFS/blob/main/unbreak_chroot.sh here]&lt;br /&gt;
&lt;br /&gt;
= Additional TmpFS folders =&lt;br /&gt;
Depending on what you're doing in the chroot, you may need or want some tmpfs folders that applications are expecting&lt;br /&gt;
&lt;br /&gt;
* sudo mount -t proc /proc ${ROOTFS}/proc/&lt;br /&gt;
* sudo mount --rbind --make-rslave /sys ${ROOTFS}/sys/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev ${ROOTFS}/dev/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev/pts ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo mount --rbind /lib/ld-linux-aarch64.so.1 ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo mount --rbind /lib/aarch64-linux-gnu ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
Then of course, make sure to unmount these partitions when you're done&lt;br /&gt;
&lt;br /&gt;
* sudo umount ${ROOTFS}/proc/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/sys/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
= Using the RootFS with FEX =&lt;br /&gt;
&lt;br /&gt;
Run the graphical FEXConfig tool to select and change the active RootFS. Any file or folder in $HOME/.fex-emu/RootFS will be detected automatically.&lt;br /&gt;
&lt;br /&gt;
= Additional Steps for building a custom rootfs = &lt;br /&gt;
== Running under WSL1 ==&lt;br /&gt;
/etc/hosts and /etc/resolv.conf change on the host side. You'll need to copy those over to the rootfs if you want network functionality to work.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu packages to install ==&lt;br /&gt;
Sample packages to install in the rootfs&lt;br /&gt;
* apt-get install pulseaudio libgles1 libgles2 libglx-mesa0 libgl1-mesa-dri libgl1-mesa-glx mesa-utils mesa-utils-extra&lt;br /&gt;
Pulseaudio specifically is required so pulseaudio will work when talking to the host pulseaudio&lt;br /&gt;
&lt;br /&gt;
== File deletion ==&lt;br /&gt;
Some files need to be deleted from the rootfs otherwise some applications will fail to work.&lt;br /&gt;
&lt;br /&gt;
Note that deleting these files '''WILL''' break the rootfs and you won't be able to chroot in to it anymore.&lt;br /&gt;
&lt;br /&gt;
A likely better route would be a script that moves these files and folders then brings them back when you want to chroot&lt;br /&gt;
&lt;br /&gt;
=== Files to remove ===&lt;br /&gt;
* ${ROOTFS}/etc/hosts&lt;br /&gt;
* ${ROOTFS}/etc/resolv.conf&lt;br /&gt;
* ${ROOTFS}/etc/timezone&lt;br /&gt;
* ${ROOTFS}/etc/localtime&lt;br /&gt;
* ${ROOTFS}/etc/passwd&lt;br /&gt;
&lt;br /&gt;
=== Folders to remove ===&lt;br /&gt;
* ${ROOTFS}/boot&lt;br /&gt;
* ${ROOTFS}/dev&lt;br /&gt;
* ${ROOTFS}/home&lt;br /&gt;
* ${ROOTFS}/media&lt;br /&gt;
* ${ROOTFS}/mnt&lt;br /&gt;
* ${ROOTFS}/proc&lt;br /&gt;
* ${ROOTFS}/root&lt;br /&gt;
* ${ROOTFS}/srv&lt;br /&gt;
* ${ROOTFS}/tmp&lt;br /&gt;
* ${ROOTFS}/var/cache/apt&lt;br /&gt;
* ${ROOTFS}/var/lib/apt&lt;br /&gt;
* ${ROOTFS}/sys&lt;br /&gt;
* ${ROOTFS}/opt&lt;br /&gt;
&lt;br /&gt;
== Creating a Squashfs rootfs from custom rootfs ==&lt;br /&gt;
SquashFS is a great way to do binary distribution of the rootfs. If you have created a rootfs and you want to roll it in to a squashfs like the FEX-Emu provided images then this is information on how to do that.&lt;br /&gt;
&lt;br /&gt;
'''SquashFS is currently only recommended for binary distribution. User should unpack it to not get dangling processes and mounts.'''&lt;br /&gt;
* Offers tooling to mount in userspace&lt;br /&gt;
* Supports ZSTD compression&lt;br /&gt;
* Is a readonly partition that matches FEX's use case&lt;br /&gt;
&lt;br /&gt;
=== Tools that FEX needs to run squashfs ===&lt;br /&gt;
* squashfuse&lt;br /&gt;
* fusermount&lt;br /&gt;
&lt;br /&gt;
=== Making the squashfs image ===&lt;br /&gt;
Making the squashfs image is very straightforward&lt;br /&gt;
* mksquashfs ${ROOTFS}/ Squashfs.sqsh -comp zstd&lt;br /&gt;
&lt;br /&gt;
This creates a file called Squashfs.sqsh that contains the original rootfs that we generated above.&lt;br /&gt;
&lt;br /&gt;
=== Using the squashfs image in FEX ===&lt;br /&gt;
* Copy the resulting sqsh file in to ${XDG_DATA_HOME}/.fex-emu/RootFS/&lt;br /&gt;
** If ${XDG_DATA_HOME} doesn't exist then that will be replaced with ${HOME}&lt;br /&gt;
* Use FEXConfig to select the sqsh file as a named rootfs&lt;br /&gt;
* or pass the name in to the FEX_ROOTFS argument in the various ways FEX supports&lt;br /&gt;
* or the absolute path if you don't want it in the FEX RootFS folder&lt;br /&gt;
&lt;br /&gt;
=== Extracting the squashfs ===&lt;br /&gt;
If you don't want to use squashfs for whatever reason then you can extract it in to the FEX RootFS folder and use the directory directly&lt;br /&gt;
* unsquashfs -f -d NewRootFS/ Squashfs.sqsh&lt;br /&gt;
&lt;br /&gt;
=== If you want to install packages in the squashfs ===&lt;br /&gt;
The squashfs image is immutable and can't be modified.&lt;br /&gt;
* Extract the squashfs first&lt;br /&gt;
* Change the working directory to the rootfs&lt;br /&gt;
* execute `unbreak_chroot.sh`&lt;br /&gt;
* `apt-get update`&lt;br /&gt;
* `apt-get install &amp;lt;Whatever you want&amp;gt;`&lt;br /&gt;
* `exit` to leave the chroot&lt;br /&gt;
* Use the new extracted chroot directly, or follow the previous steps to recompress it to a squashfs format.&lt;br /&gt;
&lt;br /&gt;
=== Known problems with squashfs ===&lt;br /&gt;
'''FEX automatically mounts your squashfs file and can leave dangling squashfs mounts around in some instances.'''&lt;br /&gt;
* '''This is fairly rare but it can occur. Whenever an instance of FEX is run, it registers with the FEXMountDaemon'''&lt;br /&gt;
** FEXMountDaemon then watches these instances of FEX to ensure they have exited before unmounting&lt;br /&gt;
** There is roughly a ten second grace period of no instances of FEX running before unmounting&lt;br /&gt;
** If an instance of FEX starts running then it will reuse the mount partition and reset the timeout&lt;br /&gt;
* To get rid of these dangling mounts if they do manage to manifest, use the following commands&lt;br /&gt;
** fusermount -u /tmp/.FEXMount* ; rmdir /tmp/.FEXMount*&lt;br /&gt;
** These don't require root to unmount&lt;br /&gt;
* In some cases the unmounting can end up returning busy status and not unmount&lt;br /&gt;
** Check the output of `mount` for any /tmp/.FEXMount folders&lt;br /&gt;
** This is due to either FEXMountDaemon or squashfuse still running in the background&lt;br /&gt;
** Can force the application to exit&lt;br /&gt;
** step 1: kill `pidof squashfuse`&lt;br /&gt;
** This will attempt to send SIGTERM to all squashfuse applications, which will unmount the partition on terminate&lt;br /&gt;
** Failing that, you can try to be more abusive&lt;br /&gt;
** kill -9 `pidof FEXMountDaemon`&lt;br /&gt;
** This will forcibly terminate FEXMountDaemon which should also take out the child mounted process&lt;br /&gt;
* If any instances of the mount still exists then you may need to kill more FEX processes.&lt;br /&gt;
** Any ''FEX'' process will end up keeping the folder mounted and keep it busy&lt;br /&gt;
&lt;br /&gt;
'''strace breaks squashfs'''&lt;br /&gt;
* If you run FEX with `strace -f` then the process that mounts your rootfs loses its setuid bit.&lt;br /&gt;
** This means you then can't mount the rootFS&lt;br /&gt;
* The only workaround is to not use a squashfs in this instance.&lt;br /&gt;
* Alternatively you can spin up a FEXBash instance to force squashfs to be mounted. Then strace a different FEX instance which will use the mounted squashfs location.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=1452</id>
		<title>Development:Adding Config Options</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=1452"/>
		<updated>2025-09-22T14:16:24Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Fix broken list formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
Configuration options are programatically generated from json.&lt;br /&gt;
&lt;br /&gt;
This file lives in `FEXCore/Source/Interface/Config/Config.json`&lt;br /&gt;
&lt;br /&gt;
= Options section =&lt;br /&gt;
To add a configuration option that can be set from JSON or from environment variables, you need to add the option to this file.&lt;br /&gt;
&lt;br /&gt;
Currently FEX has six groups to group configs&lt;br /&gt;
* CPU&lt;br /&gt;
* Emulation&lt;br /&gt;
* Debug&lt;br /&gt;
* Logging&lt;br /&gt;
* Hacks&lt;br /&gt;
* Misc&lt;br /&gt;
&lt;br /&gt;
== Configuration option object ==&lt;br /&gt;
Each JSON object under a group becomes a configuration.&lt;br /&gt;
&lt;br /&gt;
'''Object Layout'''&lt;br /&gt;
* Key:&lt;br /&gt;
** Becomes the C++ enum. eg. 'Multiblock' becomes `FEXCore::Config::ConfigOption::CONFIG_MULTIBLOCK`&lt;br /&gt;
** Also used for the environment variable. Becomes `FEX_MULTIBLOCK`&lt;br /&gt;
** If the object type is boolean then a negated argument also is generated. `--no-multiblock`&lt;br /&gt;
&lt;br /&gt;
* Type:&lt;br /&gt;
** Can be `[bool, uint8, int32, uint32, uint64, str, strarray]`&lt;br /&gt;
** This is what the argument type ends up being once loaded from a configuration backing&lt;br /&gt;
&lt;br /&gt;
* Default:&lt;br /&gt;
** Default value that matches this object&lt;br /&gt;
** Used to generate code so needs to handle being codified. Compilation will fail otherwise&lt;br /&gt;
** If Type is str or strarray then this string will be automatically wrapped with double-quotes when generated&lt;br /&gt;
&lt;br /&gt;
* TextDefault:&lt;br /&gt;
** If the `Default` option which is used in code can't be represented by text. Like an enum being used.&lt;br /&gt;
** eg. `Core` has a `Default` which is an enum. `TextDefault` is set to `irjit` for the user to handle this case&lt;br /&gt;
&lt;br /&gt;
* Choices:&lt;br /&gt;
** Allows us to represent the textual options that a argument can accept&lt;br /&gt;
** eg. `Core` supports `[ &amp;quot;irint&amp;quot;, &amp;quot;irjit&amp;quot;, &amp;quot;host&amp;quot; ]`&lt;br /&gt;
&lt;br /&gt;
* ArgumentHandler:&lt;br /&gt;
** If an argument option needs some special handling to be parsed then this points to a C++ function in the argument loader&lt;br /&gt;
** `Core` uses it to convert the textual representation in to an enum&lt;br /&gt;
&lt;br /&gt;
* Desc:&lt;br /&gt;
** Short description of what this option does&lt;br /&gt;
** This is used to generate the text in the man pages&lt;br /&gt;
&lt;br /&gt;
== UnnamedOptions section ==&lt;br /&gt;
These are configuration options that can '''NOT''' be set by user means. There won't be any Environment variable or json helpers generated to load these.&lt;br /&gt;
&lt;br /&gt;
These need to exist as a way to have internal configuration options existing in the same global space as user options. Allows us to pull internal configuration options the same way as user configurations.&lt;br /&gt;
&lt;br /&gt;
These can exist under any group config. Currently only `Misc` is used. Only three things need to be set for these&lt;br /&gt;
* Key: This is only used to generate the enum in code&lt;br /&gt;
* Type: Same supported types as the regular options&lt;br /&gt;
* Default: The default value of this configuration&lt;br /&gt;
&lt;br /&gt;
== Getting configurations in FEX code ==&lt;br /&gt;
FEX provides a `FEX_CONFIG_OPT` define to help developers get configuration options.&lt;br /&gt;
* FEX_CONFIG_OPT(name, enum)&lt;br /&gt;
** eg: `FEX_CONFIG_OPT(Cores, THREADS);`&lt;br /&gt;
** This will load the THREADS configuration option from the configuration directory and save the value in to local value called `Cores`&lt;br /&gt;
* Gotchas:&lt;br /&gt;
** Construction of the object queries the the global configuration layer. This can be slow so be careful with its use.&lt;br /&gt;
** Upon construction of the `FEXCore::Config::Value&amp;lt;T&amp;gt;` object it will pull the string configuration&lt;br /&gt;
** Then it will convert that value in to whatever type the value needs&lt;br /&gt;
** In high performance code, keep constructor instantiation outside of the hot code path&lt;br /&gt;
** Construct the configuration inside of a class definition so it only pulls the configuration once&lt;br /&gt;
* Caveats:&lt;br /&gt;
** If the configuration changes then this doesn't pick up the change&lt;br /&gt;
** Configuration isn't meant to change live in FEX so this is typically a non-issue&lt;br /&gt;
** Frontend object loader needs to be careful with its configuration loading to ensure the meta layer stays in sync&lt;br /&gt;
** ELFLoader.cpp for examples here&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=1451</id>
		<title>Development:Debugging Crash</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=1451"/>
		<updated>2025-09-22T14:13:23Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Remove screenshot of outdated FEXConfig interface&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting Started ==&lt;br /&gt;
* Debug an application with `gdb --args FEX &amp;lt;application full path&amp;gt;`&lt;br /&gt;
* Under GDB make sure to do `handle SIGBUS SIGILL SIG63 noprint`&lt;br /&gt;
** We use signals for various things, check out [[Development:Debugging_FEX_with_Signals|Here]] for more information&lt;br /&gt;
&lt;br /&gt;
== Crash in emulated/JIT code ==&lt;br /&gt;
Walking through debugging a simple test application that is crashing.&lt;br /&gt;
  $ gdb --args FEX ./sigsegv_test&lt;br /&gt;
  Reading symbols from FEX...&lt;br /&gt;
  (gdb) r&lt;br /&gt;
  Starting program: /usr/bin/FEX ./sigsegv_test&lt;br /&gt;
  [Thread debugging using libthread_db enabled]&lt;br /&gt;
  Using host libthread_db library &amp;quot;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;quot;.&lt;br /&gt;
  [New Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  &lt;br /&gt;
  Thread 2 &amp;quot;FEX received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  [Switching to Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  0x0000007fccfb9ec8 in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay, we have a sigsegv. Let's double check that it is JIT code (aka, guest emulated code)&lt;br /&gt;
  (gdb) disas $pc,+32&lt;br /&gt;
  Dump of assembler code from 0x7fe26ebc20 to 0x7fe26ebc40:&lt;br /&gt;
  =&amp;gt; 0x0000007fe26ebc20:  stlrb   w22, [x21]&lt;br /&gt;
     0x0000007fe26ebc24:  mov     x4, #0x0                        // #0&lt;br /&gt;
     0x0000007fe26ebc28:  ldr     x10, [x20]&lt;br /&gt;
     0x0000007fe26ebc2c:  add     x21, x20, #0x8&lt;br /&gt;
     0x0000007fe26ebc30:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc34:  strb    w22, [x28, #428]&lt;br /&gt;
     0x0000007fe26ebc38:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc3c:  strb    w22, [x28, #431]&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb) info reg x9&lt;br /&gt;
  x9             0x0                 0&lt;br /&gt;
* Looks like JIT code, even doing accesses to x28 which is the FEX CPU state&lt;br /&gt;
* Code has no backtrace which reinforces this&lt;br /&gt;
* Code is doing an atomic store, which reinforces this is FEX emulating the x86 TSO memory model&lt;br /&gt;
&lt;br /&gt;
* Now that we have checked that we are in the JIT code. Where are we in the guest side?&lt;br /&gt;
* Let's dump the FEX CPU state information that is directly pointed to in x28 at all times in JIT code.&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State&lt;br /&gt;
  $3 = {rip = 0x401110, gregs = {0x416eb0, 0x7fe1e3b640, 0xffffffffffffff70, 0x0, 0x7fe1e3bf30, 0x0, 0x416eb0, 0x7fe1e3ae28, 0x0, 0x7fe1e3b640, 0x8, 0x7fe2054cc0, 0x7ff75ff48e, 0x7ff75ff48f, 0x0, 0x7fe163b000}, xmm = {{0x0, 0x0}, {0x0, 0x0}, {0xdeadbeef, 0xbad0dad1} &amp;lt;repeats 14 times&amp;gt;}, es = 0x0, cs = 0x0, ss = 0x0, ds = 0x0, gs = 0x0, fs = 0x7fe1e3b640, flags = {0x0, 0x1, 0x0,&lt;br /&gt;
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 &amp;lt;repeats 38 times&amp;gt;}, mm = {{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}}, gdt = {{base = 0x0} &amp;lt;repeats 32 times&amp;gt;}, FCW = 0x37f, FTW = 0xffff}&lt;br /&gt;
&lt;br /&gt;
* Looks like our guest RIP is currently `0x401110`&lt;br /&gt;
** Consult the `info proc mappings` again&lt;br /&gt;
  0x401000           0x402000     0x1000     0x1000 {...}/sigsegv_test&lt;br /&gt;
* Yep, we are inside our test application&lt;br /&gt;
* For a simple test, let's load the application in gdb-multiarch and disassemble where we are&lt;br /&gt;
  $ gdb-multiarch ./sigsegv_test&lt;br /&gt;
  Reading symbols from ./sigsegv_test...&lt;br /&gt;
  (gdb) set disassembly-flavor intel&lt;br /&gt;
  (gdb) disas 0x401110&lt;br /&gt;
  Dump of assembler code for function main(int, char**):&lt;br /&gt;
     0x0000000000401110 &amp;lt;+0&amp;gt;:     push   rbp&lt;br /&gt;
     0x0000000000401111 &amp;lt;+1&amp;gt;:     mov    rbp,rsp&lt;br /&gt;
     0x0000000000401114 &amp;lt;+4&amp;gt;:     mov    DWORD PTR [rbp-0x4],0x0&lt;br /&gt;
     0x000000000040111b &amp;lt;+11&amp;gt;:    mov    DWORD PTR [rbp-0x8],edi&lt;br /&gt;
     0x000000000040111e &amp;lt;+14&amp;gt;:    mov    QWORD PTR [rbp-0x10],rsi&lt;br /&gt;
     0x0000000000401122 &amp;lt;+18&amp;gt;:    mov    rax,QWORD PTR [rbp-0x10]&lt;br /&gt;
     0x0000000000401126 &amp;lt;+22&amp;gt;:    movsxd rcx,DWORD PTR [rbp-0x8]&lt;br /&gt;
     0x000000000040112a &amp;lt;+26&amp;gt;:    mov    rax,QWORD PTR [rax+rcx*8]&lt;br /&gt;
     0x000000000040112e &amp;lt;+30&amp;gt;:    mov    QWORD PTR [rbp-0x18],rax&lt;br /&gt;
     0x0000000000401132 &amp;lt;+34&amp;gt;:    mov    rax,QWORD PTR [rbp-0x18]&lt;br /&gt;
     0x0000000000401136 &amp;lt;+38&amp;gt;:    mov    BYTE PTR [rax],0x63&lt;br /&gt;
     0x0000000000401139 &amp;lt;+41&amp;gt;:    xor    eax,eax&lt;br /&gt;
     0x000000000040113b &amp;lt;+43&amp;gt;:    pop    rbp&lt;br /&gt;
     0x000000000040113c &amp;lt;+44&amp;gt;:    ret&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb)&lt;br /&gt;
&lt;br /&gt;
* Okay, not super helpful since FEX translates instructions in to blocks, `0x401110` is just our starting address&lt;br /&gt;
** It's in this code somewhere, let's change some FEX settings to get a clearer picture&lt;br /&gt;
* Set block size to one instruction and disable multiblock&lt;br /&gt;
* Now rerun our test application and find the new RIP&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State.rip&lt;br /&gt;
  $2 = 0x401136&lt;br /&gt;
&lt;br /&gt;
* Alright, now we know the RIP is exactly at `0x401136`&lt;br /&gt;
* Back in gdb-multiarch&lt;br /&gt;
  (gdb) disas 0x401136,+1&lt;br /&gt;
  Dump of assembler code from 0x401136 to 0x401137:&lt;br /&gt;
     0x0000000000401136 &amp;lt;main(int, char**)+38&amp;gt;:   mov    BYTE PTR [rax],0x63&lt;br /&gt;
&lt;br /&gt;
* Looks like something in main is storing 0x63 to a nullptr&lt;br /&gt;
* In this simple case we can now take a look at the test application's source and find the problem.&lt;br /&gt;
** We know the problem is in the first block of main()&lt;br /&gt;
** We know the exact instruction that it is at&lt;br /&gt;
** We know it's something storing a byte to memory&lt;br /&gt;
* For more complex cases it is likely necessary to use reverse engineering tools&lt;br /&gt;
** BinaryNinja, Ghidra, IDA, and Hopper are all examples of tools like this&lt;br /&gt;
&lt;br /&gt;
== What to do from here ==&lt;br /&gt;
Now it becomes a lot harder. You don't get a typical debugging environment or even clean backtraces.&lt;br /&gt;
&lt;br /&gt;
FEX's gdbserver integration is sorely lacking so you can't even use a remote gdb server connecting to FEX right now.&lt;br /&gt;
&lt;br /&gt;
If you enable thunks you can get better backtraces here. [[Development:Debugging_Crash_In_Thunks|Debugging_Crash_In_Thunks]]&lt;br /&gt;
&lt;br /&gt;
== Attempting to use FEX-Emu's gdbserver implementation ==&lt;br /&gt;
'''Here be dragons'''&lt;br /&gt;
&lt;br /&gt;
FEX supports gdbserver as an integration. It's implementation is significantly limited but can still be used for debugging and getting some backtraces.&lt;br /&gt;
* Currently hardcodes the port to use as `8086` and if you have multiple gdbserver processes running then it will encounter problems.&lt;br /&gt;
* Currently does not follow processes through fork/execve at all. No multiprocess support&lt;br /&gt;
** This means you '''must''' only start the process you're caring about debugging&lt;br /&gt;
* Currently starts the process paused and will wait until gdb attach before continuing&lt;br /&gt;
** No way to start a FEX instance then attach at some later point&lt;br /&gt;
* Ctrl-C to stop the FEX process needs to be done twice&lt;br /&gt;
** Maybe with a small delay inbetween because gdb needs to fetch a bunch of data on pause&lt;br /&gt;
** Known bug, unknown why broken at the moment&lt;br /&gt;
&lt;br /&gt;
  FEXLoader -G -- &amp;lt;Application&amp;gt; &amp;lt;Args...&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Double checking if we are in JIT code ==&lt;br /&gt;
  (gdb) info reg pc&lt;br /&gt;
  pc             0x7fccfb9ec8        0x7fccfb9ec8&lt;br /&gt;
  &lt;br /&gt;
  (gdb) info proc mappings&lt;br /&gt;
  ...&lt;br /&gt;
  0x7fccfb9000       0x7fcdfb9000  0x1000000        0x0&lt;br /&gt;
&lt;br /&gt;
* Looks like FEX JIT mapping, we start out at 16MB but scale up to 128MB&lt;br /&gt;
* Depending on version of FEX we can check the base mapping for a unique string &lt;br /&gt;
  (gdb) p (char*)0x7fccfb9000&lt;br /&gt;
  $4 = 0x7fccfb9000 &amp;quot;FEXJIT::Arm64JITCore::&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Getting RIP of current code block ==&lt;br /&gt;
FEX sets up an address in our CPU context to get some debug data out.&lt;br /&gt;
&lt;br /&gt;
Currently this isn't exposed in a way that a debugger can see other than manually typing out gdb commands&lt;br /&gt;
&lt;br /&gt;
  p/x *(uint64_t*)($x28) = inline block header ptr&lt;br /&gt;
  p/x *(uint32_t*)(*(uint64_t*)($x28)) = OffsetToBlockTail&lt;br /&gt;
  p/x *(uint64_t*)($x28) + *(uint32_t*)(*(uint64_t*)($x28))&lt;br /&gt;
&lt;br /&gt;
  p/x *(unsigned long long*)((*(unsigned long long*)($x28) + *(unsigned int*)(*(unsigned long long*)($x28)))+8) = RIP of block&lt;br /&gt;
&lt;br /&gt;
  disas *(unsigned long long*)($x28),+*(unsigned long long*)(*(unsigned long long*)($x28) + *(unsigned int*)(*(unsigned long long*)($x28))) = Disassemble this block of code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While hard to decipher here is basically what is happening.&lt;br /&gt;
- x28 is the CPU register that FEX keeps in the JIT for context accesses&lt;br /&gt;
- offset 184 is the offset of the `InlineJITBlockHeader` member inside of that context.&lt;br /&gt;
- As long as FEX is in a JIT block that offset will be valid to point to the current RIP that the block is operating on.&lt;br /&gt;
&lt;br /&gt;
Getting the stack can also be very useful&lt;br /&gt;
&lt;br /&gt;
  x/64wx ((FEXCore::Core::CPUState*)$x28)-&amp;gt;gregs[FEXCore::X86State::REG_RSP]&lt;br /&gt;
&lt;br /&gt;
Doing raw pointer math here means that this works even when gdb fails to find symbols for the CPUState object, which happens very frequently for some reason.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1450</id>
		<title>Development:Setting up RootFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1450"/>
		<updated>2025-09-22T14:11:50Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Update for FEXConfig changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Setting up a RootFS =&lt;br /&gt;
'''For AArch64 hosts you are required to have an x86-64 rootfs'''. With or without 32bit compatibility libraries.&lt;br /&gt;
&lt;br /&gt;
This isn't strictly required for testing on x86-64 host environments but is useful for ensuring correct behaviour there.&lt;br /&gt;
&lt;br /&gt;
= Quick Setup with FEXRootFSFetcher =&lt;br /&gt;
FEX comes with a FEXRootFSFetcher tool that can download an official preconfigured rootfs from the FEX servers.&lt;br /&gt;
This tool operates as either a terminal application or a Zenity application depending on if it is launched from terminal or not.&lt;br /&gt;
&lt;br /&gt;
This tool will walk you through selecting a RootFS for FEX:&lt;br /&gt;
* If your host OS matches one in the download list then it will recommend that one&lt;br /&gt;
* After selecting the RootFS, it will download it&lt;br /&gt;
** This downloads to the default location in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
* After downloading the RootFS the tool will ask if you want to use the SquashFS file directly or extract it&lt;br /&gt;
* It will then ask if you want to set the downloaded RootFS as your default&lt;br /&gt;
** This writes to the default configuration in '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
You can skip the rest of the guide if you used FEXRootFSFetcher to download the rootfs.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
* The squashfs image will fail to extract if you don't have unsquashfs installed&lt;br /&gt;
** Install the squashfs-tools package to get this application&lt;br /&gt;
&lt;br /&gt;
* '''SquashFS RootFS file corrupted?'''&lt;br /&gt;
** Rerun the tool, select the rootfs from the list, and if the rootfs already exists it will ask to verify&lt;br /&gt;
** If verification fails it will ask if you want to redownload&lt;br /&gt;
* '''Want to manually check the hash?'''&lt;br /&gt;
** Run the rootfs file directly through the tool to get a hash&lt;br /&gt;
** '''FEXRootFSFetcher $HOME/.fex-emu/RootFS/Ubuntu_21_10.sqsh'''&lt;br /&gt;
** Ubuntu_21_10.sqsh has hash: bf9507fbdbaec2cf&lt;br /&gt;
* '''Want to use the Zenity UI but still launch through terminal?'''&lt;br /&gt;
** Force Zenity from terminal with '''FEXRootFSFetcher 1&amp;gt; /dev/null'''&lt;br /&gt;
* '''What if my Linux distro isn't listed?'''&lt;br /&gt;
** Don't worry, select one that is most similar to yours or newest&lt;br /&gt;
** This will work in most cases&lt;br /&gt;
* '''How can I trust these images?'''&lt;br /&gt;
** These images are generated by scripts living in our public repo&lt;br /&gt;
** If you want to rebuild them yourself, you are free to do so.&lt;br /&gt;
** https://github.com/FEX-Emu/RootFS&lt;br /&gt;
* '''I want to add a distro'''&lt;br /&gt;
** Follow how our current rootfs is generated and add your own&lt;br /&gt;
** Open a pull request to add the rootfs setup&lt;br /&gt;
** Contact us on the official FEX-Emu Discord to get the RootFS added to the server.&lt;br /&gt;
* '''Where is the raw list of images at?'''&lt;br /&gt;
** The image links live on our website at the following link&lt;br /&gt;
** https://rootfs.fex-emu.gg/RootFS_links.json&lt;br /&gt;
** This file is in a format that our tool understands&lt;br /&gt;
** Generally the format is:&lt;br /&gt;
*** Distro Name&lt;br /&gt;
*** Distro Version&lt;br /&gt;
*** Human readable name&lt;br /&gt;
*** Raw rootfs link&lt;br /&gt;
*** xxhash based file hash&lt;br /&gt;
&lt;br /&gt;
= Making a custom rootfs prerequisites =&lt;br /&gt;
An x86-64 PC or FEX-Emu installed for chrooting&lt;br /&gt;
&lt;br /&gt;
= Getting Started =&lt;br /&gt;
The easiest way to get started is to just download a prebuilt x86-64 rootfs from your favourite distribution and extract it to where you want.&lt;br /&gt;
* Ubuntu - http://cdimage.ubuntu.com/ubuntu-base/releases/&lt;br /&gt;
* Debian Debootstrap guide - https://wiki.debian.org/Debootstrap&lt;br /&gt;
** Debootstrap is more involved and not explained here.&lt;br /&gt;
&lt;br /&gt;
Using chroot you can then enter the rootfs and install applications that you desire for testing purposes.&lt;br /&gt;
It's easiest to set this up on an x86-64 host and then copy it to an AArch64 device.&lt;br /&gt;
&lt;br /&gt;
== Cross architecture chroot ==&lt;br /&gt;
'''You need to have binfmt_misc setup for x86-64 support on your host system.'''&lt;br /&gt;
* ls /proc/sys/fs/binfmt_misc &lt;br /&gt;
** If there are files in this folder then your host supports binfmt_misc&lt;br /&gt;
* Once you have binfmt_misc running and FEX-Emu installed in to it, you can chroot in to an x86-64 rootfs&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to rootfs with FEX-Emu Rootfs ==&lt;br /&gt;
* If you're using a FEX-Emu provided rootfs then we provide two scripts at the start to handle this&lt;br /&gt;
** '''unbreak_chroot.sh''' - This sets up the rootfs and chroots inside of it&lt;br /&gt;
** '''break_chroot.sh''' - This sets up the rootfs for using with FEX generally.&lt;br /&gt;
*** '''Make sure to run this after leaving the chroot!'''&lt;br /&gt;
*** The '''unbreak_chroot.sh''' script will run this if you exit safely.&lt;br /&gt;
** The remaining steps in this guide can be skipped&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to custom rootfs with FEX-Emu ==&lt;br /&gt;
* If you're setting up your own rootfs then you need to follow the binding steps that are following.&lt;br /&gt;
** We have a script that if you know what you're doing you can cherry pick parts from [https://github.com/FEX-Emu/RootFS/blob/main/unbreak_chroot.sh here]&lt;br /&gt;
&lt;br /&gt;
= Additional TmpFS folders =&lt;br /&gt;
Depending on what you're doing in the chroot, you may need or want some tmpfs folders that applications are expecting&lt;br /&gt;
&lt;br /&gt;
* sudo mount -t proc /proc ${ROOTFS}/proc/&lt;br /&gt;
* sudo mount --rbind --make-rslave /sys ${ROOTFS}/sys/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev ${ROOTFS}/dev/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev/pts ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo mount --rbind /lib/ld-linux-aarch64.so.1 ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo mount --rbind /lib/aarch64-linux-gnu ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
Then of course, make sure to unmount these partitions when you're done&lt;br /&gt;
&lt;br /&gt;
* sudo umount ${ROOTFS}/proc/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/sys/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
= Using the RootFS with FEX =&lt;br /&gt;
&lt;br /&gt;
Run the graphical FEXConfig tool to select and change the active RootFS. Any file or folder in $HOME/.fex-emu/RootFS will be detected automatically.&lt;br /&gt;
&lt;br /&gt;
= Additional Steps for building a custom rootfs = &lt;br /&gt;
== Running under WSL1 ==&lt;br /&gt;
/etc/hosts and /etc/resolv.conf change on the host side. You'll need to copy those over to the rootfs if you want network functionality to work.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu packages to install ==&lt;br /&gt;
Sample packages to install in the rootfs&lt;br /&gt;
* apt-get install pulseaudio libgles1 libgles2 libglx-mesa0 libgl1-mesa-dri libgl1-mesa-glx mesa-utils mesa-utils-extra&lt;br /&gt;
Pulseaudio specifically is required so pulseaudio will work when talking to the host pulseaudio&lt;br /&gt;
&lt;br /&gt;
== File deletion ==&lt;br /&gt;
Some files need to be deleted from the rootfs otherwise some applications will fail to work.&lt;br /&gt;
&lt;br /&gt;
Note that deleting these files '''WILL''' break the rootfs and you won't be able to chroot in to it anymore.&lt;br /&gt;
&lt;br /&gt;
A likely better route would be a script that moves these files and folders then brings them back when you want to chroot&lt;br /&gt;
&lt;br /&gt;
=== Files to remove ===&lt;br /&gt;
* ${ROOTFS}/etc/hosts&lt;br /&gt;
* ${ROOTFS}/etc/resolv.conf&lt;br /&gt;
* ${ROOTFS}/etc/timezone&lt;br /&gt;
* ${ROOTFS}/etc/localtime&lt;br /&gt;
* ${ROOTFS}/etc/passwd&lt;br /&gt;
&lt;br /&gt;
=== Folders to remove ===&lt;br /&gt;
* ${ROOTFS}/boot&lt;br /&gt;
* ${ROOTFS}/dev&lt;br /&gt;
* ${ROOTFS}/home&lt;br /&gt;
* ${ROOTFS}/media&lt;br /&gt;
* ${ROOTFS}/mnt&lt;br /&gt;
* ${ROOTFS}/proc&lt;br /&gt;
* ${ROOTFS}/root&lt;br /&gt;
* ${ROOTFS}/srv&lt;br /&gt;
* ${ROOTFS}/tmp&lt;br /&gt;
* ${ROOTFS}/var/cache/apt&lt;br /&gt;
* ${ROOTFS}/var/lib/apt&lt;br /&gt;
* ${ROOTFS}/sys&lt;br /&gt;
* ${ROOTFS}/opt&lt;br /&gt;
&lt;br /&gt;
== Creating a Squashfs rootfs from custom rootfs ==&lt;br /&gt;
SquashFS is a great way to do binary distribution of the rootfs. If you have created a rootfs and you want to roll it in to a squashfs like the FEX-Emu provided images then this is information on how to do that.&lt;br /&gt;
&lt;br /&gt;
'''SquashFS is currently only recommended for binary distribution. User should unpack it to not get dangling processes and mounts.'''&lt;br /&gt;
* Offers tooling to mount in userspace&lt;br /&gt;
* Supports ZSTD compression&lt;br /&gt;
* Is a readonly partition that matches FEX's use case&lt;br /&gt;
&lt;br /&gt;
=== Tools that FEX needs to run squashfs ===&lt;br /&gt;
* squashfuse&lt;br /&gt;
* fusermount&lt;br /&gt;
&lt;br /&gt;
=== Making the squashfs image ===&lt;br /&gt;
Making the squashfs image is very straightforward&lt;br /&gt;
* mksquashfs ${ROOTFS}/ Squashfs.sqsh -comp zstd&lt;br /&gt;
&lt;br /&gt;
This creates a file called Squashfs.sqsh that contains the original rootfs that we generated above.&lt;br /&gt;
&lt;br /&gt;
=== Using the squashfs image in FEX ===&lt;br /&gt;
* Copy the resulting sqsh file in to ${XDG_DATA_HOME}/.fex-emu/RootFS/&lt;br /&gt;
** If ${XDG_DATA_HOME} doesn't exist then that will be replaced with ${HOME}&lt;br /&gt;
* Use FEXConfig to select the sqsh file as a named rootfs&lt;br /&gt;
* or pass the name in to the FEX_ROOTFS argument in the various ways FEX supports&lt;br /&gt;
* or the absolute path if you don't want it in the FEX RootFS folder&lt;br /&gt;
&lt;br /&gt;
=== Extracting the squashfs ===&lt;br /&gt;
If you don't want to use squashfs for whatever reason then you can extract it in to the FEX RootFS folder and use the directory directly&lt;br /&gt;
* unsquashfs -f -d NewRootFS/ Squashfs.sqsh&lt;br /&gt;
&lt;br /&gt;
=== If you want to install packages in the squashfs ===&lt;br /&gt;
The squashfs image is immutable and can't be modified.&lt;br /&gt;
* Extract the squashfs first&lt;br /&gt;
* Change the working directory to the rootfs&lt;br /&gt;
* execute `unbreak_chroot.sh`&lt;br /&gt;
* `apt-get update`&lt;br /&gt;
* `apt-get install &amp;lt;Whatever you want&amp;gt;`&lt;br /&gt;
* `exit` to leave the chroot&lt;br /&gt;
* Use the new extracted chroot directly, or follow the previous steps to recompress it to a squashfs format.&lt;br /&gt;
&lt;br /&gt;
=== Known problems with squashfs ===&lt;br /&gt;
'''FEX automatically mounts your squashfs file and can leave dangling squashfs mounts around in some instances.'''&lt;br /&gt;
* '''This is fairly rare but it can occur. Whenever an instance of FEX is run, it registers with the FEXMountDaemon'''&lt;br /&gt;
** FEXMountDaemon then watches these instances of FEX to ensure they have exited before unmounting&lt;br /&gt;
** There is roughly a ten second grace period of no instances of FEX running before unmounting&lt;br /&gt;
** If an instance of FEX starts running then it will reuse the mount partition and reset the timeout&lt;br /&gt;
* To get rid of these dangling mounts if they do manage to manifest, use the following commands&lt;br /&gt;
** fusermount -u /tmp/.FEXMount* ; rmdir /tmp/.FEXMount*&lt;br /&gt;
** These don't require root to unmount&lt;br /&gt;
* In some cases the unmounting can end up returning busy status and not unmount&lt;br /&gt;
** Check the output of `mount` for any /tmp/.FEXMount folders&lt;br /&gt;
** This is due to either FEXMountDaemon or squashfuse still running in the background&lt;br /&gt;
** Can force the application to exit&lt;br /&gt;
** step 1: kill `pidof squashfuse`&lt;br /&gt;
** This will attempt to send SIGTERM to all squashfuse applications, which will unmount the partition on terminate&lt;br /&gt;
** Failing that, you can try to be more abusive&lt;br /&gt;
** kill -9 `pidof FEXMountDaemon`&lt;br /&gt;
** This will forcibly terminate FEXMountDaemon which should also take out the child mounted process&lt;br /&gt;
* If any instances of the mount still exists then you may need to kill more FEX processes.&lt;br /&gt;
** Any ''FEX'' process will end up keeping the folder mounted and keep it busy&lt;br /&gt;
&lt;br /&gt;
'''strace breaks squashfs'''&lt;br /&gt;
* If you run FEX with `strace -f` then the process that mounts your rootfs loses its setuid bit.&lt;br /&gt;
** This means you then can't mount the rootFS&lt;br /&gt;
* The only workaround is to not use a squashfs in this instance.&lt;br /&gt;
* Alternatively you can spin up a FEXBash instance to force squashfs to be mounted. Then strace a different FEX instance which will use the mounted squashfs location.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1449</id>
		<title>Development:Setting up RootFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=1449"/>
		<updated>2025-09-22T14:02:51Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Setting up a RootFS =&lt;br /&gt;
'''For AArch64 hosts you are required to have an x86-64 rootfs'''. With or without 32bit compatibility libraries.&lt;br /&gt;
&lt;br /&gt;
This isn't strictly required for testing on x86-64 host environments but is useful for ensuring correct behaviour there.&lt;br /&gt;
&lt;br /&gt;
= Quick Setup with FEXRootFSFetcher =&lt;br /&gt;
FEX comes with a FEXRootFSFetcher tool that can download an official preconfigured rootfs from the FEX servers.&lt;br /&gt;
This tool operates as either a terminal application or a Zenity application depending on if it is launched from terminal or not.&lt;br /&gt;
&lt;br /&gt;
This tool will walk you through selecting a RootFS for FEX:&lt;br /&gt;
* If your host OS matches one in the download list then it will recommend that one&lt;br /&gt;
* After selecting the RootFS, it will download it&lt;br /&gt;
** This downloads to the default location in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
* After downloading the RootFS the tool will ask if you want to use the SquashFS file directly or extract it&lt;br /&gt;
* It will then ask if you want to set the downloaded RootFS as your default&lt;br /&gt;
** This writes to the default configuration in '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
You can skip the rest of the guide if you used FEXRootFSFetcher to download the rootfs.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
* The squashfs image will fail to extract if you don't have unsquashfs installed&lt;br /&gt;
** Install the squashfs-tools package to get this application&lt;br /&gt;
&lt;br /&gt;
* '''SquashFS RootFS file corrupted?'''&lt;br /&gt;
** Rerun the tool, select the rootfs from the list, and if the rootfs already exists it will ask to verify&lt;br /&gt;
** If verification fails it will ask if you want to redownload&lt;br /&gt;
* '''Want to manually check the hash?'''&lt;br /&gt;
** Run the rootfs file directly through the tool to get a hash&lt;br /&gt;
** '''FEXRootFSFetcher $HOME/.fex-emu/RootFS/Ubuntu_21_10.sqsh'''&lt;br /&gt;
** Ubuntu_21_10.sqsh has hash: bf9507fbdbaec2cf&lt;br /&gt;
* '''Want to use the Zenity UI but still launch through terminal?'''&lt;br /&gt;
** Force Zenity from terminal with '''FEXRootFSFetcher 1&amp;gt; /dev/null'''&lt;br /&gt;
* '''What if my Linux distro isn't listed?'''&lt;br /&gt;
** Don't worry, select one that is most similar to yours or newest&lt;br /&gt;
** This will work in most cases&lt;br /&gt;
* '''How can I trust these images?'''&lt;br /&gt;
** These images are generated by scripts living in our public repo&lt;br /&gt;
** If you want to rebuild them yourself, you are free to do so.&lt;br /&gt;
** https://github.com/FEX-Emu/RootFS&lt;br /&gt;
* '''I want to add a distro'''&lt;br /&gt;
** Follow how our current rootfs is generated and add your own&lt;br /&gt;
** Open a pull request to add the rootfs setup&lt;br /&gt;
** Contact us on the official FEX-Emu Discord to get the RootFS added to the server.&lt;br /&gt;
* '''Where is the raw list of images at?'''&lt;br /&gt;
** The image links live on our website at the following link&lt;br /&gt;
** https://rootfs.fex-emu.gg/RootFS_links.json&lt;br /&gt;
** This file is in a format that our tool understands&lt;br /&gt;
** Generally the format is:&lt;br /&gt;
*** Distro Name&lt;br /&gt;
*** Distro Version&lt;br /&gt;
*** Human readable name&lt;br /&gt;
*** Raw rootfs link&lt;br /&gt;
*** xxhash based file hash&lt;br /&gt;
&lt;br /&gt;
= Making a custom rootfs prerequisites =&lt;br /&gt;
An x86-64 PC or FEX-Emu installed for chrooting&lt;br /&gt;
&lt;br /&gt;
= Getting Started =&lt;br /&gt;
The easiest way to get started is to just download a prebuilt x86-64 rootfs from your favourite distribution and extract it to where you want.&lt;br /&gt;
* Ubuntu - http://cdimage.ubuntu.com/ubuntu-base/releases/&lt;br /&gt;
* Debian Debootstrap guide - https://wiki.debian.org/Debootstrap&lt;br /&gt;
** Debootstrap is more involved and not explained here.&lt;br /&gt;
&lt;br /&gt;
Using chroot you can then enter the rootfs and install applications that you desire for testing purposes.&lt;br /&gt;
It's easiest to set this up on an x86-64 host and then copy it to an AArch64 device.&lt;br /&gt;
&lt;br /&gt;
== Cross architecture chroot ==&lt;br /&gt;
'''You need to have binfmt_misc setup for x86-64 support on your host system.'''&lt;br /&gt;
* ls /proc/sys/fs/binfmt_misc &lt;br /&gt;
** If there are files in this folder then your host supports binfmt_misc&lt;br /&gt;
* Once you have binfmt_misc running and FEX-Emu installed in to it, you can chroot in to an x86-64 rootfs&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to rootfs with FEX-Emu Rootfs ==&lt;br /&gt;
* If you're using a FEX-Emu provided rootfs then we provide two scripts at the start to handle this&lt;br /&gt;
** '''unbreak_chroot.sh''' - This sets up the rootfs and chroots inside of it&lt;br /&gt;
** '''break_chroot.sh''' - This sets up the rootfs for using with FEX generally.&lt;br /&gt;
*** '''Make sure to run this after leaving the chroot!'''&lt;br /&gt;
*** The '''unbreak_chroot.sh''' script will run this if you exit safely.&lt;br /&gt;
** The remaining steps in this guide can be skipped&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to custom rootfs with FEX-Emu ==&lt;br /&gt;
* If you're setting up your own rootfs then you need to follow the binding steps that are following.&lt;br /&gt;
** We have a script that if you know what you're doing you can cherry pick parts from [https://github.com/FEX-Emu/RootFS/blob/main/unbreak_chroot.sh here]&lt;br /&gt;
&lt;br /&gt;
= Additional TmpFS folders =&lt;br /&gt;
Depending on what you're doing in the chroot, you may need or want some tmpfs folders that applications are expecting&lt;br /&gt;
&lt;br /&gt;
* sudo mount -t proc /proc ${ROOTFS}/proc/&lt;br /&gt;
* sudo mount --rbind --make-rslave /sys ${ROOTFS}/sys/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev ${ROOTFS}/dev/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev/pts ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo mount --rbind /lib/ld-linux-aarch64.so.1 ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo mount --rbind /lib/aarch64-linux-gnu ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
Then of course, make sure to unmount these partitions when you're done&lt;br /&gt;
&lt;br /&gt;
* sudo umount ${ROOTFS}/proc/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/sys/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
= Using the rootfs with FEX =&lt;br /&gt;
If you're using FEXLoader then you can pass the full path of the rootfs with the -R option.&lt;br /&gt;
Additionally you can put the rootfs folder inside of $HOME/.fex-emu/RootFS/&amp;lt;RootFS name&amp;gt;/ and FEX supports a &amp;quot;named&amp;quot; rootfs option&lt;br /&gt;
* eq: -R Ubuntu_2104 will use rootfs $HOME/.fex-emu/RootfS/Ubuntu_2104&lt;br /&gt;
* Read the Fex man page with man fex for more information&lt;br /&gt;
&lt;br /&gt;
== Setting RootFS with FEXConfig ==&lt;br /&gt;
[[File:FEXConfig Load Default.png|frameless|Load the default options on first run]]&lt;br /&gt;
On the first run of FEXConfig, select the &amp;quot;Load Default Options&amp;quot; configuration.&lt;br /&gt;
* Subsequent runs should select &amp;quot;Open Default&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[File:FEXConfig RootFS Selection.png|frameless|Select the RootFS from the FEXConfig location]]&lt;br /&gt;
&lt;br /&gt;
FEXConfig will autopopulate the rootfs list with rootfs folders that exist in $HOME/.fex-emu/RootFS/&lt;br /&gt;
&lt;br /&gt;
You can select one from the list or provide a full path in the RootFS: line to set it manually.&lt;br /&gt;
&lt;br /&gt;
''' Make sure to select the File-&amp;gt;Save option after the fact to save'''&lt;br /&gt;
&lt;br /&gt;
= Additional Steps for building a custom rootfs = &lt;br /&gt;
== Running under WSL1 ==&lt;br /&gt;
/etc/hosts and /etc/resolv.conf change on the host side. You'll need to copy those over to the rootfs if you want network functionality to work.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu packages to install ==&lt;br /&gt;
Sample packages to install in the rootfs&lt;br /&gt;
* apt-get install pulseaudio libgles1 libgles2 libglx-mesa0 libgl1-mesa-dri libgl1-mesa-glx mesa-utils mesa-utils-extra&lt;br /&gt;
Pulseaudio specifically is required so pulseaudio will work when talking to the host pulseaudio&lt;br /&gt;
&lt;br /&gt;
== File deletion ==&lt;br /&gt;
Some files need to be deleted from the rootfs otherwise some applications will fail to work.&lt;br /&gt;
&lt;br /&gt;
Note that deleting these files '''WILL''' break the rootfs and you won't be able to chroot in to it anymore.&lt;br /&gt;
&lt;br /&gt;
A likely better route would be a script that moves these files and folders then brings them back when you want to chroot&lt;br /&gt;
&lt;br /&gt;
=== Files to remove ===&lt;br /&gt;
* ${ROOTFS}/etc/hosts&lt;br /&gt;
* ${ROOTFS}/etc/resolv.conf&lt;br /&gt;
* ${ROOTFS}/etc/timezone&lt;br /&gt;
* ${ROOTFS}/etc/localtime&lt;br /&gt;
* ${ROOTFS}/etc/passwd&lt;br /&gt;
&lt;br /&gt;
=== Folders to remove ===&lt;br /&gt;
* ${ROOTFS}/boot&lt;br /&gt;
* ${ROOTFS}/dev&lt;br /&gt;
* ${ROOTFS}/home&lt;br /&gt;
* ${ROOTFS}/media&lt;br /&gt;
* ${ROOTFS}/mnt&lt;br /&gt;
* ${ROOTFS}/proc&lt;br /&gt;
* ${ROOTFS}/root&lt;br /&gt;
* ${ROOTFS}/srv&lt;br /&gt;
* ${ROOTFS}/tmp&lt;br /&gt;
* ${ROOTFS}/var/cache/apt&lt;br /&gt;
* ${ROOTFS}/var/lib/apt&lt;br /&gt;
* ${ROOTFS}/sys&lt;br /&gt;
* ${ROOTFS}/opt&lt;br /&gt;
&lt;br /&gt;
== Creating a Squashfs rootfs from custom rootfs ==&lt;br /&gt;
SquashFS is a great way to do binary distribution of the rootfs. If you have created a rootfs and you want to roll it in to a squashfs like the FEX-Emu provided images then this is information on how to do that.&lt;br /&gt;
&lt;br /&gt;
'''SquashFS is currently only recommended for binary distribution. User should unpack it to not get dangling processes and mounts.'''&lt;br /&gt;
* Offers tooling to mount in userspace&lt;br /&gt;
* Supports ZSTD compression&lt;br /&gt;
* Is a readonly partition that matches FEX's use case&lt;br /&gt;
&lt;br /&gt;
=== Tools that FEX needs to run squashfs ===&lt;br /&gt;
* squashfuse&lt;br /&gt;
* fusermount&lt;br /&gt;
&lt;br /&gt;
=== Making the squashfs image ===&lt;br /&gt;
Making the squashfs image is very straightforward&lt;br /&gt;
* mksquashfs ${ROOTFS}/ Squashfs.sqsh -comp zstd&lt;br /&gt;
&lt;br /&gt;
This creates a file called Squashfs.sqsh that contains the original rootfs that we generated above.&lt;br /&gt;
&lt;br /&gt;
=== Using the squashfs image in FEX ===&lt;br /&gt;
* Copy the resulting sqsh file in to ${XDG_DATA_HOME}/.fex-emu/RootFS/&lt;br /&gt;
** If ${XDG_DATA_HOME} doesn't exist then that will be replaced with ${HOME}&lt;br /&gt;
* Use FEXConfig to select the sqsh file as a named rootfs&lt;br /&gt;
* or pass the name in to the FEX_ROOTFS argument in the various ways FEX supports&lt;br /&gt;
* or the absolute path if you don't want it in the FEX RootFS folder&lt;br /&gt;
&lt;br /&gt;
=== Extracting the squashfs ===&lt;br /&gt;
If you don't want to use squashfs for whatever reason then you can extract it in to the FEX RootFS folder and use the directory directly&lt;br /&gt;
* unsquashfs -f -d NewRootFS/ Squashfs.sqsh&lt;br /&gt;
&lt;br /&gt;
=== If you want to install packages in the squashfs ===&lt;br /&gt;
The squashfs image is immutable and can't be modified.&lt;br /&gt;
* Extract the squashfs first&lt;br /&gt;
* Change the working directory to the rootfs&lt;br /&gt;
* execute `unbreak_chroot.sh`&lt;br /&gt;
* `apt-get update`&lt;br /&gt;
* `apt-get install &amp;lt;Whatever you want&amp;gt;`&lt;br /&gt;
* `exit` to leave the chroot&lt;br /&gt;
* Use the new extracted chroot directly, or follow the previous steps to recompress it to a squashfs format.&lt;br /&gt;
&lt;br /&gt;
=== Known problems with squashfs ===&lt;br /&gt;
'''FEX automatically mounts your squashfs file and can leave dangling squashfs mounts around in some instances.'''&lt;br /&gt;
* '''This is fairly rare but it can occur. Whenever an instance of FEX is run, it registers with the FEXMountDaemon'''&lt;br /&gt;
** FEXMountDaemon then watches these instances of FEX to ensure they have exited before unmounting&lt;br /&gt;
** There is roughly a ten second grace period of no instances of FEX running before unmounting&lt;br /&gt;
** If an instance of FEX starts running then it will reuse the mount partition and reset the timeout&lt;br /&gt;
* To get rid of these dangling mounts if they do manage to manifest, use the following commands&lt;br /&gt;
** fusermount -u /tmp/.FEXMount* ; rmdir /tmp/.FEXMount*&lt;br /&gt;
** These don't require root to unmount&lt;br /&gt;
* In some cases the unmounting can end up returning busy status and not unmount&lt;br /&gt;
** Check the output of `mount` for any /tmp/.FEXMount folders&lt;br /&gt;
** This is due to either FEXMountDaemon or squashfuse still running in the background&lt;br /&gt;
** Can force the application to exit&lt;br /&gt;
** step 1: kill `pidof squashfuse`&lt;br /&gt;
** This will attempt to send SIGTERM to all squashfuse applications, which will unmount the partition on terminate&lt;br /&gt;
** Failing that, you can try to be more abusive&lt;br /&gt;
** kill -9 `pidof FEXMountDaemon`&lt;br /&gt;
** This will forcibly terminate FEXMountDaemon which should also take out the child mounted process&lt;br /&gt;
* If any instances of the mount still exists then you may need to kill more FEX processes.&lt;br /&gt;
** Any ''FEX'' process will end up keeping the folder mounted and keep it busy&lt;br /&gt;
&lt;br /&gt;
'''strace breaks squashfs'''&lt;br /&gt;
* If you run FEX with `strace -f` then the process that mounts your rootfs loses its setuid bit.&lt;br /&gt;
** This means you then can't mount the rootFS&lt;br /&gt;
* The only workaround is to not use a squashfs in this instance.&lt;br /&gt;
* Alternatively you can spin up a FEXBash instance to force squashfs to be mounted. Then strace a different FEX instance which will use the mounted squashfs location.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Config&amp;diff=1448</id>
		<title>Config</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Config&amp;diff=1448"/>
		<updated>2025-09-22T14:02:30Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXLoader was removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FEX-Emu has a relatively complex configuration system. This is due to the fact that it is an overlay based configuration system and also it is technically two configuration systems in one.&lt;br /&gt;
== Main application configuration ==&lt;br /&gt;
This is the primary configuration that is the bulk of the implementation. This falls under the &amp;quot;Config&amp;quot; section of the json configuration files.&lt;br /&gt;
&lt;br /&gt;
=== Overlay system ===&lt;br /&gt;
This configuration system is based on layers that either override or merge with the layer under it.&lt;br /&gt;
&lt;br /&gt;
=== Loadable layers ===&lt;br /&gt;
From highest priority to lowest priority. Higher priority layers can override options in lower-priority layers.&lt;br /&gt;
&lt;br /&gt;
* Meta layer (Top most)&lt;br /&gt;
** This layer is the final merging of all the layers under it. &lt;br /&gt;
* Environment variables&lt;br /&gt;
** This layer loads options from the environment variable prefixed with FEX_&lt;br /&gt;
* User-writable app config&lt;br /&gt;
* User-writable steam app id&lt;br /&gt;
* Global installed app config&lt;br /&gt;
* Global installed Steam App config&lt;br /&gt;
* User-writable main config&lt;br /&gt;
* Global main config&lt;br /&gt;
&lt;br /&gt;
=== Environment variables ===&lt;br /&gt;
These come from environment variables prefixed with '''FEX_'''. Check the man page for FEX to know what environment variables correspond to which options.&lt;br /&gt;
&lt;br /&gt;
=== User-writable app config ===&lt;br /&gt;
Just like the global app config file, this takes the form of '''&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
This can be loaded from multiple paths highest priority to lowest priority&lt;br /&gt;
&lt;br /&gt;
* '''$FEX_APP_CONFIG'''&lt;br /&gt;
** Usually not set. Direct JSON filepath&lt;br /&gt;
* '''$XDG_CONFIG_HOME/.fex-emu/AppConfig/&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** Depends on environment, not always set on all distributions&lt;br /&gt;
* '''$FEX_APP_CONFIG_LOCATION/AppConfig/&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** Usually not set&lt;br /&gt;
* '''$HOME/.fex-emu/AppConfig/&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** The regular config location&lt;br /&gt;
&lt;br /&gt;
=== User-writable steam app id ===&lt;br /&gt;
Just like the global steam app config file, this takes the form of '''Steam_$SteamAppId_&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
This can be loaded from multiple paths highest priority to lowest priority&lt;br /&gt;
&lt;br /&gt;
* '''$XDG_CONFIG_HOME/.fex-emu/AppConfig/Steam_$SteamAppId_&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** Depends on environment, not always set on all distributions&lt;br /&gt;
* '''$FEX_APP_CONFIG_LOCATION/AppConfig/Steam_$SteamAppId_&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** Usually not set&lt;br /&gt;
* '''$HOME/.fex-emu/AppConfig/Steam_$SteamAppId_&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
** The regular config location&lt;br /&gt;
&lt;br /&gt;
=== Global installed app config ===&lt;br /&gt;
This file is loaded from '''/usr/share/fex-emu/AppConfig/&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
* Usually doesn't exist&lt;br /&gt;
* FEX-Emu ships a handful of these&lt;br /&gt;
&lt;br /&gt;
=== Global steam app config ===&lt;br /&gt;
This file is loaded from '''/usr/share/fex-emu/AppConfig/Steam_$SteamAppId_&amp;lt;AppName&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
* Usually doesn't exist&lt;br /&gt;
&lt;br /&gt;
=== User-writable main config ===&lt;br /&gt;
This can come from a couple locations. From highest priority to lowest.&lt;br /&gt;
&lt;br /&gt;
Will not fallback to loading later configs in the list if one fails.&lt;br /&gt;
&lt;br /&gt;
* '''$XDG_CONFIG_HOME/.fex-emu/Config.json'''&lt;br /&gt;
** Depends on environment, not always set on all distributions&lt;br /&gt;
* '''$FEX_APP_CONFIG_LOCATION/Config.json'''&lt;br /&gt;
** Usually not set&lt;br /&gt;
* '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
** The regular config location&lt;br /&gt;
&lt;br /&gt;
=== Global main config ===&lt;br /&gt;
This file is loaded from '''/usr/share/fex-emu/Config.json'''&lt;br /&gt;
* Usually doesn't exist&lt;br /&gt;
&lt;br /&gt;
== Thunks configuration system ==&lt;br /&gt;
This system is disjoint from the other configuration system, but overlaps slightly as we will see. This system loads the '''ThunksDB''' section of the json configuration files.&lt;br /&gt;
&lt;br /&gt;
This system is disjoint from the other configuration system because it only affects thunking configuration options.&lt;br /&gt;
&lt;br /&gt;
=== Loadable Layers ===&lt;br /&gt;
The layers from highest priority to lowest priority. Higher priority layers can enable or disable options from the lower priority layers.&lt;br /&gt;
* User-writable app config&lt;br /&gt;
* User-writable steam app config&lt;br /&gt;
* Global installed app config&lt;br /&gt;
* Global installed Steam App config&lt;br /&gt;
* FEX ThunkConfig option path&lt;br /&gt;
* User-writable main config&lt;br /&gt;
* Global main config&lt;br /&gt;
&lt;br /&gt;
=== User-writable installed app config ===&lt;br /&gt;
* Exactly the same as the above user-writable installed app config&lt;br /&gt;
&lt;br /&gt;
=== User-writable steam app config ===&lt;br /&gt;
* Exactly the same as the above user-writable installed steam app config&lt;br /&gt;
&lt;br /&gt;
=== Global installed app config ===&lt;br /&gt;
* Exactly the same as the above global installed app config&lt;br /&gt;
&lt;br /&gt;
=== Global installed Steam App config ===&lt;br /&gt;
* Exactly the same as the above global installed steam app config&lt;br /&gt;
&lt;br /&gt;
=== FEX ThunkConfig Option path ===&lt;br /&gt;
'''ThunkConfig''' is an option in FEX's '''Config''' section. If this filepath exists then it is loaded.&lt;br /&gt;
* This means it can be overridden with '''FEX_THUNKCONFIG''' environment variable, which is handy.&lt;br /&gt;
&lt;br /&gt;
=== User-writable main config ===&lt;br /&gt;
* Exactly the same as the above user-writable main config&lt;br /&gt;
&lt;br /&gt;
=== Global main config ===&lt;br /&gt;
* Exactly the same as the above Global main config&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1447</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1447"/>
		<updated>2025-09-22T14:01:48Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTING=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEX&lt;br /&gt;
** This is the emulator executable used to run x86 programs&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a (deprecated) alias for ''FEX'', provided for backwards compatibility&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for configuring emulation from a Qt-based GUI&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when FEX exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=FEXBash&amp;diff=1446</id>
		<title>FEXBash</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=FEXBash&amp;diff=1446"/>
		<updated>2025-09-22T14:01:24Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Utility_Type_Application]]&lt;br /&gt;
FEXBash is a utility program provided by FEX-emu for quickly spinning up a bash instance.&lt;br /&gt;
== What isn't FEXBash ==&lt;br /&gt;
FEXBash is '''not''':&lt;br /&gt;
* A virtual machine&lt;br /&gt;
** FEX is never a virtual machine.&lt;br /&gt;
* A chroot&lt;br /&gt;
** See [[Development:Setting_up_RootFS#Chrooting_in_to_rootfs_with_FEX-Emu_Rootfs|this wiki page]] if you want to chroot in to the rootfs.&lt;br /&gt;
* A way to install packages inside the x86-64 rootfs&lt;br /&gt;
** See [[Development:Setting_up_RootFS#If_you_want_to_install_packages_in_the_squashfs|this wiki page]] if you want to add packages to the rootfs.&lt;br /&gt;
** Trying to install packages while running under FEXBash will not work. The rootfs is effectively read-only.&lt;br /&gt;
&lt;br /&gt;
== What is FEXBash ==&lt;br /&gt;
FEXBash is a wrapper program that executes ''FEX'' to run x86-64 '''/bin/sh''' or '''/bin/bash'''. Which application is executed depends on the number of arguments passed in&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
=== Zero arguments ===&lt;br /&gt;
If the user passes in no arguments then FEXBash will execute x86-64 '''/bin/bash''' to give an emulated shell environment for tinkering around in.&lt;br /&gt;
  ryanh@ubuntu:~$ uname -a&lt;br /&gt;
  Linux ubuntu 5.15.0-rc1+ #106 SMP Tue Aug 2 19:43:23 PDT 2022 aarch64 aarch64 aarch64 GNU/Linux&lt;br /&gt;
  ryanh@ubuntu:~$ FEXBash&lt;br /&gt;
  FEXBash-ryanh@ubuntu:~&amp;gt; uname -a&lt;br /&gt;
  Linux ubuntu 5.15.0 #FEX-2208-11-ga2f4f494a SMP Aug 13 2022 09:47:20 x86_64 x86_64 x86_64 GNU/Linux&lt;br /&gt;
&lt;br /&gt;
This is not a virtual machine. It is just an emulated environment that overlays the AArch64 host environment. You can still execute AArch64 programs from the host and also x86-64 programs.&lt;br /&gt;
&lt;br /&gt;
=== Any arguments ===&lt;br /&gt;
If any arguments are passed in then FEXBash executes '''/bin/sh -c''' with the provided arguments passed along. One must be careful with this as '''sh -c''' is usually expected to have its arguments wrapped in double quotes.&lt;br /&gt;
  ryanh@ubuntu:~$ sh -c uname -a&lt;br /&gt;
  Linux&lt;br /&gt;
  ryanh@ubuntu:~$ sh -c &amp;quot;uname -a&amp;quot;&lt;br /&gt;
  Linux ubuntu 5.15.0-rc1+ #106 SMP Tue Aug 2 19:43:23 PDT 2022 aarch64 aarch64 aarch64 GNU/Linux&lt;br /&gt;
  ryanh@ubuntu:~$ FEXBash uname -a&lt;br /&gt;
  Linux&lt;br /&gt;
  ryanh@ubuntu:~$ FEXBash &amp;quot;uname -a&amp;quot;&lt;br /&gt;
  Linux ubuntu 5.15.0 #FEX-2208-11-ga2f4f494a SMP Aug 13 2022 09:47:20 x86_64 x86_64 x86_64 GNU/Linux&lt;br /&gt;
As one can see, without the double quotes you effectively lose the '''-a''' argument. This behaves the same as '''/bin/sh -c''' behaviour without FEXBash.&lt;br /&gt;
&lt;br /&gt;
This is usually used for some sort of scripting wanting to enter the FEX emulated environment.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=1445</id>
		<title>Development:Debugging Crash</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=1445"/>
		<updated>2025-09-22T14:00:56Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Getting Started ==&lt;br /&gt;
* Debug an application with `gdb --args FEX &amp;lt;application full path&amp;gt;`&lt;br /&gt;
* Under GDB make sure to do `handle SIGBUS SIGILL SIG63 noprint`&lt;br /&gt;
** We use signals for various things, check out [[Development:Debugging_FEX_with_Signals|Here]] for more information&lt;br /&gt;
&lt;br /&gt;
== Crash in emulated/JIT code ==&lt;br /&gt;
Walking through debugging a simple test application that is crashing.&lt;br /&gt;
  $ gdb --args FEX ./sigsegv_test&lt;br /&gt;
  Reading symbols from FEX...&lt;br /&gt;
  (gdb) r&lt;br /&gt;
  Starting program: /usr/bin/FEX ./sigsegv_test&lt;br /&gt;
  [Thread debugging using libthread_db enabled]&lt;br /&gt;
  Using host libthread_db library &amp;quot;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;quot;.&lt;br /&gt;
  [New Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  &lt;br /&gt;
  Thread 2 &amp;quot;FEX received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  [Switching to Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  0x0000007fccfb9ec8 in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay, we have a sigsegv. Let's double check that it is JIT code (aka, guest emulated code)&lt;br /&gt;
  (gdb) disas $pc,+32&lt;br /&gt;
  Dump of assembler code from 0x7fe26ebc20 to 0x7fe26ebc40:&lt;br /&gt;
  =&amp;gt; 0x0000007fe26ebc20:  stlrb   w22, [x21]&lt;br /&gt;
     0x0000007fe26ebc24:  mov     x4, #0x0                        // #0&lt;br /&gt;
     0x0000007fe26ebc28:  ldr     x10, [x20]&lt;br /&gt;
     0x0000007fe26ebc2c:  add     x21, x20, #0x8&lt;br /&gt;
     0x0000007fe26ebc30:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc34:  strb    w22, [x28, #428]&lt;br /&gt;
     0x0000007fe26ebc38:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc3c:  strb    w22, [x28, #431]&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb) info reg x9&lt;br /&gt;
  x9             0x0                 0&lt;br /&gt;
* Looks like JIT code, even doing accesses to x28 which is the FEX CPU state&lt;br /&gt;
* Code has no backtrace which reinforces this&lt;br /&gt;
* Code is doing an atomic store, which reinforces this is FEX emulating the x86 TSO memory model&lt;br /&gt;
&lt;br /&gt;
* Now that we have checked that we are in the JIT code. Where are we in the guest side?&lt;br /&gt;
* Let's dump the FEX CPU state information that is directly pointed to in x28 at all times in JIT code.&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State&lt;br /&gt;
  $3 = {rip = 0x401110, gregs = {0x416eb0, 0x7fe1e3b640, 0xffffffffffffff70, 0x0, 0x7fe1e3bf30, 0x0, 0x416eb0, 0x7fe1e3ae28, 0x0, 0x7fe1e3b640, 0x8, 0x7fe2054cc0, 0x7ff75ff48e, 0x7ff75ff48f, 0x0, 0x7fe163b000}, xmm = {{0x0, 0x0}, {0x0, 0x0}, {0xdeadbeef, 0xbad0dad1} &amp;lt;repeats 14 times&amp;gt;}, es = 0x0, cs = 0x0, ss = 0x0, ds = 0x0, gs = 0x0, fs = 0x7fe1e3b640, flags = {0x0, 0x1, 0x0,&lt;br /&gt;
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 &amp;lt;repeats 38 times&amp;gt;}, mm = {{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}}, gdt = {{base = 0x0} &amp;lt;repeats 32 times&amp;gt;}, FCW = 0x37f, FTW = 0xffff}&lt;br /&gt;
&lt;br /&gt;
* Looks like our guest RIP is currently `0x401110`&lt;br /&gt;
** Consult the `info proc mappings` again&lt;br /&gt;
  0x401000           0x402000     0x1000     0x1000 {...}/sigsegv_test&lt;br /&gt;
* Yep, we are inside our test application&lt;br /&gt;
* For a simple test, let's load the application in gdb-multiarch and disassemble where we are&lt;br /&gt;
  $ gdb-multiarch ./sigsegv_test&lt;br /&gt;
  Reading symbols from ./sigsegv_test...&lt;br /&gt;
  (gdb) set disassembly-flavor intel&lt;br /&gt;
  (gdb) disas 0x401110&lt;br /&gt;
  Dump of assembler code for function main(int, char**):&lt;br /&gt;
     0x0000000000401110 &amp;lt;+0&amp;gt;:     push   rbp&lt;br /&gt;
     0x0000000000401111 &amp;lt;+1&amp;gt;:     mov    rbp,rsp&lt;br /&gt;
     0x0000000000401114 &amp;lt;+4&amp;gt;:     mov    DWORD PTR [rbp-0x4],0x0&lt;br /&gt;
     0x000000000040111b &amp;lt;+11&amp;gt;:    mov    DWORD PTR [rbp-0x8],edi&lt;br /&gt;
     0x000000000040111e &amp;lt;+14&amp;gt;:    mov    QWORD PTR [rbp-0x10],rsi&lt;br /&gt;
     0x0000000000401122 &amp;lt;+18&amp;gt;:    mov    rax,QWORD PTR [rbp-0x10]&lt;br /&gt;
     0x0000000000401126 &amp;lt;+22&amp;gt;:    movsxd rcx,DWORD PTR [rbp-0x8]&lt;br /&gt;
     0x000000000040112a &amp;lt;+26&amp;gt;:    mov    rax,QWORD PTR [rax+rcx*8]&lt;br /&gt;
     0x000000000040112e &amp;lt;+30&amp;gt;:    mov    QWORD PTR [rbp-0x18],rax&lt;br /&gt;
     0x0000000000401132 &amp;lt;+34&amp;gt;:    mov    rax,QWORD PTR [rbp-0x18]&lt;br /&gt;
     0x0000000000401136 &amp;lt;+38&amp;gt;:    mov    BYTE PTR [rax],0x63&lt;br /&gt;
     0x0000000000401139 &amp;lt;+41&amp;gt;:    xor    eax,eax&lt;br /&gt;
     0x000000000040113b &amp;lt;+43&amp;gt;:    pop    rbp&lt;br /&gt;
     0x000000000040113c &amp;lt;+44&amp;gt;:    ret&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb)&lt;br /&gt;
&lt;br /&gt;
* Okay, not super helpful since FEX translates instructions in to blocks, `0x401110` is just our starting address&lt;br /&gt;
** It's in this code somewhere, let's change some FEX settings to get a clearer picture&lt;br /&gt;
* Set block size to one instruction and disable multiblock&lt;br /&gt;
** See the image in FEXConfig to the right&lt;br /&gt;
[[File:FEXConfig 1Inst NoMulti.png|thumb]]&lt;br /&gt;
* Now rerun our test application and find the new RIP&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State.rip&lt;br /&gt;
  $2 = 0x401136&lt;br /&gt;
&lt;br /&gt;
* Alright, now we know the RIP is exactly at `0x401136`&lt;br /&gt;
* Back in gdb-multiarch&lt;br /&gt;
  (gdb) disas 0x401136,+1&lt;br /&gt;
  Dump of assembler code from 0x401136 to 0x401137:&lt;br /&gt;
     0x0000000000401136 &amp;lt;main(int, char**)+38&amp;gt;:   mov    BYTE PTR [rax],0x63&lt;br /&gt;
&lt;br /&gt;
* Looks like something in main is storing 0x63 to a nullptr&lt;br /&gt;
* In this simple case we can now take a look at the test application's source and find the problem.&lt;br /&gt;
** We know the problem is in the first block of main()&lt;br /&gt;
** We know the exact instruction that it is at&lt;br /&gt;
** We know it's something storing a byte to memory&lt;br /&gt;
* For more complex cases it is likely necessary to use reverse engineering tools&lt;br /&gt;
** BinaryNinja, Ghidra, IDA, and Hopper are all examples of tools like this&lt;br /&gt;
&lt;br /&gt;
== What to do from here ==&lt;br /&gt;
Now it becomes a lot harder. You don't get a typical debugging environment or even clean backtraces.&lt;br /&gt;
&lt;br /&gt;
FEX's gdbserver integration is sorely lacking so you can't even use a remote gdb server connecting to FEX right now.&lt;br /&gt;
&lt;br /&gt;
If you enable thunks you can get better backtraces here. [[Development:Debugging_Crash_In_Thunks|Debugging_Crash_In_Thunks]]&lt;br /&gt;
&lt;br /&gt;
== Attempting to use FEX-Emu's gdbserver implementation ==&lt;br /&gt;
'''Here be dragons'''&lt;br /&gt;
&lt;br /&gt;
FEX supports gdbserver as an integration. It's implementation is significantly limited but can still be used for debugging and getting some backtraces.&lt;br /&gt;
* Currently hardcodes the port to use as `8086` and if you have multiple gdbserver processes running then it will encounter problems.&lt;br /&gt;
* Currently does not follow processes through fork/execve at all. No multiprocess support&lt;br /&gt;
** This means you '''must''' only start the process you're caring about debugging&lt;br /&gt;
* Currently starts the process paused and will wait until gdb attach before continuing&lt;br /&gt;
** No way to start a FEX instance then attach at some later point&lt;br /&gt;
* Ctrl-C to stop the FEX process needs to be done twice&lt;br /&gt;
** Maybe with a small delay inbetween because gdb needs to fetch a bunch of data on pause&lt;br /&gt;
** Known bug, unknown why broken at the moment&lt;br /&gt;
&lt;br /&gt;
  FEXLoader -G -- &amp;lt;Application&amp;gt; &amp;lt;Args...&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Double checking if we are in JIT code ==&lt;br /&gt;
  (gdb) info reg pc&lt;br /&gt;
  pc             0x7fccfb9ec8        0x7fccfb9ec8&lt;br /&gt;
  &lt;br /&gt;
  (gdb) info proc mappings&lt;br /&gt;
  ...&lt;br /&gt;
  0x7fccfb9000       0x7fcdfb9000  0x1000000        0x0&lt;br /&gt;
&lt;br /&gt;
* Looks like FEX JIT mapping, we start out at 16MB but scale up to 128MB&lt;br /&gt;
* Depending on version of FEX we can check the base mapping for a unique string &lt;br /&gt;
  (gdb) p (char*)0x7fccfb9000&lt;br /&gt;
  $4 = 0x7fccfb9000 &amp;quot;FEXJIT::Arm64JITCore::&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Getting RIP of current code block ==&lt;br /&gt;
FEX sets up an address in our CPU context to get some debug data out.&lt;br /&gt;
&lt;br /&gt;
Currently this isn't exposed in a way that a debugger can see other than manually typing out gdb commands&lt;br /&gt;
&lt;br /&gt;
  p/x *(uint64_t*)($x28) = inline block header ptr&lt;br /&gt;
  p/x *(uint32_t*)(*(uint64_t*)($x28)) = OffsetToBlockTail&lt;br /&gt;
  p/x *(uint64_t*)($x28) + *(uint32_t*)(*(uint64_t*)($x28))&lt;br /&gt;
&lt;br /&gt;
  p/x *(unsigned long long*)((*(unsigned long long*)($x28) + *(unsigned int*)(*(unsigned long long*)($x28)))+8) = RIP of block&lt;br /&gt;
&lt;br /&gt;
  disas *(unsigned long long*)($x28),+*(unsigned long long*)(*(unsigned long long*)($x28) + *(unsigned int*)(*(unsigned long long*)($x28))) = Disassemble this block of code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While hard to decipher here is basically what is happening.&lt;br /&gt;
- x28 is the CPU register that FEX keeps in the JIT for context accesses&lt;br /&gt;
- offset 184 is the offset of the `InlineJITBlockHeader` member inside of that context.&lt;br /&gt;
- As long as FEX is in a JIT block that offset will be valid to point to the current RIP that the block is operating on.&lt;br /&gt;
&lt;br /&gt;
Getting the stack can also be very useful&lt;br /&gt;
&lt;br /&gt;
  x/64wx ((FEXCore::Core::CPUState*)$x28)-&amp;gt;gregs[FEXCore::X86State::REG_RSP]&lt;br /&gt;
&lt;br /&gt;
Doing raw pointer math here means that this works even when gdb fails to find symbols for the CPUState object, which happens very frequently for some reason.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=1444</id>
		<title>Development:Debugging Crash In Thunks</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=1444"/>
		<updated>2025-09-22T14:00:29Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Once Thunks are enabled ==&lt;br /&gt;
* Once you've verified your crash is in a thunk then this becomes quite a bit easier&lt;br /&gt;
&lt;br /&gt;
  gdb --args FEX /usr/bin/vulkaninfo&lt;br /&gt;
  Thread 1 &amp;quot;FEX&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  #1  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #2  0x0000007fe25e4028 in ?? ()&lt;br /&gt;
  Backtrace stopped: previous frame inner to this frame (corrupt stack?)&lt;br /&gt;
&lt;br /&gt;
* Okay, that's a direct crash in Turnip, let's rebuild Mesa with a debug build and try again&lt;br /&gt;
  Thread 1 &amp;quot;FEX&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  1632       memset(ptr, 0x42, 16);&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  #1  0x0000007fc80eab9c in vk_tramp_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at src/vulkan/runtime/vk_dispatch_trampolines.c:78&lt;br /&gt;
  #2  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #3  0x0000007fe25e426c in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay the crash is at.. `tu_device:1632`, let's go and debug that line&lt;br /&gt;
&lt;br /&gt;
  1631    void* ptr = (void*)1;&lt;br /&gt;
  1632    memset(ptr, 0x42, 16);&lt;br /&gt;
&lt;br /&gt;
* Who put that in there?!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1443</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1443"/>
		<updated>2025-09-22T14:00:03Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXInterpreter -&amp;gt; FEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTING=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEX&lt;br /&gt;
** This is the emulator executable used to run x86 programs&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a (deprecated) alias for ''FEX'', provided for backwards compatibility&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for configuring emulation from a Qt-based GUI&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=1434</id>
		<title>Development:Adding Config Options</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=1434"/>
		<updated>2025-09-13T08:18:53Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXLoader was removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
Configuration options are programatically generated from json.&lt;br /&gt;
&lt;br /&gt;
This file lives in `FEXCore/Source/Interface/Config/Config.json`&lt;br /&gt;
&lt;br /&gt;
= Options section =&lt;br /&gt;
To add a configuration option that can be set from JSON or from environment variables, you need to add the option to this file.&lt;br /&gt;
&lt;br /&gt;
Currently FEX has six groups to group configs&lt;br /&gt;
* CPU&lt;br /&gt;
* Emulation&lt;br /&gt;
* Debug&lt;br /&gt;
* Logging&lt;br /&gt;
* Hacks&lt;br /&gt;
* Misc&lt;br /&gt;
&lt;br /&gt;
== Configuration option object ==&lt;br /&gt;
Each JSON object under a group becomes a configuration.&lt;br /&gt;
&lt;br /&gt;
'''Object Layout'''&lt;br /&gt;
* Key:&lt;br /&gt;
  * Becomes the C++ enum. eg. 'Multiblock' becomes `FEXCore::Config::ConfigOption::CONFIG_MULTIBLOCK`&lt;br /&gt;
  * Also used for the environment variable. Becomes `FEX_MULTIBLOCK`&lt;br /&gt;
  * If the object type is boolean then a negated argument also is generated. `--no-multiblock`&lt;br /&gt;
&lt;br /&gt;
* Type:&lt;br /&gt;
  * Can be `[bool, uint8, int32, uint32, uint64, str, strarray]`&lt;br /&gt;
  * This is what the argument type ends up being once loaded from a configuration backing&lt;br /&gt;
&lt;br /&gt;
* Default:&lt;br /&gt;
  * Default value that matches this object&lt;br /&gt;
  * Used to generate code so needs to handle being codified. Compilation will fail otherwise&lt;br /&gt;
  * If Type is str or strarray then this string will be automatically wrapped with double-quotes when generated&lt;br /&gt;
&lt;br /&gt;
* TextDefault:&lt;br /&gt;
  * If the `Default` option which is used in code can't be represented by text. Like an enum being used.&lt;br /&gt;
  * eg. `Core` has a `Default` which is an enum. `TextDefault` is set to `irjit` for the user to handle this case&lt;br /&gt;
&lt;br /&gt;
* Choices:&lt;br /&gt;
  * Allows us to represent the textual options that a argument can accept&lt;br /&gt;
  * eg. `Core` supports `[ &amp;quot;irint&amp;quot;, &amp;quot;irjit&amp;quot;, &amp;quot;host&amp;quot; ]`&lt;br /&gt;
&lt;br /&gt;
* ArgumentHandler:&lt;br /&gt;
  * If an argument option needs some special handling to be parsed then this points to a C++ function in the argument loader&lt;br /&gt;
  * `Core` uses it to convert the textual representation in to an enum&lt;br /&gt;
&lt;br /&gt;
* Desc:&lt;br /&gt;
  * Short description of what this option does&lt;br /&gt;
  * This is used to generate the text in the man pages&lt;br /&gt;
&lt;br /&gt;
== UnnamedOptions section ==&lt;br /&gt;
These are configuration options that can '''NOT''' be set by user means. There won't be any Environment variable or json helpers generated to load these.&lt;br /&gt;
&lt;br /&gt;
These need to exist as a way to have internal configuration options existing in the same global space as user options. Allows us to pull internal configuration options the same way as user configurations.&lt;br /&gt;
&lt;br /&gt;
These can exist under any group config. Currently only `Misc` is used. Only three things need to be set for these&lt;br /&gt;
* Key: This is only used to generate the enum in code&lt;br /&gt;
* Type: Same supported types as the regular options&lt;br /&gt;
* Default: The default value of this configuration&lt;br /&gt;
&lt;br /&gt;
== Getting configurations in FEX code ==&lt;br /&gt;
FEX provides a `FEX_CONFIG_OPT` define to help developers get configuration options.&lt;br /&gt;
* FEX_CONFIG_OPT(name, enum)&lt;br /&gt;
  * eg: `FEX_CONFIG_OPT(Cores, THREADS);`&lt;br /&gt;
  * This will load the THREADS configuration option from the configuration directory and save the value in to local value called `Cores`&lt;br /&gt;
* Gotchas:&lt;br /&gt;
  * Construction of the object queries the the global configuration layer. This can be slow so be careful with its use.&lt;br /&gt;
  * Upon construction of the `FEXCore::Config::Value&amp;lt;T&amp;gt;` object it will pull the string configuration&lt;br /&gt;
  * Then it will convert that value in to whatever type the value needs&lt;br /&gt;
  * In high performance code, keep constructor instantiation outside of the hot code path&lt;br /&gt;
  * Construct the configuration inside of a class definition so it only pulls the configuration once&lt;br /&gt;
* Caveats:&lt;br /&gt;
  * If the configuration changes then this doesn't pick up the change&lt;br /&gt;
  * Configuration isn't meant to change live in FEX so this is typically a non-issue&lt;br /&gt;
  * Frontend object loader needs to be careful with its configuration loading to ensure the meta layer stays in sync&lt;br /&gt;
  * ELFLoader.cpp for examples here&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Configuration&amp;diff=1433</id>
		<title>Development:Configuration</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Configuration&amp;diff=1433"/>
		<updated>2025-09-13T08:14:17Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXLoader was removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FEX-Emu supports a layered configuration system that can be confusing to understand at face value. This is page to hopefully explain how FEX's configuration system works.&lt;br /&gt;
&lt;br /&gt;
= FEX Configuration layers =&lt;br /&gt;
FEX supports multiple layers to its configuration. Many of which are available for users to modify to their liking.&lt;br /&gt;
&lt;br /&gt;
'''List of layers - Lower layers overwriting configurations from upper layers'''&lt;br /&gt;
* Global Primary configuration - '''Read-only'''&lt;br /&gt;
* User Primary configuration&lt;br /&gt;
* User Arguments configuration&lt;br /&gt;
* Global application configuration - '''Read-only'''&lt;br /&gt;
* User application configuration&lt;br /&gt;
* User environment variable configuration&lt;br /&gt;
&lt;br /&gt;
== Global Primary configuration ==&lt;br /&gt;
'''/usr/share/fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
This configuration file is a global read-only configuration that is only used in very select circumstances. It is not expected that a user will need or want this since it is read-only.&lt;br /&gt;
&lt;br /&gt;
This is FEX's standard JSON configuration format.&lt;br /&gt;
&lt;br /&gt;
== User Primary configuration ==&lt;br /&gt;
'''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
This is the primary configuration file that is expected to be changed most frequently by the user. If the user is modifying configuration with FEXConfig, this is the file that should be saved.&lt;br /&gt;
&lt;br /&gt;
This is FEX's standard JSON configuration format.&lt;br /&gt;
&lt;br /&gt;
== Global application configuration ==&lt;br /&gt;
'''/usr/share/fex-emu/AppConfig/&amp;lt;Application Name&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
This is a read-only configuration for application specific options. These are usually workarounds or trivial workarounds that FEX needs for specific applications. It's not expected that a user will need to modify these.&lt;br /&gt;
&lt;br /&gt;
This is FEX's standard JSON configuration format. &lt;br /&gt;
&lt;br /&gt;
== User application configuration ==&lt;br /&gt;
'''$HOME/.fex-emu/AppConfig/&amp;lt;Application Name&amp;gt;.json'''&lt;br /&gt;
&lt;br /&gt;
This is a user provided application configuration. This is useful for users to set their own options for specific applications.&lt;br /&gt;
* Very useful for only enabling Thunks for specific applications. Where global enabling can cause too many crashes.&lt;br /&gt;
&lt;br /&gt;
This is FEX's standard JSON configuration format.&lt;br /&gt;
&lt;br /&gt;
== User environment variable configuration ==&lt;br /&gt;
'''Environment variables starting with FEX_'''&lt;br /&gt;
&lt;br /&gt;
These are useful for testing various options. While in most cases the environment variables will pass through to child processes. It still isn't guaranteed if the application is modifying the environment before executing a child process.&lt;br /&gt;
&lt;br /&gt;
These can be found under '''man FEX''' under the '''ENVIRONMENT''' section. The environment name is just '''FEX_''' prepended to an all capitalized json key name.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1432</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1432"/>
		<updated>2025-09-13T08:13:13Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: FEXLoader was removed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTING=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is the emulator executable used to run x86 programs&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for configuring emulation from a Qt-based GUI&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1431</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1431"/>
		<updated>2025-09-11T12:12:09Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: BUILD_TESTS -&amp;gt; BUILD_TESTING&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTING=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXLoader&lt;br /&gt;
** This is useful for development purposes but is generally recommended against using.&lt;br /&gt;
** Allows passing arguments to FEX for configuration purposes, which can break under some execve situations&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a hardlink to FEXLoader which refuses to treat arguments as configuration options&lt;br /&gt;
** Is recommended to use over FEXLoader; Using FEXConfig to set configuration&lt;br /&gt;
** Requires being a hardlink or executable copy, execve logic sees through a softlink&lt;br /&gt;
** Is the executable used for binfmt_misc for interpreters&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for configuring emulation from a Qt-based GUI&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:InstCountCI&amp;diff=1430</id>
		<title>Development:InstCountCI</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:InstCountCI&amp;diff=1430"/>
		<updated>2025-09-11T12:11:54Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: BUILD_TESTS -&amp;gt; BUILD_TESTING&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
InstCountCI is a continuous integration tool that FEX-Emu uses to ensure that instruction implementations aren't getting worse over time.&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
Make sure to follow [[Development:Setting_up_FEX]] to get an initial build environment set up.&lt;br /&gt;
&lt;br /&gt;
=== What you need ===&lt;br /&gt;
* An Arm64 Linux device that can build FEX&lt;br /&gt;
** An x86-64 device using the VIXL simulator can be used as a substitute.&lt;br /&gt;
&lt;br /&gt;
=== Additional cmake options ===&lt;br /&gt;
Some additional cmake options need to be passed to the FEX-Emu cmake options to get the tests building.&lt;br /&gt;
&lt;br /&gt;
* -DBUILD_TESTING=True&lt;br /&gt;
* -DENABLE_VIXL_DISASSEMBLER=True&lt;br /&gt;
&lt;br /&gt;
=== Quality of life improvements ===&lt;br /&gt;
Add these cmake options to make iteration time faster and have debug assertions to catch problems.&lt;br /&gt;
* -DENABLE_LTO=False&lt;br /&gt;
* -DCMAKE_BUILD_TYPE=RelWithDebInfo&lt;br /&gt;
* -DENABLE_ASSERTIONS=True&lt;br /&gt;
&lt;br /&gt;
=== Running InstCountCI ===&lt;br /&gt;
First thing you need to build the tests. This step will parse all the json files inside of '''unittests/InstructionCountCI/''' and set up running CI in the next step.&lt;br /&gt;
* ninja instcountci_test_files&lt;br /&gt;
&lt;br /&gt;
Next you need to actually run the tests. This will run all the instructions declared in '''unittests/InstructionCountCI/*.json'''. If this step fails, that is okay since that just means that either an instruction translation has gotten worse, or if the test crashed then something catastrophic happened.&lt;br /&gt;
* ninja instcountci_tests&lt;br /&gt;
&lt;br /&gt;
The next step is to take the data generated from the previous step and modify the resulting json that is tracked by git. &lt;br /&gt;
* ninja instcountci_update_tests&lt;br /&gt;
&lt;br /&gt;
Now to see how the implementations have changed, you can just run '''git diff''' to see how the json files in '''unittests/InstructionCountCI/''' have changed.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
Minor improvement when optimizing a move instruction. From [https://github.com/FEX-Emu/FEX/pull/2972 This] pull request.&lt;br /&gt;
       &amp;quot;movd mm0, eax&amp;quot;: {&lt;br /&gt;
  -      &amp;quot;ExpectedInstructionCount&amp;quot;: 3,&lt;br /&gt;
  +      &amp;quot;ExpectedInstructionCount&amp;quot;: 2,&lt;br /&gt;
         &amp;quot;Comment&amp;quot;: &amp;quot;0x0f 0x6e&amp;quot;,&lt;br /&gt;
         &amp;quot;ExpectedArm64ASM&amp;quot;: [&lt;br /&gt;
  -        &amp;quot;ubfx x20, x4, #0, #32&amp;quot;,&lt;br /&gt;
  -        &amp;quot;fmov s4, w20&amp;quot;,&lt;br /&gt;
  +        &amp;quot;fmov s4, w4&amp;quot;,&lt;br /&gt;
           &amp;quot;str d4, [x28, #752]&amp;quot;&lt;br /&gt;
         ]&lt;br /&gt;
       },&lt;br /&gt;
* Reset the files with '''git checkout -- unittests/InstructionCountCI/*.json''' if the changes weren't desired.&lt;br /&gt;
&lt;br /&gt;
== What classifies as an optimal translation? ==&lt;br /&gt;
Nothing classifies if an instruction implementation is considered optimal or not. This is left up to the human to try and understand if the translation is optimal for that particular instruction.&lt;br /&gt;
* In general the ''Optimal'' tag is just a guideline since humans could have made a mistake and the instruction could be further optimized.&lt;br /&gt;
* Alternatively ARM could introduce a new set of instructions that improve how optimal an instruction could be.&lt;br /&gt;
* Further an instruction could be considered optimal, but the reviewer ignored something like flag generation around it since that is a systemic FEX-Emu issue.&lt;br /&gt;
* Or of course, just human error and it was misunderstood as an optimal implementation but someone found a way to do it better.&lt;br /&gt;
&lt;br /&gt;
This is more just a tag to help humans when they are doing code auditing so they don't need to pay as much attention to the ones that are classified as such. It's still good to periodically go over these implementations and see if things could be done better.&lt;br /&gt;
&lt;br /&gt;
== Diving deeper in to the assembly ==&lt;br /&gt;
=== Manually run instcountci result ===&lt;br /&gt;
A useful first step might be to run the json tests directly in the code size validation program. This can be done from the build directory.&lt;br /&gt;
&lt;br /&gt;
* eg:&lt;br /&gt;
  ./Bin/CodeSizeValidation unittests/InstructionCountCI/FEXOpt/libnss.json.instcountci&lt;br /&gt;
&lt;br /&gt;
=== Run the test through the TestHarnessRunner ===&lt;br /&gt;
While the instruction count CI is good at showing the final result, it isn't the best at showing what FEX did to get to that result. This is where the assembly test harness can come in handy.&lt;br /&gt;
* Create a file in '''unittests/ASM/Test.asm'''&lt;br /&gt;
* Add the following data:&lt;br /&gt;
  %ifdef CONFIG&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
  %endif&lt;br /&gt;
  addps xmm0, xmm1&lt;br /&gt;
  hlt&lt;br /&gt;
* Recompile the asm tests with `ninja asm_files`&lt;br /&gt;
* Run the assembly test manually now with '''FEX_DUMPIR=stderr FEX_DISASSEMBLE=blocks ./Bin/TestHarnessRunner -c irjit -n 1 -g ./unittests/ASM/Test.asm.bin ./unittests/ASM/Test.asm.config.bin'''&lt;br /&gt;
** This will dump both FEX's internal IR and the disassembly of the code for each instruction&lt;br /&gt;
** The second code block for the '''hlt''' can be ignored. It is just necessary for this test harness to run.&lt;br /&gt;
&lt;br /&gt;
The resulting output will be:&lt;br /&gt;
  IR-post 0x10000:&lt;br /&gt;
        (%0) IRHeader %2, #65536, #0, #1&lt;br /&gt;
        (%2) CodeBlock %3, %10&lt;br /&gt;
                (%3 i0) BeginBlock %2(Invalid)&lt;br /&gt;
                %4(FPRFixed1) i128 = LoadRegister #0x0, #0xd0, FPR, FPRFixed, u8:Tmp:Size&lt;br /&gt;
                %5(FPRFixed0) i128 = LoadRegister #0x0, #0xc0, FPR, FPRFixed, u8:Tmp:Size&lt;br /&gt;
                %6(FPRFixed0) i32v4 = VFAdd u8:Tmp:RegisterSize, u8:Tmp:ElementSize, %5(FPRFixed0) i128, %4(FPRFixed1) i128&lt;br /&gt;
                (%7 i128) StoreRegister %6(FPRFixed0) i32v4, #0x0, #0xc0, FPR, FPRFixed, u8:Tmp:Size&lt;br /&gt;
                (%8 i64) InlineEntrypointOffset #0x3, u8:Tmp:RegisterSize&lt;br /&gt;
                (%9 i64) ExitFunction %8(Invalid)&lt;br /&gt;
                (%10 i0) EndBlock %2(Invalid)&lt;br /&gt;
  @@@@@&lt;br /&gt;
  [INFO] Disassemble Begin&lt;br /&gt;
  [INFO] adr x0, #-0x4 (addr 0xffff6fa00018)&lt;br /&gt;
  [INFO] str x0, [x28, #184]&lt;br /&gt;
  [INFO] fadd v16.4s, v16.4s, v17.4s&lt;br /&gt;
  [INFO] ldr x0, pc+8 (addr 0xffff6fa00030)&lt;br /&gt;
  [INFO] blr x0&lt;br /&gt;
  [INFO] unallocated (Unallocated)&lt;br /&gt;
  [INFO] udf #0xffff&lt;br /&gt;
  [INFO] unallocated (Unallocated)&lt;br /&gt;
  [INFO] udf #0x0&lt;br /&gt;
  [INFO] Disassemble End&lt;br /&gt;
&lt;br /&gt;
* The disassembly has some instructions at the start and end which are necessary for the JIT to run&lt;br /&gt;
** InstCountCI strips this code out automatically.&lt;br /&gt;
* In a vacuum of a single instruction, the code block header and tail can dominate the code size.&lt;br /&gt;
** It's recommended to become familiar with what the header and tail look like and ignore it in the resulting code generation.&lt;br /&gt;
** Currently the header is the first two instructions '''adr+str'''&lt;br /&gt;
** Currently the tail starts with the '''ldr+blr''' after the '''fadd''' and continues with some metadata afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Diving Deeper ===&lt;br /&gt;
I would recommend looking at the man page for FEX to see additional options that can be useful&lt;br /&gt;
* Specifically the options for '''FEX_PASSMANAGERDUMPIR''' to get more IR dumping options and '''FEX_HOSTFEATURES''' to fake CPU feature support.&lt;br /&gt;
* Enabling the vixl simulator with the cmake option '''-DENABLE_VIXL_SIMULATOR=True''' can be useful to test features your CPU doesn't support!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1429</id>
		<title>Development:ARM64EC</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1429"/>
		<updated>2025-09-11T12:11:37Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: BUILD_TESTS -&amp;gt; BUILD_TESTING&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
=== Building ===&lt;br /&gt;
These instructions expect you to be building on an ARM64 host. &lt;br /&gt;
&lt;br /&gt;
==== Toolchain ====&lt;br /&gt;
Scripts and instructions to build an ARM64EC toolchain can be found [https://github.com/bylaws/llvm-mingw here], with prebuilt binaries for ARM64/x86 hosts on the [https://github.com/bylaws/llvm-mingw/releases/tag/20240929 releases page]. Once built/downloaded, add it to your environment with &lt;br /&gt;
 export PATH=&amp;quot;&amp;lt;path to toolchain&amp;gt;/bin:$PATH&amp;quot;&lt;br /&gt;
note the toolchain must come before all other path entries as it needs to override the host ar binary.&lt;br /&gt;
* Make sure to grab the tar.gz aarch64 files when compiling on Linux. The zip files are for a Windows toolchain which doesn't work for these instructions.&lt;br /&gt;
&lt;br /&gt;
==== Wine ====&lt;br /&gt;
[https://gitlab.winehq.org/wine/wine Upstream] wine has various things missing for full FEX/ARM64EC support, while it can be used, [https://github.com/bylaws/wine/tree/upstream-arm64ec my fork] will give the best results for now. Make sure to install the deps listed [https://salsa.debian.org/wine-team/wine/-/blob/debian/9.0_repack-4/debian/control.in?ref_type=tags#L13 here] before building with the ARM64EC toolchain.&lt;br /&gt;
&lt;br /&gt;
  ./configure --enable-archs=arm64ec,aarch64,i386 --prefix=/usr --with-mingw=clang --disable-tests&lt;br /&gt;
  make -j$(nproc)&lt;br /&gt;
  sudo --preserve-env=PATH make install -j$(nproc)&lt;br /&gt;
&lt;br /&gt;
==== FEX ====&lt;br /&gt;
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)&lt;br /&gt;
&lt;br /&gt;
FEX's official [https://launchpad.net/~fex-emu/+archive/ubuntu/fex Ubuntu PPA] now provides a fex-emu-wine package of the latest release. This package can be downloaded and the DLL files can be extracted if compiling isn't desired.&lt;br /&gt;
&lt;br /&gt;
===== Build directions =====&lt;br /&gt;
 mkdir build-arm64ec&lt;br /&gt;
 cd build-arm64ec&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../Data/CMake/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 -DBUILD_TESTING=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
 mkdir build-wow64&lt;br /&gt;
 cd build-wow64&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../Data/CMake/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 -DBUILD_TESTING=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
==== dxvk/vkd3d-proton ====&lt;br /&gt;
&lt;br /&gt;
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file: &lt;br /&gt;
 [binaries]&lt;br /&gt;
 ar = 'arm64ec-w64-mingw32-ar'&lt;br /&gt;
 c = 'arm64ec-w64-mingw32-gcc'&lt;br /&gt;
 cpp = 'arm64ec-w64-mingw32-g++'&lt;br /&gt;
 ld = 'arm64ec-w64-mingw32-ld'&lt;br /&gt;
 windres = 'arm64ec-w64-mingw32-windres'&lt;br /&gt;
 strip = 'strip'&lt;br /&gt;
 widl = 'arm64ec-w64-mingw32-widl'&lt;br /&gt;
 pkgconfig = 'aarch64-linux-gnu-pkg-config'&lt;br /&gt;
 [host_machine]&lt;br /&gt;
 system = 'windows'&lt;br /&gt;
 cpu_family = 'aarch64'&lt;br /&gt;
 cpu = 'aarch64'&lt;br /&gt;
 endian = 'little'&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
ARM64EC FEX is usable as a drop-in replacement for xtajit64 on native WOA, build FEX with -DUSE_PDB_DEBUGINFO=True and copy the libarm64ecfex.{dll,pdb} binaries into C:/Windows/System32. To actually use FEX create an empty registry key at HKLM\\Software\\Microsoft\\Wow64\\amd64 and set its value to libarm64ecfex.dll, all subsequently launched programs will then use FEX. Logs/configuration is stored in %localappdata%.&lt;br /&gt;
&lt;br /&gt;
=== Info ===&lt;br /&gt;
Unlike Linux FEX, the Windows FEX modules purely handle CPU emulation, with syscall translation being done on either the wine side (WOW64) or ABI (ARM64EC). This is similarly the case for wine's unixcalls and as a result native ARM64 variants can be used for all .so libraries (Vulkan, wine, etc.) dropping the need for an x86 rootfs and FEX-side thunking. &lt;br /&gt;
&lt;br /&gt;
WOW64 (Windows 32-bit On Windows 64-bit) is the mechanism to run 32-bit applications on 64-bit platforms: All system libraries are built as x86 and emulated. Any 32-bit syscalls they use are adapted on-the-fly to 64-bit equivalents by injecting thunks.&lt;br /&gt;
&lt;br /&gt;
ARM64EC (Emulation Compatible) on the other hand deals with 64-bit applications and avoids emulation overhead by using a dedicated set of system libraries compiled for ARM64 with the custom ARM64EC ABI. This ABI is designed to be callable from recompiled x86_64 code in order to allow a mix-and-match of native and emulated code. To avoid needing both a set of ARM64EC and ARM64 system libraries, ARM64X is introduced: It uses linker relocations to combine ARM64EC code and regular ARM64 code in a single binary file, which can be used both by standard Windows-on-Arm applications and emulated x86_64 ones.&lt;br /&gt;
&lt;br /&gt;
The following pages serve as a good reference: &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi &lt;br /&gt;
&lt;br /&gt;
https://gitlab.winehq.org/wine/wine/-/wikis/ARM64EC-Toolchain&lt;br /&gt;
&lt;br /&gt;
Of note is the fact that FEX needs to run in a very reduced Windows environment - due to how early it is loaded it can only depend on ntdll and not say the system CRT. This is worked around by implementing/stubbing the subset of the CRT/Windows APIs necessary for FEX to run/link purely ontop of ntdll (see Common/Windows/{WinAPI,CRT}).&lt;br /&gt;
&lt;br /&gt;
=== Building problems ===&lt;br /&gt;
==== `bytes of instructions in range, but .seh directives corresponding to` ====&lt;br /&gt;
This is seemingly caused by the `-mcpu` tune option, pass to cmake `-DTUNE_CPU=none`&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1392</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1392"/>
		<updated>2025-07-14T10:12:19Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTS=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install -j4&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc_32&lt;br /&gt;
  sudo ninja binfmt_misc_64&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXLoader&lt;br /&gt;
** This is useful for development purposes but is generally recommended against using.&lt;br /&gt;
** Allows passing arguments to FEX for configuration purposes, which can break under some execve situations&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a hardlink to FEXLoader which refuses to treat arguments as configuration options&lt;br /&gt;
** Is recommended to use over FEXLoader; Using FEXConfig to set configuration&lt;br /&gt;
** Requires being a hardlink or executable copy, execve logic sees through a softlink&lt;br /&gt;
** Is the executable used for binfmt_misc for interpreters&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for configuring emulation from a Qt-based GUI&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1391</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=1391"/>
		<updated>2025-07-14T10:08:57Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: /* Installing Thunks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
=== Debian/Ubuntu dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkgconf&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* llvm&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* python-setuptools (For build scripts)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* libgcc-XX-dev-i386-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* libgcc-XX-dev-amd64-cross (For building thunks, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-12-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
* qtdeclarative5-dev (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls (For GUI)&lt;br /&gt;
* qml-module-qtquick-controls2 (For GUI)&lt;br /&gt;
* qml-module-qtquick-dialogs (For GUI)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* llvm&lt;br /&gt;
* llvm-devel&lt;br /&gt;
* openssl-devel&lt;br /&gt;
* nasm&lt;br /&gt;
* python3-clang&lt;br /&gt;
* python3-setuptools&lt;br /&gt;
* squashfs-tools&lt;br /&gt;
* squashfuse&lt;br /&gt;
* erofs-fuse&lt;br /&gt;
* erofs-utils&lt;br /&gt;
* qt5-qtdeclarative-devel&lt;br /&gt;
* qt5-qtquickcontrols&lt;br /&gt;
* qt5-qtquickcontrols2&lt;br /&gt;
&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTS=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install -j4&lt;br /&gt;
&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then make sure to uninstall their's first.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc_32&lt;br /&gt;
  sudo ninja binfmt_misc_64&lt;br /&gt;
&lt;br /&gt;
=== Quirks ===&lt;br /&gt;
&lt;br /&gt;
==== binfmt_misc problems ====&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
==== DESTDIR quirks ====&lt;br /&gt;
* When using DESTDIR, make sure the path is absolute instead of relative&lt;br /&gt;
** FEX's thunks use subprojects because it needs to cross-compile&lt;br /&gt;
** If DESTDIR is relative then the install paths of the subprojects go to the wrong location&lt;br /&gt;
** Using $(pwd)/install works well&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves the configuration.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications. FEX provides various x86 images that can be installed through [[Development:Setting_up_RootFS#Quick_Setup_with_FEXRootFSFetcher|FEXRootFSFetcher]]&lt;br /&gt;
&lt;br /&gt;
For more detailed instructions see [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Setting up library forwarding ==&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Library_Forwarding|here]].&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXLoader&lt;br /&gt;
** This is useful for development purposes but is generally recommended against using.&lt;br /&gt;
** Allows passing arguments to FEX for configuration purposes, which can break under some execve situations&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a hardlink to FEXLoader which refuses to treat arguments as configuration options&lt;br /&gt;
** Is recommended to use over FEXLoader; Using FEXConfig to set configuration&lt;br /&gt;
** Requires being a hardlink or executable copy, execve logic sees through a softlink&lt;br /&gt;
** Is the executable used for binfmt_misc for interpreters&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for setting configuration options from a GUI&lt;br /&gt;
** Written using Dear ImGui&lt;br /&gt;
** Can load/save global configuration and application configuration files&lt;br /&gt;
** Application configuration files are compared against the executable filename&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Main_Page&amp;diff=1390</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Main_Page&amp;diff=1390"/>
		<updated>2025-07-14T10:05:46Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: /* Development Topics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the FEX emulator wiki website!&lt;br /&gt;
&lt;br /&gt;
== Account Creation ==&lt;br /&gt;
Due to the typical problem of mediawiki sites getting hit by spam bots. Account creation is moderated.&lt;br /&gt;
&lt;br /&gt;
If you create a new account and it doesn't pass through the moderation queue quickly then make sure to ask on IRC or Discord and someone should be able to help.&lt;br /&gt;
&lt;br /&gt;
== Game Categories of interest ==&lt;br /&gt;
&lt;br /&gt;
[[:Category:Game_Type_Application|Games list]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:Vulkan_Render_API|Games that support Vulkan]]&lt;br /&gt;
* [[:Category:Vulkan_Thunk_Capable|Vulkan Thunk Capable]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:OpenGL_Render_API|Games that support OpenGL]]&lt;br /&gt;
* [[:Category:OpenGL_Thunk_Capable|OpenGL Thunk Capable]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:X86-32|32-bit x86 Games]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:X86-64|64-bit x86_64 Games]]&lt;br /&gt;
&lt;br /&gt;
== Development Topics ==&lt;br /&gt;
[[Development:Setting_up_FEX]]&lt;br /&gt;
&lt;br /&gt;
[[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
[[Development:Setting_up_Library_Forwarding]]&lt;br /&gt;
&lt;br /&gt;
[[Development:Debugging_FEX_with_Signals]]&lt;br /&gt;
&lt;br /&gt;
[[Development:Debugging_Crash]]&lt;br /&gt;
&lt;br /&gt;
[[Development:Renderdoc]]&lt;br /&gt;
&lt;br /&gt;
[[Development:gfxreconstruct]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1389</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1389"/>
		<updated>2025-07-14T10:05:07Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Library forwarding is a FEX feature that allows redirecting calls to common libraries OpenGL or Vulkan from their emulated x86 builds to their native ARM64 counterparts installed on the host system. This saves emulation overhead and dramatically improves performance for some applications.&lt;br /&gt;
&lt;br /&gt;
= Build instructions =&lt;br /&gt;
&lt;br /&gt;
Install the dependencies below and enable the &amp;lt;code&amp;gt;BUILD_THUNKS&amp;lt;/code&amp;gt; CMake option:&lt;br /&gt;
* &amp;lt;code&amp;gt;cmake -DBUILD_THUNKS=True .&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your distribution is not listed below, there is a generic fallback that requires Nix or a [https://lix.systems/install/#on-any-other-linuxmacos-system compatible alternative].&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu dependencies ===&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* pkg-config&lt;br /&gt;
* libclang-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* Development packages for thunked libraries:&lt;br /&gt;
** libdrm-dev&lt;br /&gt;
** libxcb-present-dev&lt;br /&gt;
** libxcb-dri2-0-dev&lt;br /&gt;
** libxcb-dri3-dev&lt;br /&gt;
** libxcb-glx0-dev&lt;br /&gt;
** libxcb-shm0-dev&lt;br /&gt;
** libxshmfence-dev&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* libXext-devel&lt;br /&gt;
* libXfixes-devel&lt;br /&gt;
* libXrender-devel&lt;br /&gt;
* libXrandr-devel&lt;br /&gt;
* alsa-lib-devel&lt;br /&gt;
* libxcb-devel&lt;br /&gt;
* libxshmfence-devel&lt;br /&gt;
* libdrm-devel&lt;br /&gt;
* xorg-x11-server-devel&lt;br /&gt;
&lt;br /&gt;
=== Generic Nix fallback ===&lt;br /&gt;
&lt;br /&gt;
With Nix installed, run &amp;lt;code&amp;gt;../Data/nix/cmake_enable_libfwd.sh&amp;lt;/code&amp;gt; from your build folder. This will set up a cross-compiler, install the required dependencies, and enable the required CMake option.&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
FEXConfig can be used to enable/disable individual libraries.&lt;br /&gt;
&lt;br /&gt;
=== Per-app overrides ===&lt;br /&gt;
* Filename in '''$HOME/.fex-emu/AppConfig/Balatro.exe.json'''&lt;br /&gt;
* Change the filename as necessary for your application&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan&amp;quot;: 1&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Advanced configuration =&lt;br /&gt;
=== FEX environment variables and command-line arguments ===&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
===Overriding paths for library wrappers ===&lt;br /&gt;
You can can set the three configuration options to custom paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
&lt;br /&gt;
=== ThunksDB.json schema ===&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''. Normally this does not need to be modified, but an overlay to the default database can be provided at '''$HOME/.fex-emu/ThunksDB.json'''.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Thunks&amp;diff=1388</id>
		<title>Development:Setting up Thunks</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Thunks&amp;diff=1388"/>
		<updated>2025-07-14T09:42:46Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Neobrain moved page Development:Setting up Thunks to Development:Setting up Library Forwarding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Development:Setting up Library Forwarding]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1387</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1387"/>
		<updated>2025-07-14T09:42:46Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Neobrain moved page Development:Setting up Thunks to Development:Setting up Library Forwarding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Build instructions =&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* pkg-config&lt;br /&gt;
* libclang-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* Development packages for thunked libraries:&lt;br /&gt;
** libdrm-dev&lt;br /&gt;
** libxcb-present-dev&lt;br /&gt;
** libxcb-dri2-0-dev&lt;br /&gt;
** libxcb-dri3-dev&lt;br /&gt;
** libxcb-glx0-dev&lt;br /&gt;
** libxcb-shm0-dev&lt;br /&gt;
** libxshmfence-dev&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* libXext-devel&lt;br /&gt;
* libXfixes-devel&lt;br /&gt;
* libXrender-devel&lt;br /&gt;
* libXrandr-devel&lt;br /&gt;
* alsa-lib-devel&lt;br /&gt;
* libxcb-devel&lt;br /&gt;
* libxshmfence-devel&lt;br /&gt;
* libdrm-devel&lt;br /&gt;
* xorg-x11-server-devel&lt;br /&gt;
&lt;br /&gt;
== Setting CMake to build thunks ==&lt;br /&gt;
Pass in to CMake the option to enable thunk building.&lt;br /&gt;
* -DBUILD_THUNKS=True&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
FEXConfig can be used to enable/disable individual libraries.&lt;br /&gt;
&lt;br /&gt;
= Advanced configuration =&lt;br /&gt;
== FEX thunk options ==&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
== How to use Thunks ==&lt;br /&gt;
You can can set the three configuration options to custom paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
&lt;br /&gt;
== Thunks Database format ==&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''&lt;br /&gt;
&lt;br /&gt;
The user can also provide a '''$HOME/.fex-emu/ThunksDB.json''' which will overlay the system installed path&lt;br /&gt;
&lt;br /&gt;
This allows the user to configure the thunk file mapping once, since it is unlikely to change between applications. The user can also mix and match ThunksDB and regular thunks configuration if a complex configuration is necessary.&lt;br /&gt;
&lt;br /&gt;
* ThunksDB.json example&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Look at the FEX provided library for a real implementation, or just use the provided configuration.&lt;br /&gt;
&lt;br /&gt;
Once the user has a viable ThunksDB provided, now configure FEX with a ThunkConfig filepath with the application thunk configuration.&lt;br /&gt;
&lt;br /&gt;
This thunks configuration file can now enable Thunk definitions using the user defined names.&lt;br /&gt;
&lt;br /&gt;
== Per-app overrides ==&lt;br /&gt;
* Filename in '''$HOME/.fex-emu/AppConfig/Balatro.exe.json'''&lt;br /&gt;
* Change the filename as necessary for your application&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan&amp;quot;: 1&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Further notes =&lt;br /&gt;
== Limitations and problems ==&lt;br /&gt;
* For 32-bit applications, libGL is the only library that can use the host variant currently&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1386</id>
		<title>Development:ARM64EC</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1386"/>
		<updated>2025-07-14T09:41:50Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
=== Building ===&lt;br /&gt;
These instructions expect you to be building on an ARM64 host. &lt;br /&gt;
&lt;br /&gt;
==== Toolchain ====&lt;br /&gt;
Scripts and instructions to build an ARM64EC toolchain can be found [https://github.com/bylaws/llvm-mingw here], with prebuilt binaries for ARM64/x86 hosts on the [https://github.com/bylaws/llvm-mingw/releases/tag/20240929 releases page]. Once built/downloaded, add it to your environment with &lt;br /&gt;
 export PATH=&amp;quot;&amp;lt;path to toolchain&amp;gt;/bin:$PATH&amp;quot;&lt;br /&gt;
note the toolchain must come before all other path entries as it needs to override the host ar binary.&lt;br /&gt;
* Make sure to grab the tar.gz aarch64 files when compiling on Linux. The zip files are for a Windows toolchain which doesn't work for these instructions.&lt;br /&gt;
&lt;br /&gt;
==== Wine ====&lt;br /&gt;
[https://gitlab.winehq.org/wine/wine Upstream] wine has various things missing for full FEX/ARM64EC support, while it can be used, [https://github.com/bylaws/wine/tree/upstream-arm64ec my fork] will give the best results for now. Make sure to install the deps listed [https://salsa.debian.org/wine-team/wine/-/blob/debian/9.0_repack-4/debian/control.in?ref_type=tags#L13 here] before building with the ARM64EC toolchain.&lt;br /&gt;
&lt;br /&gt;
  ./configure --enable-archs=arm64ec,aarch64,i386 --prefix=/usr --with-mingw=clang --disable-tests&lt;br /&gt;
  make -j$(nproc)&lt;br /&gt;
  sudo --preserve-env=PATH make install -j$(nproc)&lt;br /&gt;
&lt;br /&gt;
==== FEX ====&lt;br /&gt;
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)&lt;br /&gt;
&lt;br /&gt;
FEX's official [https://launchpad.net/~fex-emu/+archive/ubuntu/fex Ubuntu PPA] now provides a fex-emu-wine package of the latest release. This package can be downloaded and the DLL files can be extracted if compiling isn't desired.&lt;br /&gt;
&lt;br /&gt;
===== Build directions =====&lt;br /&gt;
 mkdir build-arm64ec&lt;br /&gt;
 cd build-arm64ec&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../Data/CMake/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
 mkdir build-wow64&lt;br /&gt;
 cd build-wow64&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../Data/CMake/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
==== dxvk/vkd3d-proton ====&lt;br /&gt;
&lt;br /&gt;
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file: &lt;br /&gt;
 [binaries]&lt;br /&gt;
 ar = 'arm64ec-w64-mingw32-ar'&lt;br /&gt;
 c = 'arm64ec-w64-mingw32-gcc'&lt;br /&gt;
 cpp = 'arm64ec-w64-mingw32-g++'&lt;br /&gt;
 ld = 'arm64ec-w64-mingw32-ld'&lt;br /&gt;
 windres = 'arm64ec-w64-mingw32-windres'&lt;br /&gt;
 strip = 'strip'&lt;br /&gt;
 widl = 'arm64ec-w64-mingw32-widl'&lt;br /&gt;
 pkgconfig = 'aarch64-linux-gnu-pkg-config'&lt;br /&gt;
 [host_machine]&lt;br /&gt;
 system = 'windows'&lt;br /&gt;
 cpu_family = 'aarch64'&lt;br /&gt;
 cpu = 'aarch64'&lt;br /&gt;
 endian = 'little'&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
ARM64EC FEX is usable as a drop-in replacement for xtajit64 on native WOA, build FEX with -DUSE_PDB_DEBUGINFO=True and copy the libarm64ecfex.{dll,pdb} binaries into C:/Windows/System32. To actually use FEX create an empty registry key at HKLM\\Software\\Microsoft\\Wow64\\amd64 and set its value to libarm64ecfex.dll, all subsequently launched programs will then use FEX. Logs/configuration is stored in %localappdata%.&lt;br /&gt;
&lt;br /&gt;
=== Info ===&lt;br /&gt;
Unlike Linux FEX, the Windows FEX modules purely handle CPU emulation, with syscall translation being done on either the wine side (WOW64) or ABI (ARM64EC). This is similarly the case for wine's unixcalls and as a result native ARM64 variants can be used for all .so libraries (Vulkan, wine, etc.) dropping the need for an x86 rootfs and FEX-side thunking. &lt;br /&gt;
&lt;br /&gt;
WOW64 (Windows 32-bit On Windows 64-bit) is the mechanism to run 32-bit applications on 64-bit platforms: All system libraries are built as x86 and emulated. Any 32-bit syscalls they use are adapted on-the-fly to 64-bit equivalents by injecting thunks.&lt;br /&gt;
&lt;br /&gt;
ARM64EC (Emulation Compatible) on the other hand deals with 64-bit applications and avoids emulation overhead by using a dedicated set of system libraries compiled for ARM64 with the custom ARM64EC ABI. This ABI is designed to be callable from recompiled x86_64 code in order to allow a mix-and-match of native and emulated code. To avoid needing both a set of ARM64EC and ARM64 system libraries, ARM64X is introduced: It uses linker relocations to combine ARM64EC code and regular ARM64 code in a single binary file, which can be used both by standard Windows-on-Arm applications and emulated x86_64 ones.&lt;br /&gt;
&lt;br /&gt;
The following pages serve as a good reference: &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi &lt;br /&gt;
&lt;br /&gt;
https://gitlab.winehq.org/wine/wine/-/wikis/ARM64EC-Toolchain&lt;br /&gt;
&lt;br /&gt;
Of note is the fact that FEX needs to run in a very reduced Windows environment - due to how early it is loaded it can only depend on ntdll and not say the system CRT. This is worked around by implementing/stubbing the subset of the CRT/Windows APIs necessary for FEX to run/link purely ontop of ntdll (see Common/Windows/{WinAPI,CRT}).&lt;br /&gt;
&lt;br /&gt;
=== Building problems ===&lt;br /&gt;
==== `bytes of instructions in range, but .seh directives corresponding to` ====&lt;br /&gt;
This is seemingly caused by the `-mcpu` tune option, pass to cmake `-DTUNE_CPU=none`&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1369</id>
		<title>Development:ARM64EC</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1369"/>
		<updated>2025-06-27T08:19:10Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
=== Building ===&lt;br /&gt;
These instructions expect you to be building on an ARM64 host. &lt;br /&gt;
&lt;br /&gt;
==== Toolchain ====&lt;br /&gt;
Scripts and instructions to build an ARM64EC toolchain can be found [https://github.com/bylaws/llvm-mingw here], with prebuilt binaries for ARM64/x86 hosts on the [https://github.com/bylaws/llvm-mingw/releases/tag/20240929 releases page]. Once built/downloaded, add it to your environment with &lt;br /&gt;
 export PATH=&amp;quot;&amp;lt;path to toolchain&amp;gt;/bin:$PATH&amp;quot;&lt;br /&gt;
note the toolchain must come before all other path entries as it needs to override the host ar binary.&lt;br /&gt;
* Make sure to grab the tar.gz aarch64 files when compiling on Linux. The zip files are for a Windows toolchain which doesn't work for these instructions.&lt;br /&gt;
&lt;br /&gt;
==== Wine ====&lt;br /&gt;
[https://gitlab.winehq.org/wine/wine Upstream] wine has various things missing for full FEX/ARM64EC support, while it can be used, [https://github.com/bylaws/wine/tree/upstream-arm64ec my fork] will give the best results for now. Make sure to install the deps listed [https://salsa.debian.org/wine-team/wine/-/blob/debian/9.0_repack-4/debian/control.in?ref_type=tags#L13 here] before building with the ARM64EC toolchain.&lt;br /&gt;
&lt;br /&gt;
  ./configure --enable-archs=arm64ec,aarch64,i386 --prefix=/usr --with-mingw=clang --disable-tests&lt;br /&gt;
  make -j$(nproc)&lt;br /&gt;
  sudo --preserve-env=PATH make install -j$(nproc)&lt;br /&gt;
&lt;br /&gt;
==== FEX ====&lt;br /&gt;
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)&lt;br /&gt;
&lt;br /&gt;
FEX's official [https://launchpad.net/~fex-emu/+archive/ubuntu/fex Ubuntu PPA] now provides a fex-emu-wine package of the latest release. This package can be downloaded and the DLL files can be extracted if compiling isn't desired.&lt;br /&gt;
&lt;br /&gt;
===== Build directions =====&lt;br /&gt;
 mkdir build-arm64ec&lt;br /&gt;
 cd build-arm64ec&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
 mkdir build-wow64&lt;br /&gt;
 cd build-wow64&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
==== dxvk/vkd3d-proton ====&lt;br /&gt;
&lt;br /&gt;
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file: &lt;br /&gt;
 [binaries]&lt;br /&gt;
 ar = 'arm64ec-w64-mingw32-ar'&lt;br /&gt;
 c = 'arm64ec-w64-mingw32-gcc'&lt;br /&gt;
 cpp = 'arm64ec-w64-mingw32-g++'&lt;br /&gt;
 ld = 'arm64ec-w64-mingw32-ld'&lt;br /&gt;
 windres = 'arm64ec-w64-mingw32-windres'&lt;br /&gt;
 strip = 'strip'&lt;br /&gt;
 widl = 'arm64ec-w64-mingw32-widl'&lt;br /&gt;
 pkgconfig = 'aarch64-linux-gnu-pkg-config'&lt;br /&gt;
 [host_machine]&lt;br /&gt;
 system = 'windows'&lt;br /&gt;
 cpu_family = 'aarch64'&lt;br /&gt;
 cpu = 'aarch64'&lt;br /&gt;
 endian = 'little'&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
ARM64EC FEX is usable as a drop-in replacement for xtajit64 on native WOA, build FEX with -DUSE_PDB_DEBUGINFO=True and copy the libarm64ecfex.{dll,pdb} binaries into C:/Windows/System32. To actually use FEX create an empty registry key at HKLM\\Software\\Microsoft\\Wow64\\amd64 and set its value to libarm64ecfex.dll, all subsequently launched programs will then use FEX. Logs/configuration is stored in %localappdata%.&lt;br /&gt;
&lt;br /&gt;
=== Info ===&lt;br /&gt;
Unlike Linux FEX, the Windows FEX modules purely handle CPU emulation, with syscall translation being done on either the wine side (WOW64) or ABI (ARM64EC). This is similarly the case for wine's unixcalls and as a result native ARM64 variants can be used for all .so libraries (Vulkan, wine, etc.) dropping the need for an x86 rootfs and FEX-side thunking. &lt;br /&gt;
&lt;br /&gt;
WOW64 is the mechanism to run 32-bit applications on 64-bit platforms: Almost all Windows system libraries are emulated from their original x86 builds here. Only {unix,sys}calls are adapted on-the-fly by injecting thunks. For developers, Microsoft distributes native ARM64 builds of the system libraries as well, but that isn't a concern for FEX.&lt;br /&gt;
&lt;br /&gt;
ARM64EC on the other hand deals with 64-bit applications and avoids emulation overhead by using a dedicated set of system libraries compiled for ARM64 with a custom ABI. This ARM64EC ABI is designed to be callable from recompiled x86_64 code, so that application binaries can use the non-emulated system libraries directly. To ease application porting, Microsoft extended the PE format (&amp;quot;ARM64X&amp;quot;) to combine ARM64EC code with regular ARM64 code in a single binary file (leveraging linker relocations for function prologues/epilogues to avoid duplicating any code). This extension allows a single set of system libraries to be used both for native ARM64 applications and for emulated x86 ones, without needing to distribute any of the original x86 system libraries at all.&lt;br /&gt;
&lt;br /&gt;
The following pages serve as a good reference: &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi &lt;br /&gt;
&lt;br /&gt;
https://gitlab.winehq.org/wine/wine/-/wikis/ARM64EC-Toolchain&lt;br /&gt;
&lt;br /&gt;
Of note is the fact that FEX needs to run in a very reduced Windows environment - due to how early it is loaded it can only depend on ntdll and not say the system CRT. This is worked around by implementing/stubbing the subset of the CRT/Windows APIs necessary for FEX to run/link purely ontop of ntdll (see Common/Windows/{WinAPI,CRT}).&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Configuring_FEX&amp;diff=1200</id>
		<title>Development:Configuring FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Configuring_FEX&amp;diff=1200"/>
		<updated>2025-02-16T17:02:43Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuration via GUI ==&lt;br /&gt;
&lt;br /&gt;
The FEXConfig tool provides a graphical user interface to edit FEX configuration. On first use, it will load default settings and save them to .fex-emu/Config.json.&lt;br /&gt;
&lt;br /&gt;
=== Setup Rootfs ===&lt;br /&gt;
The ''General'' tab in FEXConfig contains the rootfs configuration.&lt;br /&gt;
* Named RootFS folders option shows RootFS installed in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
** sqsh files and folders are selectable here&lt;br /&gt;
* Selecting an option in the Named RootFS option will set the name in RootFS&lt;br /&gt;
** If your x86 RootFS is in an absolute folder elsewhere, you can place the absolute path in the RootFS option&lt;br /&gt;
&lt;br /&gt;
== Manual Configuration ==&lt;br /&gt;
The FEX main configuration file lives at $HOME/.fex-emu/Config.json&lt;br /&gt;
* or $XDG_CONFIG_HOME/.fex-emu/Config.json if you use XDG).&lt;br /&gt;
&lt;br /&gt;
This is a JSON file that holds all of our settings.&lt;br /&gt;
The basic structure is as follows:&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;Config&amp;quot;: {&lt;br /&gt;
            &amp;quot;Threads&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;MaxInst&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
            &amp;quot;RootFS&amp;quot;: &amp;quot;Ubuntu_21_10&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
There are a fair number of configuration options to tinker with. You can see a full suite of configuration option in the FEX man pages.&lt;br /&gt;
* man FEX - To see the options&lt;br /&gt;
** Under the ENVIRONMENT section there is each option's ENVIRONMENT override&lt;br /&gt;
** Additionally each option has a &amp;quot;JSON key&amp;quot; name that shows the Key inside of the Config.json file&lt;br /&gt;
** Every option is a string inside of the config and will be reinterpreted to their programmatic type at load&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1199</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=1199"/>
		<updated>2025-02-16T16:57:14Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Build instructions =&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* pkg-config&lt;br /&gt;
* libclang-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* Development packages for thunked libraries:&lt;br /&gt;
** libdrm-dev&lt;br /&gt;
** libxcb-present-dev&lt;br /&gt;
** libxcb-dri2-0-dev&lt;br /&gt;
** libxcb-dri3-dev&lt;br /&gt;
** libxcb-glx0-dev&lt;br /&gt;
** libxcb-shm0-dev&lt;br /&gt;
** libxshmfence-dev&lt;br /&gt;
&lt;br /&gt;
=== Fedora dependencies ===&lt;br /&gt;
* libXext-devel&lt;br /&gt;
* libXfixes-devel&lt;br /&gt;
* libXrender-devel&lt;br /&gt;
* libXrandr-devel&lt;br /&gt;
* alsa-lib-devel&lt;br /&gt;
* libxcb-devel&lt;br /&gt;
* libxshmfence-devel&lt;br /&gt;
* libdrm-devel&lt;br /&gt;
* xorg-x11-server-devel&lt;br /&gt;
&lt;br /&gt;
== Setting CMake to build thunks ==&lt;br /&gt;
Pass in to CMake the option to enable thunk building.&lt;br /&gt;
* -DBUILD_THUNKS=True&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
FEXConfig can be used to enable/disable individual libraries.&lt;br /&gt;
&lt;br /&gt;
= Advanced configuration =&lt;br /&gt;
== FEX thunk options ==&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
== How to use Thunks ==&lt;br /&gt;
You can can set the three configuration options to custom paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
&lt;br /&gt;
== Thunks Database format ==&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''&lt;br /&gt;
&lt;br /&gt;
The user can also provide a '''$HOME/.fex-emu/ThunksDB.json''' which will overlay the system installed path&lt;br /&gt;
&lt;br /&gt;
This allows the user to configure the thunk file mapping once, since it is unlikely to change between applications. The user can also mix and match ThunksDB and regular thunks configuration if a complex configuration is necessary.&lt;br /&gt;
&lt;br /&gt;
* ThunksDB.json example&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Look at the FEX provided library for a real implementation, or just use the provided configuration.&lt;br /&gt;
&lt;br /&gt;
Once the user has a viable ThunksDB provided, now configure FEX with a ThunkConfig filepath with the application thunk configuration.&lt;br /&gt;
&lt;br /&gt;
This thunks configuration file can now enable Thunk definitions using the user defined names.&lt;br /&gt;
&lt;br /&gt;
== Per-app overrides ==&lt;br /&gt;
* Filename in '''$HOME/.fex-emu/AppConfig/Balatro.exe.json'''&lt;br /&gt;
* Change the filename as necessary for your application&lt;br /&gt;
&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan&amp;quot;: 1&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Further notes =&lt;br /&gt;
== Limitations and problems ==&lt;br /&gt;
* For 32-bit applications, libGL is the only library that can use the host variant currently&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1192</id>
		<title>Development:ARM64EC</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:ARM64EC&amp;diff=1192"/>
		<updated>2025-02-02T16:39:06Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
=== Building ===&lt;br /&gt;
These instructions expect you to be building on an ARM64 host. &lt;br /&gt;
&lt;br /&gt;
==== Toolchain ====&lt;br /&gt;
Scripts and instructions to build an ARM64EC toolchain can be found [https://github.com/bylaws/llvm-mingw here], with prebuilt binaries for ARM64/x86 hosts on the [https://github.com/bylaws/llvm-mingw/releases/tag/20240929 releases page]. Once built/downloaded, add it to your environment with &lt;br /&gt;
 export PATH=&amp;quot;&amp;lt;path to toolchain&amp;gt;/bin:$PATH&amp;quot;&lt;br /&gt;
note the toolchain must come before all other path entries as it needs to override the host ar binary.&lt;br /&gt;
* Make sure to grab the tar.gz aarch64 files when compiling on Linux. The zip files are for a Windows toolchain which doesn't work for these instructions.&lt;br /&gt;
&lt;br /&gt;
==== Wine ====&lt;br /&gt;
[https://gitlab.winehq.org/wine/wine Upstream] wine has various things missing for full FEX/ARM64EC support, while it can be used, [https://github.com/bylaws/wine/tree/upstream-arm64ec my fork] will give the best results for now. Make sure to install the deps listed [https://salsa.debian.org/wine-team/wine/-/blob/debian/9.0_repack-4/debian/control.in?ref_type=tags#L13 here] before building with the ARM64EC toolchain.&lt;br /&gt;
&lt;br /&gt;
  ./configure --enable-archs=arm64ec,aarch64,i386 --with-mingw=clang --disable-tests&lt;br /&gt;
  make -j$(nproc)&lt;br /&gt;
  sudo --preserve-env=PATH make install -j$(nproc)&lt;br /&gt;
&lt;br /&gt;
If using FEX from the ppa then make sure to append '''--prefix=/usr''' to the wine configure commands. Both FEX and Wine's prefix need to match if they are to find each other!&lt;br /&gt;
&lt;br /&gt;
==== FEX ====&lt;br /&gt;
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)&lt;br /&gt;
&lt;br /&gt;
FEX's official [https://launchpad.net/~fex-emu/+archive/ubuntu/fex Ubuntu PPA] now provides a fex-emu-wine package of the latest release. This package can be downloaded and the DLL files can be extracted if compiling isn't desired.&lt;br /&gt;
&lt;br /&gt;
===== Build directions =====&lt;br /&gt;
 mkdir build-arm64ec&lt;br /&gt;
 cd build-arm64ec&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=&amp;lt;desire build type&amp;gt; -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False &amp;lt;path to fex&amp;gt;&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
 mkdir build-wow64&lt;br /&gt;
 cd build-wow64&lt;br /&gt;
 cmake -GNinja -DCMAKE_BUILD_TYPE=&amp;lt;desire build type&amp;gt; -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 -DBUILD_TESTS=False -DENABLE_JEMALLOC_GLIBC_ALLOC=False &amp;lt;path to fex&amp;gt;&lt;br /&gt;
 ninja&lt;br /&gt;
 sudo ninja install&lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
==== dxvk/vkd3d-proton ====&lt;br /&gt;
&lt;br /&gt;
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file: &lt;br /&gt;
 [binaries]&lt;br /&gt;
 ar = 'arm64ec-w64-mingw32-ar'&lt;br /&gt;
 c = 'arm64ec-w64-mingw32-gcc'&lt;br /&gt;
 cpp = 'arm64ec-w64-mingw32-g++'&lt;br /&gt;
 ld = 'arm64ec-w64-mingw32-ld'&lt;br /&gt;
 windres = 'arm64ec-w64-mingw32-windres'&lt;br /&gt;
 strip = 'strip'&lt;br /&gt;
 widl = 'arm64ec-w64-mingw32-widl'&lt;br /&gt;
 pkgconfig = 'aarch64-linux-gnu-pkg-config'&lt;br /&gt;
 [host_machine]&lt;br /&gt;
 system = 'windows'&lt;br /&gt;
 cpu_family = 'aarch64'&lt;br /&gt;
 cpu = 'aarch64'&lt;br /&gt;
 endian = 'little'&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
ARM64EC FEX is usable as a drop-in replacement for xtajit64 on native WOA, build FEX with -DUSE_PDB_DEBUGINFO=True and copy the libarm64ecfex.{dll,pdb} binaries into C:/Windows/System32. To actually use FEX create an empty registry key at HKLM\\Software\\Microsoft\\Wow64\\amd64 and set its value to libarm64ecfex.dll, all subsequently launched programs will then use FEX. Logs/configuration is stored in %localappdata%.&lt;br /&gt;
&lt;br /&gt;
=== Info ===&lt;br /&gt;
Unlike Linux FEX, the Windows FEX modules purely handle CPU emulation, with syscall translation being done on either the wine side (WOW64) or ABI (ARM64EC). This is similarly the case for wine's unixcalls and as a result native ARM64 variants can be used for all .so libraries (Vulkan, wine, etc.) dropping the need for an x86 rootfs and FEX-side thunking. &lt;br /&gt;
&lt;br /&gt;
WOW64 is fairly simple, every DLL is compiled with both x86 and ARM64 variants and in an x86 process only the x86 variants are loaded (with ARM64 FEX and ntdll) the only thunking done is for {unix,sys}calls so almost all Windows code is emulated. &lt;br /&gt;
&lt;br /&gt;
ARM64EC on the otherhand avoids duplicating DLLs at all, instead choosing to introduce a new ARM64 ABI allowing for transparent compiler-aided interop with any existing x86_64 code. The following pages serve as a good introduction: &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec &lt;br /&gt;
&lt;br /&gt;
https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi &lt;br /&gt;
&lt;br /&gt;
https://gitlab.winehq.org/wine/wine/-/wikis/ARM64EC-Toolchain&lt;br /&gt;
&lt;br /&gt;
Of note is the fact that FEX needs to run in a very reduced Windows environment - due to how early it is loaded it can only depend on ntdll and not say the system CRT. This is worked around by implementing/stubbing the subset of the CRT/Windows APIs necessary for FEX to run/link purely ontop of ntdll (see Common/Windows/{WinAPI,CRT}).&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=683</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=683"/>
		<updated>2022-09-15T08:17:34Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add standard library dependencies for cross-compiling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* pkg-config&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libsdl2-dev (For GUI)&lt;br /&gt;
* libepoxy-dev (For GUI)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* squashfuse (For mounting the squashfs)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
* gcc-multilib (For FEXLinuxTests)&lt;br /&gt;
* g++-multilib (For FEXLinuxTests)&lt;br /&gt;
* libc6-dev-i386-amd64-cross (For FEXLinuxTests)&lt;br /&gt;
* lib32stdc++-XX-dev-amd64-cross (For FEXLinuxTests, version should match your g++-x86-64-linux-gnu package)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* libsdl2&lt;br /&gt;
* libepoxy&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable test building&lt;br /&gt;
* Enable LTO in a release build&lt;br /&gt;
* Enable LLD to make LTO builds faster&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DENABLE_LTO=True -DENABLE_LLD=True -DBUILD_TESTS=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
=== On AArch64 hosts ===&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then I don't recommend installing FEX's until it is useful.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc_32&lt;br /&gt;
  sudo ninja binfmt_misc_64&lt;br /&gt;
&lt;br /&gt;
'''binfmt_misc problems'''&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTRL+SHIFT+O will open default &amp;quot;global&amp;quot; configuration.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves it.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
* Multiblock: enabled (Can cause more stuttering)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions [[Development:Configuring_FEX|here]]&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications&lt;br /&gt;
Follow the instructions [[Development:Setting_up_RootFS]]&lt;br /&gt;
&lt;br /&gt;
== Installing Thunks ==&lt;br /&gt;
Only if you want&lt;br /&gt;
&lt;br /&gt;
Follow the instructions [[Development:Setting_up_Thunks|here]]&lt;br /&gt;
&lt;br /&gt;
Additional details here: https://github.com/FEX-Emu/FEX/blob/main/ThunkLibs/README.md&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXLoader&lt;br /&gt;
** This is useful for development purposes but is generally recommended against using.&lt;br /&gt;
** Allows passing arguments to FEX for configuration purposes, which can break under some execve situations&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a hardlink to FEXLoader which refuses to treat arguments as configuration options&lt;br /&gt;
** Is recommended to use over FEXLoader; Using FEXConfig to set configuration&lt;br /&gt;
** Requires being a hardlink or executable copy, execve logic sees through a softlink&lt;br /&gt;
** Is the executable used for binfmt_misc for interpreters&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for setting configuration options from a GUI&lt;br /&gt;
** Written using Dear ImGui&lt;br /&gt;
** Can load/save global configuration and application configuration files&lt;br /&gt;
** Application configuration files are compared against the executable filename&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Jupiter_Hell&amp;diff=623</id>
		<title>Jupiter Hell</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Jupiter_Hell&amp;diff=623"/>
		<updated>2022-07-09T09:07:53Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Mention workaround for Vulkan thunks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox&lt;br /&gt;
|steamappid      = 811320&lt;br /&gt;
|os              = Linux&lt;br /&gt;
|engine          = U1nique&lt;br /&gt;
|arch            = x86-64&lt;br /&gt;
|cpufeats        = Unknown&lt;br /&gt;
|compat          = Playable&lt;br /&gt;
|apptype         = Game&lt;br /&gt;
|renderapi       = Vulkan&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Steps to Run ==&lt;br /&gt;
'''No special instructions'''&lt;br /&gt;
&lt;br /&gt;
== Quirks ==&lt;br /&gt;
&lt;br /&gt;
== Problems/Workarounds ==&lt;br /&gt;
== Supported Thunks ==&lt;br /&gt;
== Unsupported Thunks ==&lt;br /&gt;
  Vulkan&lt;br /&gt;
Ships its own libvulkan loader, resulting in Vulkan thunking not working. As a workaround, removing libvulkan.so.1 from the game folder allows Vulkan thunks to operate properly.&lt;br /&gt;
&lt;br /&gt;
== Testing Results ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Copy the below and paste it above testing/end, then fill it out. Please don't delete any existing data. Revision is the githash. Arch should be formatted as x86-32, x86-64, ARM.--&amp;gt;&lt;br /&gt;
&amp;lt;!-- {{testing/entry|revision=|archtitle=|archhost=|result=|tester=}} --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{testing/start}}&lt;br /&gt;
{{testing/entry|revision=FEX-2207|archtitle=x86-64|archhost=AArch64|result=Game runs|tester=Sonicadvance1}}&lt;br /&gt;
{{testing/end}}&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=449</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=449"/>
		<updated>2022-06-22T14:00:55Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Build instructions =&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* pkg-config&lt;br /&gt;
* libclang-dev&lt;br /&gt;
* libssl-dev&lt;br /&gt;
* Development packages for thunked libraries:&lt;br /&gt;
** libdrm-dev&lt;br /&gt;
** libxcb-present-dev&lt;br /&gt;
** libxcb-dri2-0-dev&lt;br /&gt;
** libxcb-dri3-dev&lt;br /&gt;
** libxcb-glx0-dev&lt;br /&gt;
** libxcb-shm0-dev&lt;br /&gt;
** libxshmfence-dev&lt;br /&gt;
** libvulkan-dev &lt;br /&gt;
&lt;br /&gt;
== Setting CMake to build thunks ==&lt;br /&gt;
Pass in to CMake the option to enable thunk building.&lt;br /&gt;
* -DBUILD_THUNKS=True&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
== FEX thunk options ==&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
== How to use Thunks ==&lt;br /&gt;
Once Thunks are built and installed then you can can set the three configuration options to the correct paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
* Setting the global application profile for '''ThunkConfig''' is useful for testing but not recommended for long term use&lt;br /&gt;
** Due to the unstable nature of thunks, it is recommended to use application specific profiles to enable thunks&lt;br /&gt;
** This allows the user to test applications first using the global config, then once confirmed it works, generating an application profile&lt;br /&gt;
** Recommended to reduce the application profile to the minimum set of options. FEXConfig will save a full config.&lt;br /&gt;
&lt;br /&gt;
== Thunks Database format ==&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''&lt;br /&gt;
&lt;br /&gt;
The user can also provide a '''$HOME/.fex-emu/ThunksDB.json''' which will overlay the system installed path&lt;br /&gt;
&lt;br /&gt;
This allows the user to configure the thunk file mapping once, since it is unlikely to change between applications. The user can also mix and match ThunksDB and regular thunks configuration if a complex configuration is necessary.&lt;br /&gt;
&lt;br /&gt;
* ThunksDB.json example&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Look at the FEX provided library for a real implementation, or just use the provided configuration.&lt;br /&gt;
&lt;br /&gt;
Once the user has a viable ThunksDB provided, now configure FEX with a ThunkConfig filepath with the application thunk configuration.&lt;br /&gt;
&lt;br /&gt;
This thunks configuration file can now enable Thunk definitions using the user defined names.&lt;br /&gt;
&lt;br /&gt;
* ThunkConfig example&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri2&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri3&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;X11&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-xfixes&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-shm&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-sync&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-randr&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-present&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-glx&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xshmfence&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;drm&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xrender&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xext&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xfixes&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Vulkan-lavapipe&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-radeon&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-freedreno&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-intel&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-panfrost&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-virtio&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;asound&amp;quot;: 0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Further notes =&lt;br /&gt;
== Limitations and problems ==&lt;br /&gt;
* 32-bit thunks aren't available currently&lt;br /&gt;
** Requires kernel patches for ARM64 support&lt;br /&gt;
* Thunks aren't fully stable. Expect missing symbols and crashes.&lt;br /&gt;
&lt;br /&gt;
== Legacy ThunkConfig example ==&lt;br /&gt;
'''This is legacy path and not recommended.'''&lt;br /&gt;
&lt;br /&gt;
This is just an example for how one could lay out the thunks.&lt;br /&gt;
* Save this to a file somewhere and point '''ThunkConfig''' option to it&lt;br /&gt;
** '''$HOME/.fex-emu/ThunkConfigs/''' isn't a bad choice for consistency.&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;thunks&amp;quot;: {&lt;br /&gt;
    &amp;quot;libGL-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libasound-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;],&lt;br /&gt;
    &amp;quot;libX11-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXrender-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libXext-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXfixes-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Configuring_FEX&amp;diff=448</id>
		<title>Development:Configuring FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Configuring_FEX&amp;diff=448"/>
		<updated>2022-06-22T13:49:19Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== FEXConfig configuration ==&lt;br /&gt;
'''To be filled'''&lt;br /&gt;
* File-&amp;gt; Load Default Options&lt;br /&gt;
** Only do this one time to fill the default Config.json&lt;br /&gt;
** File-&amp;gt; Save to save this to .fex-emu/Config.json&lt;br /&gt;
* File-&amp;gt; Open Default&lt;br /&gt;
** Opens the .fex-emu/Config.json file&lt;br /&gt;
&lt;br /&gt;
=== Setup Rootfs ===&lt;br /&gt;
Emulation tab in FEXConfig contains the rootfs configuration.&lt;br /&gt;
* Named RootFS folders option shows RootFS installed in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
** sqsh files and folders are selectable here&lt;br /&gt;
* Selecting an option in the Named RootFS option will set the name in RootFS&lt;br /&gt;
** If your x86 RootFS is in an absolute folder elsewhere, you can place the absolute path in the RootFS option&lt;br /&gt;
&lt;br /&gt;
== Manual Configuration ==&lt;br /&gt;
The FEX main configuration file lives at $HOME/.fex-emu/Config.json&lt;br /&gt;
* or $XDG_CONFIG_HOME/.fex-emu/Config.json if you use XDG).&lt;br /&gt;
&lt;br /&gt;
This is a JSON file that holds all of our settings.&lt;br /&gt;
The basic structure is as follows:&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;Config&amp;quot;: {&lt;br /&gt;
            &amp;quot;Threads&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;MaxInst&amp;quot;: &amp;quot;500&amp;quot;,&lt;br /&gt;
            &amp;quot;RootFS&amp;quot;: &amp;quot;Ubuntu_21_10&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
There are a fair number of configuration options to tinker with. You can see a full suite of configuration option in the FEX man pages.&lt;br /&gt;
* man FEX - To see the options&lt;br /&gt;
** Under the ENVIRONMENT section there is each option's ENVIRONMENT override&lt;br /&gt;
** Additionally each option has a &amp;quot;JSON key&amp;quot; name that shows the Key inside of the Config.json file&lt;br /&gt;
** Every option is a string inside of the config and will be reinterpreted to their programmatic type at load&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:StructPackVerifier&amp;diff=447</id>
		<title>Development:StructPackVerifier</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:StructPackVerifier&amp;diff=447"/>
		<updated>2022-06-22T13:46:34Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Struct packing verifier ==&lt;br /&gt;
The struct packing verifier python script allows us to validate struct packings match between aliases and architectures.&lt;br /&gt;
This is necessary to ensure auto generated structs match across architectures and handwritten structs match the original architecture's struct.&lt;br /&gt;
&lt;br /&gt;
== Struct annotations ==&lt;br /&gt;
The verifier tool looks for structures and unions with specifically crafted annotations to only check the ones we care about.&lt;br /&gt;
&lt;br /&gt;
`__attribute__((annotate(&amp;quot;alias-&amp;lt;arch&amp;gt;-&amp;lt;struct name&amp;gt;&amp;quot;)))`&lt;br /&gt;
* Where arch can be x86_32, x86_64, aarch64, win32, win64&lt;br /&gt;
* Struct name is the original structure name that the struct to should alias to&lt;br /&gt;
* eg `__attribute__((annotate(&amp;quot;alias-x86_32-rusage&amp;quot;)))`&lt;br /&gt;
&lt;br /&gt;
`__attribute__((annotate(&amp;quot;fex-match&amp;quot;)))`&lt;br /&gt;
* If a struct should be compared across architectures then we use this to ensure it matches&lt;br /&gt;
* FEX will compare that the struct matches between x86-64 and aarch64 for compatibility&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
* python3&lt;br /&gt;
* python3-clang&lt;br /&gt;
* clang (required to find default include paths)&lt;br /&gt;
* Multilib packages&lt;br /&gt;
** 32bit Linux&lt;br /&gt;
*** libc6-dev-i386-cross&lt;br /&gt;
*** libstdc++6-i386-cross&lt;br /&gt;
*** libstdc++-10-dev-i386-cross  &lt;br /&gt;
*** linux-libc-dev-i386-cross&lt;br /&gt;
** 64bit Linux&lt;br /&gt;
*** libc6-dev&lt;br /&gt;
*** linux-libc-dev&lt;br /&gt;
*** libc6-dev-amd64-cross&lt;br /&gt;
*** linux-libc-dev-amd64-cross&lt;br /&gt;
*** libstdc++6-amd64-cross&lt;br /&gt;
*** libstdc++-10-dev-amd64-cross&lt;br /&gt;
** AArch64 Linux&lt;br /&gt;
*** libc6-dev-arm64-cross&lt;br /&gt;
*** linux-libc-dev-arm64-cross&lt;br /&gt;
*** libstdc++6-arm64-cross&lt;br /&gt;
*** libstdc++-10-dev-arm64-cross&lt;br /&gt;
** Mingw for Windows&lt;br /&gt;
*** g++-mingw-w64-x86-64&lt;br /&gt;
*** g++-mingw-w64-x86-64-win32&lt;br /&gt;
*** g++-mingw-w64-x86-64-posix&lt;br /&gt;
*** g++-mingw-w64-i686&lt;br /&gt;
*** g++-mingw-w64-i686-win32&lt;br /&gt;
*** g++-mingw-w64-i686-posix&lt;br /&gt;
&lt;br /&gt;
== Getting a result ==&lt;br /&gt;
If the arguments are passed in to the tool correctly then it will return 0 if everything matches, else it returns 1 if something hasn't matched.&lt;br /&gt;
You'll then get logging output to compare against&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
The libclang python implementation might not be all encompassing of definitions. So one should be careful to only throw basic struct and union types at the tooling.&lt;br /&gt;
Ideally only POD types should be compared with the expectation that structs will be crossing architecture boundaries and need to match.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=446</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=446"/>
		<updated>2022-06-22T13:42:24Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build Dependencies ==&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* '''Development libraries for various thunks'''&lt;br /&gt;
* libdrm-dev&lt;br /&gt;
* libxcb-present-dev&lt;br /&gt;
* libxcb-dri2-0-dev&lt;br /&gt;
* libxcb-dri3-dev&lt;br /&gt;
* libxcb-glx0-dev&lt;br /&gt;
* libxcb-shm0-dev&lt;br /&gt;
* libxshmfence-dev&lt;br /&gt;
* libvulkan-dev &lt;br /&gt;
&lt;br /&gt;
== Building vulkan-docs if your host is too old ==&lt;br /&gt;
If you're host's libvulkan-dev is too old, which is highly likely then you'll need to install a new set of vulkan headers&lt;br /&gt;
&lt;br /&gt;
* git clone https://github.com/KhronosGroup/Vulkan-Headers.git&lt;br /&gt;
* cd Vulkan-Headers&lt;br /&gt;
* mkdir Build&lt;br /&gt;
* cd Build&lt;br /&gt;
* cmake -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
* sudo make install&lt;br /&gt;
&lt;br /&gt;
== Setting cmake to build thunks ==&lt;br /&gt;
Pass in to cmake the option to enable thunk building.&lt;br /&gt;
* -DBUILD_THUNKS=True&lt;br /&gt;
&lt;br /&gt;
== FEX thunk options ==&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
== How to use Thunks ==&lt;br /&gt;
Once Thunks are built and installed then you can can set the three configuration options to the correct paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
* Setting the global application profile for '''ThunkConfig''' is useful for testing but not recommended for long term use&lt;br /&gt;
** Due to the unstable nature of thunks, it is recommended to use application specific profiles to enable thunks&lt;br /&gt;
** This allows the user to test applications first using the global config, then once confirmed it works, generating an application profile&lt;br /&gt;
** Recommended to reduce the application profile to the minimum set of options. FEXConfig will save a full config.&lt;br /&gt;
&lt;br /&gt;
== Thunks Database format ==&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''&lt;br /&gt;
&lt;br /&gt;
The user can also provide a '''$HOME/.fex-emu/ThunksDB.json''' which will overlay the system installed path&lt;br /&gt;
&lt;br /&gt;
This allows the user to configure the thunk file mapping once, since it is unlikely to change between applications. The user can also mix and match ThunksDB and regular thunks configuration if a complex configuration is necessary.&lt;br /&gt;
&lt;br /&gt;
* ThunksDB.json example&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Look at the FEX provided library for a real implementation, or just use the provided configuration.&lt;br /&gt;
&lt;br /&gt;
Once the user has a viable ThunksDB provided, now configure FEX with a ThunkConfig filepath with the application thunk configuration.&lt;br /&gt;
&lt;br /&gt;
This thunks configuration file can now enable Thunk definitions using the user defined names.&lt;br /&gt;
&lt;br /&gt;
* ThunkConfig example&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri2&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri3&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;X11&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-xfixes&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-shm&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-sync&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-randr&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-present&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-glx&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xshmfence&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;drm&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xrender&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xext&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xfixes&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Vulkan-lavapipe&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-radeon&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-freedreno&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-intel&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-panfrost&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-virtio&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;asound&amp;quot;: 0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Limitations and problems ==&lt;br /&gt;
* 32-bit thunks aren't available currently&lt;br /&gt;
** Requires kernel patches for ARM64 support&lt;br /&gt;
* Thunks aren't fully stable. Expect missing symbols and crashes.&lt;br /&gt;
&lt;br /&gt;
== Legacy ThunkConfig example ==&lt;br /&gt;
'''This is legacy path and not recommended.'''&lt;br /&gt;
&lt;br /&gt;
This is just an example for how one could lay out the thunks.&lt;br /&gt;
* Save this to a file somewhere and point '''ThunkConfig''' option to it&lt;br /&gt;
** '''$HOME/.fex-emu/ThunkConfigs/''' isn't a bad choice for consistency.&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;thunks&amp;quot;: {&lt;br /&gt;
    &amp;quot;libGL-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libasound-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;],&lt;br /&gt;
    &amp;quot;libX11-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXrender-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libXext-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXfixes-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=445</id>
		<title>Development:Setting up RootFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=445"/>
		<updated>2022-06-22T13:42:17Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Setting up a RootFS =&lt;br /&gt;
'''For AArch64 hosts you are required to have an x86-64 rootfs'''. With or without 32bit compatibility libraries.&lt;br /&gt;
&lt;br /&gt;
This isn't strictly required for testing on x86-64 host environments but is useful for ensuring correct behaviour there.&lt;br /&gt;
&lt;br /&gt;
= Quick Setup with FEXRootFSFetch =&lt;br /&gt;
FEX comes with a FEXRootFSFetcher tool that can download an official preconfigured rootfs from the FEX servers.&lt;br /&gt;
This tool operates as either a terminal application or a Zenity application depending on if it is launched from terminal or not.&lt;br /&gt;
&lt;br /&gt;
This tool will walk you through selecting a RootFS for FEX:&lt;br /&gt;
* If your host OS matches one in the download list then it will recommend that one&lt;br /&gt;
* After selecting the RootFS, it will download it&lt;br /&gt;
** This downloads to the default location in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
* After downloading the RootFS the tool will ask if you want to use the SquashFS file directly or extract it&lt;br /&gt;
* It will then ask if you want to set the downloaded RootFS as your default&lt;br /&gt;
** This writes to the default configuration in '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
You can skip the rest of the guide if you used FEXRootFSFetcher to download the rootfs.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
* The squashfs image will fail to extract if you don't have unsquashfs installed&lt;br /&gt;
** Install the squashfs-tools package to get this application&lt;br /&gt;
&lt;br /&gt;
* '''SquashFS RootFS file corrupted?'''&lt;br /&gt;
** Rerun the tool, select the rootfs from the list, and if the rootfs already exists it will ask to verify&lt;br /&gt;
** If verification fails it will ask if you want to redownload&lt;br /&gt;
* '''Want to manually check the hash?'''&lt;br /&gt;
** Run the rootfs file directly through the tool to get a hash&lt;br /&gt;
** '''FEXRootFSFetcher $HOME/.fex-emu/RootFS/Ubuntu_21_10.sqsh'''&lt;br /&gt;
** Ubuntu_21_10.sqsh has hash: bf9507fbdbaec2cf&lt;br /&gt;
* '''Want to use the Zenity UI but still launch through terminal?'''&lt;br /&gt;
** Force Zenity from terminal with '''FEXRootFSFetcher 1&amp;gt; /dev/null'''&lt;br /&gt;
* '''What if my Linux distro isn't listed?'''&lt;br /&gt;
** Don't worry, select one that is most similar to yours or newest&lt;br /&gt;
** This will work in most cases&lt;br /&gt;
* '''How can I trust these images?'''&lt;br /&gt;
** These images are generated by scripts living in our public repo&lt;br /&gt;
** If you want to rebuild them yourself, you are free to do so.&lt;br /&gt;
** https://github.com/FEX-Emu/RootFS&lt;br /&gt;
* '''I want to add a distro'''&lt;br /&gt;
** Follow how our current rootfs is generated and add your own&lt;br /&gt;
** Open a pull request to add the rootfs setup&lt;br /&gt;
** Contact us on the official FEX-Emu Discord to get the RootFS added to the server.&lt;br /&gt;
* '''Where is the raw list of images at?'''&lt;br /&gt;
** The image links live on our website at the following link&lt;br /&gt;
** https://rootfs.fex-emu.org/file/fex-rootfs/RootFS_links_XXH3.txt&lt;br /&gt;
** This file is in a format that our tool understands&lt;br /&gt;
** Generally the format is:&lt;br /&gt;
*** Distro Name&lt;br /&gt;
*** Distro Version&lt;br /&gt;
*** Human readable name&lt;br /&gt;
*** Raw rootfs link&lt;br /&gt;
*** xxhash based file hash&lt;br /&gt;
&lt;br /&gt;
= Making a custom rootfs prerequisites =&lt;br /&gt;
An x86-64 PC or FEX-Emu installed for chrooting&lt;br /&gt;
&lt;br /&gt;
= Getting Started =&lt;br /&gt;
The easiest way to get started is to just download a prebuilt x86-64 rootfs from your favourite distribution and extract it to where you want.&lt;br /&gt;
* Ubuntu - http://cdimage.ubuntu.com/ubuntu-base/releases/&lt;br /&gt;
* Debian Debootstrap guide - https://wiki.debian.org/Debootstrap&lt;br /&gt;
** Debootstrap is more involved and not explained here.&lt;br /&gt;
&lt;br /&gt;
Using chroot you can then enter the rootfs and install applications that you desire for testing purposes.&lt;br /&gt;
It's easiest to set this up on an x86-64 host and then copy it to an AArch64 device.&lt;br /&gt;
&lt;br /&gt;
== Cross architecture chroot ==&lt;br /&gt;
'''You need to have binfmt_misc setup for x86-64 support on your host system.'''&lt;br /&gt;
* ls /proc/sys/fs/binfmt_misc &lt;br /&gt;
** If there are files in this folder then your host supports binfmt_misc&lt;br /&gt;
* Once you have binfmt_misc running and FEX-Emu installed in to it, you can chroot in to an x86-64 rootfs&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to rootfs with FEX-Emu Rootfs ==&lt;br /&gt;
* If you're using a FEX-Emu provided rootfs then we provide two scripts at the start to handle this&lt;br /&gt;
** '''unbreak_chroot.sh''' - This sets up the rootfs and chroots inside of it&lt;br /&gt;
** '''break_chroot.sh''' - This sets up the rootfs for using with FEX generally.&lt;br /&gt;
*** '''Make sure to run this after leaving the chroot!'''&lt;br /&gt;
** The remaining steps in this guide can be skipped&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to custom rootfs with FEX-Emu ==&lt;br /&gt;
* If you're setting up your own rootfs then you need to follow the binding steps that are following.&lt;br /&gt;
** We have a script that if you know what you're doing you can cherry pick parts from [https://github.com/FEX-Emu/RootFS/blob/main/unbreak_chroot.sh here]&lt;br /&gt;
&lt;br /&gt;
= Additional TmpFS folders =&lt;br /&gt;
Depending on what you're doing in the chroot, you may need or want some tmpfs folders that applications are expecting&lt;br /&gt;
&lt;br /&gt;
* sudo mount -t proc /proc ${ROOTFS}/proc/&lt;br /&gt;
* sudo mount --rbind --make-rslave /sys ${ROOTFS}/sys/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev ${ROOTFS}/dev/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev/pts ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo mount --rbind /lib/ld-linux-aarch64.so.1 ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo mount --rbind /lib/aarch64-linux-gnu ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
Then of course, make sure to unmount these partitions when you're done&lt;br /&gt;
&lt;br /&gt;
* sudo umount ${ROOTFS}/proc/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/sys/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
= Using the rootfs with FEX =&lt;br /&gt;
If you're using FEXLoader then you can pass the full path of the rootfs with the -R option.&lt;br /&gt;
Additionally you can put the rootfs folder inside of $HOME/.fex-emu/RootFS/&amp;lt;RootFS name&amp;gt;/ and FEX supports a &amp;quot;named&amp;quot; rootfs option&lt;br /&gt;
* eq: -R Ubuntu_2104 will use rootfs $HOME/.fex-emu/RootfS/Ubuntu_2104&lt;br /&gt;
* Read the Fex man page with man fex for more information&lt;br /&gt;
&lt;br /&gt;
== Setting RootFS with FEXConfig ==&lt;br /&gt;
[[File:FEXConfig Load Default.png|frameless|Load the default options on first run]]&lt;br /&gt;
On the first run of FEXConfig, select the &amp;quot;Load Default Options&amp;quot; configuration.&lt;br /&gt;
* Subsequent runs should select &amp;quot;Open Default&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[File:FEXConfig RootFS Selection.png|frameless|Select the RootFS from the FEXConfig location]]&lt;br /&gt;
&lt;br /&gt;
FEXConfig will autopopulate the rootfs list with rootfs folders that exist in $HOME/.fex-emu/RootFS/&lt;br /&gt;
&lt;br /&gt;
You can select one from the list or provide a full path in the RootFS: line to set it manually.&lt;br /&gt;
&lt;br /&gt;
''' Make sure to select the File-&amp;gt;Save option after the fact to save'''&lt;br /&gt;
&lt;br /&gt;
= Additional Steps for building a custom rootfs = &lt;br /&gt;
== Running under WSL1 ==&lt;br /&gt;
/etc/hosts and /etc/resolv.conf change on the host side. You'll need to copy those over to the rootfs if you want network functionality to work.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu packages to install ==&lt;br /&gt;
Sample packages to install in the rootfs&lt;br /&gt;
* apt-get install pulseaudio libgles1 libgles2 libglx-mesa0 libgl1-mesa-dri libgl1-mesa-glx mesa-utils mesa-utils-extra&lt;br /&gt;
Pulseaudio specifically is required so pulseaudio will work when talking to the host pulseaudio&lt;br /&gt;
&lt;br /&gt;
== File deletion ==&lt;br /&gt;
Some files need to be deleted from the rootfs otherwise some applications will fail to work.&lt;br /&gt;
&lt;br /&gt;
Note that deleting these files '''WILL''' break the rootfs and you won't be able to chroot in to it anymore.&lt;br /&gt;
&lt;br /&gt;
A likely better route would be a script that moves these files and folders then brings them back when you want to chroot&lt;br /&gt;
&lt;br /&gt;
=== Files to remove ===&lt;br /&gt;
* ${ROOTFS}/etc/hosts&lt;br /&gt;
* ${ROOTFS}/etc/resolv.conf&lt;br /&gt;
* ${ROOTFS}/etc/timezone&lt;br /&gt;
* ${ROOTFS}/etc/localtime&lt;br /&gt;
* ${ROOTFS}/etc/passwd&lt;br /&gt;
&lt;br /&gt;
=== Folders to remove ===&lt;br /&gt;
* ${ROOTFS}/boot&lt;br /&gt;
* ${ROOTFS}/dev&lt;br /&gt;
* ${ROOTFS}/home&lt;br /&gt;
* ${ROOTFS}/media&lt;br /&gt;
* ${ROOTFS}/mnt&lt;br /&gt;
* ${ROOTFS}/proc&lt;br /&gt;
* ${ROOTFS}/root&lt;br /&gt;
* ${ROOTFS}/srv&lt;br /&gt;
* ${ROOTFS}/tmp&lt;br /&gt;
* ${ROOTFS}/var/cache/apt&lt;br /&gt;
* ${ROOTFS}/var/lib/apt&lt;br /&gt;
* ${ROOTFS}/sys&lt;br /&gt;
* ${ROOTFS}/opt&lt;br /&gt;
&lt;br /&gt;
== Creating a Squashfs rootfs from custom rootfs ==&lt;br /&gt;
SquashFS is a great way to do binary distribution of the rootfs. If you have created a rootfs and you want to roll it in to a squashfs like the FEX-Emu provided images then this is information on how to do that.&lt;br /&gt;
&lt;br /&gt;
'''SquashFS is currently only recommended for binary distribution. User should unpack it to not get dangling processes and mounts.'''&lt;br /&gt;
* Offers tooling to mount in userspace&lt;br /&gt;
* Supports ZSTD compression&lt;br /&gt;
* Is a readonly partition that matches FEX's use case&lt;br /&gt;
&lt;br /&gt;
=== Tools that FEX needs to run squashfs ===&lt;br /&gt;
* squashfuse&lt;br /&gt;
* fusermount&lt;br /&gt;
&lt;br /&gt;
=== Making the squashfs image ===&lt;br /&gt;
Making the squashfs image is very straightforward&lt;br /&gt;
* mksquashfs ${ROOTFS}/ Squashfs.sqsh -comp zstd&lt;br /&gt;
&lt;br /&gt;
This creates a file called Squashfs.sqsh that contains the original rootfs that we generated above.&lt;br /&gt;
&lt;br /&gt;
=== Using the squashfs image in FEX ===&lt;br /&gt;
* Copy the resulting sqsh file in to ${XDG_DATA_HOME}/.fex-emu/RootFS/&lt;br /&gt;
** If ${XDG_DATA_HOME} doesn't exist then that will be replaced with ${HOME}&lt;br /&gt;
* Use FEXConfig to select the sqsh file as a named rootfs&lt;br /&gt;
* or pass the name in to the FEX_ROOTFS argument in the various ways FEX supports&lt;br /&gt;
* or the absolute path if you don't want it in the FEX RootFS folder&lt;br /&gt;
&lt;br /&gt;
=== Extracting the squashfs ===&lt;br /&gt;
If you don't want to use squashfs for whatever reason then you can extract it in to the FEX RootFS folder and use the directory directly&lt;br /&gt;
* unsquashfs -f -d NewRootFS/ Squashfs.sqsh&lt;br /&gt;
&lt;br /&gt;
=== If you want to install packages in the squashfs ===&lt;br /&gt;
The squashfs image is immutable and can't be modified.&lt;br /&gt;
* Extract the squashfs first&lt;br /&gt;
* Change the working directory to the rootfs&lt;br /&gt;
* execute `unbreak_chroot.sh`&lt;br /&gt;
* `apt-get update`&lt;br /&gt;
* `apt-get install &amp;lt;Whatever you want&amp;gt;`&lt;br /&gt;
* `exit` to leave the chroot&lt;br /&gt;
* `break_chroot.sh`&lt;br /&gt;
* Use the new extracted chroot directly, or follow the previous steps to recompress it to a squashfs format.&lt;br /&gt;
&lt;br /&gt;
=== Known problems with squashfs ===&lt;br /&gt;
'''FEX automatically mounts your squashfs file and can leave dangling squashfs mounts around in some instances.'''&lt;br /&gt;
* '''This is fairly rare but it can occur. Whenever an instance of FEX is run, it registers with the FEXMountDaemon'''&lt;br /&gt;
** FEXMountDaemon then watches these instances of FEX to ensure they have exited before unmounting&lt;br /&gt;
** There is roughly a ten second grace period of no instances of FEX running before unmounting&lt;br /&gt;
** If an instance of FEX starts running then it will reuse the mount partition and reset the timeout&lt;br /&gt;
* To get rid of these dangling mounts if they do manage to manifest, use the following commands&lt;br /&gt;
** fusermount -u /tmp/.FEXMount* ; rmdir /tmp/.FEXMount*&lt;br /&gt;
** These don't require root to unmount&lt;br /&gt;
* In some cases the unmounting can end up returning busy status and not unmount&lt;br /&gt;
** Check the output of `mount` for any /tmp/.FEXMount folders&lt;br /&gt;
** This is due to either FEXMountDaemon or squashfuse still running in the background&lt;br /&gt;
** Can force the application to exit&lt;br /&gt;
** step 1: kill `pidof squashfuse`&lt;br /&gt;
** This will attempt to send SIGTERM to all squashfuse applications, which will unmount the partition on terminate&lt;br /&gt;
** Failing that, you can try to be more abusive&lt;br /&gt;
** kill -9 `pidof FEXMountDaemon`&lt;br /&gt;
** This will forcibly terminate FEXMountDaemon which should also take out the child mounted process&lt;br /&gt;
* If any instances of the mount still exists then you may need to kill more FEX processes.&lt;br /&gt;
** Any FEXInterpreter process will end up keeping the folder mounted and keep it busy&lt;br /&gt;
&lt;br /&gt;
'''strace breaks squashfs'''&lt;br /&gt;
* If you run FEX with `strace -f` then the process that mounts your rootfs loses its setuid bit.&lt;br /&gt;
** This means you then can't mount the rootFS&lt;br /&gt;
* The only workaround is to not use a squashfs in this instance.&lt;br /&gt;
* Alternatively you can spin up a FEXBash instance to force squashfs to be mounted. Then strace a different FEX instance which will use the mounted squashfs location.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=444</id>
		<title>Development:Setting up FEX</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_FEX&amp;diff=444"/>
		<updated>2022-06-22T13:42:11Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Build dependencies ==&lt;br /&gt;
* git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja-build&lt;br /&gt;
* ccache (Recommended if you're rebuilding constantly)&lt;br /&gt;
* clang&lt;br /&gt;
* lld (For ThinLTO)&lt;br /&gt;
* binfmt-support (For AArch64 binfmt_misc support)&lt;br /&gt;
* libsdl2-dev (For GUI)&lt;br /&gt;
* libepoxy-dev (For GUI)&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* nasm (only if building tests)&lt;br /&gt;
* python3-clang (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-i386-cross (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-amd64-cross (for struct verifier)&lt;br /&gt;
* libstdc++-10-dev-arm64-cross (for struct verifier)&lt;br /&gt;
* squashfs-tools (For squashfs rootfs support)&lt;br /&gt;
* libc-bin or glibc-tools (For unittests, needs catchsegv from this)&lt;br /&gt;
&lt;br /&gt;
=== Gentoo dependencies ===&lt;br /&gt;
* dev-vcs/git&lt;br /&gt;
* cmake&lt;br /&gt;
* ninja&lt;br /&gt;
* ccache&lt;br /&gt;
* clang&lt;br /&gt;
* lld&lt;br /&gt;
* libsdl2&lt;br /&gt;
* libepoxy&lt;br /&gt;
* nasm&lt;br /&gt;
&lt;br /&gt;
'''Use gubbins'''&lt;br /&gt;
* &amp;gt;=media-libs/libglvnd-1.3.4 X&lt;br /&gt;
== Build Configuration ==&lt;br /&gt;
* Ensure release mode is enabled&lt;br /&gt;
* Disable static pie&lt;br /&gt;
** Bug with glibc means static-pie needs to be disabled for thunks to work.&lt;br /&gt;
** This is necessary for chroot and pressure-vessel, but is currently incompatible with thunks&lt;br /&gt;
** If using LLD then you need at least LLD 13.0&lt;br /&gt;
** If using LLD then you need at least glibc 2.35&lt;br /&gt;
** Recommendation: '''Disable LLD, use binutils ld'''&lt;br /&gt;
* Enable LTO - '''Currently bugged in some configurations''' &lt;br /&gt;
** Disable if enabling static-pie&lt;br /&gt;
* Disable test building&lt;br /&gt;
&lt;br /&gt;
  git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git&lt;br /&gt;
  cd FEX&lt;br /&gt;
  mkdir Build&lt;br /&gt;
  cd Build&lt;br /&gt;
  CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DENABLE_LTO=False -DENABLE_STATIC_PIE=False -DBUILD_TESTS=False -DENABLE_ASSERTIONS=False -G Ninja ..&lt;br /&gt;
  ninja&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
  sudo ninja install&lt;br /&gt;
&lt;br /&gt;
=== On AArch64 hosts ===&lt;br /&gt;
You can install a binfmt_misc handler for both 32bit and 64bit x86 execution directly from the environment.&lt;br /&gt;
If you already have box86's 32bit binfmt_misc handler installed then I don't recommend installing FEX's until it is useful.&lt;br /&gt;
Make sure to have run install prior to this, otherwise binfmt_misc will install an old handler even if the executable has been updated.&lt;br /&gt;
&lt;br /&gt;
  sudo ninja binfmt_misc_32&lt;br /&gt;
  sudo ninja binfmt_misc_64&lt;br /&gt;
&lt;br /&gt;
'''binfmt_misc problems'''&lt;br /&gt;
* Double check that binfmt_misc has worked&lt;br /&gt;
** `ls /usr/share/binfmts/FEX*` should return files&lt;br /&gt;
** `ls /var/lib/binfmts/FEX*` should return files&lt;br /&gt;
** `/proc/sys/fs/binfmt_misc/status` should exist&lt;br /&gt;
*** If it doesn't exist then make sure your kernel has `CONFIG_BINFMT_MISC=y`&lt;br /&gt;
*** If it still doesn't exist then make sure systemd isn't disabling it `systemctl enable binfmt-support`&lt;br /&gt;
&lt;br /&gt;
== Runtime Configuration ==&lt;br /&gt;
FEXConfig is the application to use for runtime configuration setup.&lt;br /&gt;
&lt;br /&gt;
CTRL+SHIFT+O will open default &amp;quot;global&amp;quot; configuration.&lt;br /&gt;
&lt;br /&gt;
CTLR+S saves it.&lt;br /&gt;
&lt;br /&gt;
=== Things to ensure to set ===&lt;br /&gt;
On AArch64 host, a rootfs path is mandatory, while it is optional on x86-64 host&lt;br /&gt;
&lt;br /&gt;
* Core: JIT&lt;br /&gt;
* RootFS&lt;br /&gt;
* Silent Logging (Useful to get FEX information spam out of the way)&lt;br /&gt;
* Block Size (500 is a good default. Optimization passes may break things though)&lt;br /&gt;
* Multiblock: enabled (Can cause more stuttering)&lt;br /&gt;
&lt;br /&gt;
More Details at: Follow the instructions here https://wiki.fex-emu.org/index.php/Development:Configuring_FEX&lt;br /&gt;
== RootFS generation ==&lt;br /&gt;
AArch64 hosts require a rootfs for running applications&lt;br /&gt;
Follow the instructions here https://wiki.fex-emu.org/index.php/Development:Setting_up_RootFS&lt;br /&gt;
&lt;br /&gt;
== Installing Thunks ==&lt;br /&gt;
Only if you want&lt;br /&gt;
&lt;br /&gt;
Follow the instructions here: https://wiki.fex-emu.org/index.php/Development:Setting_up_Thunks&lt;br /&gt;
&lt;br /&gt;
Additional details here: https://github.com/FEX-Emu/FEX/blob/main/ThunkLibs/README.md&lt;br /&gt;
&lt;br /&gt;
== Binaries ==&lt;br /&gt;
* FEXLoader&lt;br /&gt;
** This is useful for development purposes but is generally recommended against using.&lt;br /&gt;
** Allows passing arguments to FEX for configuration purposes, which can break under some execve situations&lt;br /&gt;
* FEXInterpreter&lt;br /&gt;
** This is a hardlink to FEXLoader which refuses to treat arguments as configuration options&lt;br /&gt;
** Is recommended to use over FEXLoader; Using FEXConfig to set configuration&lt;br /&gt;
** Requires being a hardlink or executable copy, execve logic sees through a softlink&lt;br /&gt;
** Is the executable used for binfmt_misc for interpreters&lt;br /&gt;
* FEXConfig&lt;br /&gt;
** Used for setting configuration options from a GUI&lt;br /&gt;
** Written using Dear ImGui&lt;br /&gt;
** Can load/save global configuration and application configuration files&lt;br /&gt;
** Application configuration files are compared against the executable filename&lt;br /&gt;
* FEXBash&lt;br /&gt;
** Can be useful for starting a bash instance that is running under emulation&lt;br /&gt;
** It's not a chroot! Don't use sudo inside of this environment!&lt;br /&gt;
* FEXMountDaemon&lt;br /&gt;
** This is a mount daemon that will run in the background when you are using a squashfs based rootfs&lt;br /&gt;
** Usually one one instance open at any given moment&lt;br /&gt;
** It usually closes when the FEXInterpreter exits, but not always. See the problems section in setting up a rootfs&lt;br /&gt;
*** Has a ten second timeout window in case a another instance of FEX opens and uses it.&lt;br /&gt;
&lt;br /&gt;
=== Debug binaries ===&lt;br /&gt;
* TestHarnessRunner&lt;br /&gt;
** Used for running FEX's ASM unit tests&lt;br /&gt;
** Runs some binary in a host x86_64 host environment or FEX and checks results&lt;br /&gt;
** Useful for quickly creating ASM based unit tests&lt;br /&gt;
* IRLoader&lt;br /&gt;
** Used for running FEX's IR based unit tests&lt;br /&gt;
** Only runs through FEX and checks the results&lt;br /&gt;
** Minimal number of tests&lt;br /&gt;
* UnitTestGenerator&lt;br /&gt;
** This is supposed to be an x86-64 instruction generator&lt;br /&gt;
** Has an understanding of x86-64 instruction encoding format&lt;br /&gt;
** Generates hundreds of thousands of instructions&lt;br /&gt;
** Used to be used with a lockstep runner to ensure correct behaviour&lt;br /&gt;
** Largely unsupported, avoiding undefined behaviour is difficult and FEX doesn't need to match undefined behaviour&lt;br /&gt;
** Lockstep hostrunner wasn't ever made to be bug free, hard to support&lt;br /&gt;
** Doesn't ensure correct behaviour on AArch64 device&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Renderdoc&amp;diff=443</id>
		<title>Development:Renderdoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Renderdoc&amp;diff=443"/>
		<updated>2022-06-22T13:42:05Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Getting a capture =&lt;br /&gt;
== Without Thunks ==&lt;br /&gt;
* Ensure Renderdoc is installed in the rootfs&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
* Set LD_PRELOAD=librenderdoc.so as an environment variable&lt;br /&gt;
* This can be done in FEXConfig or an application profile to limit its reach&lt;br /&gt;
&lt;br /&gt;
=== Vulkan ===&lt;br /&gt;
* Ensure the renderdoc layer is installed&lt;br /&gt;
* Set ENABLE_VULKAN_RENDERDOC_CAPTURE=1 as an environment variable&lt;br /&gt;
* This can be done in FEXConfig or an application profile to limit its reach&lt;br /&gt;
&lt;br /&gt;
=== Alternatively ===&lt;br /&gt;
You can use renderdoccmd to launch an application directly.&lt;br /&gt;
* renderdoccmd capture -w &amp;lt;program&amp;gt; &amp;lt;args...&amp;gt;&lt;br /&gt;
As long as this application is installed in your rootfs then it should work for both OpenGL and Vulkan applications.&lt;br /&gt;
&lt;br /&gt;
=== Capture results ===&lt;br /&gt;
* Once you have captured a frame in an application running renderdoc (F12 typically)&lt;br /&gt;
* The results will be in /tmp/RenderDoc/ as *.rdc files&lt;br /&gt;
* Technically these are meant to be moved over to the qrenderdoc application but you can rip them directly&lt;br /&gt;
&lt;br /&gt;
== With Thunks ==&lt;br /&gt;
Likely to be the same as without thunks, but instead of adding environment variables inside of FEX. One needs to do it outside of FEX instead&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:gfxreconstruct&amp;diff=442</id>
		<title>Development:gfxreconstruct</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:gfxreconstruct&amp;diff=442"/>
		<updated>2022-06-22T13:42:00Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= gfxreconstruct =&lt;br /&gt;
gfxreconstruct is a Vulkan layer that is useful for capturing a frame in a robust way.&lt;br /&gt;
&lt;br /&gt;
This is usually useful for capturing frames that is more portable than renderdoc.&lt;br /&gt;
&lt;br /&gt;
https://github.com/LunarG/gfxreconstruct&lt;br /&gt;
&lt;br /&gt;
= Setting up gfxreconstruct =&lt;br /&gt;
First thing you must do is build gfxreconstruct from source. Either for your host or guest rootfs, depending on if you're using thunks or not.&lt;br /&gt;
&lt;br /&gt;
If building for the x86 rootfs then make sure to install it in to the rootfs after building. This can be done by just copying the install files over afterwards.&lt;br /&gt;
&lt;br /&gt;
== Set up environment variables ==&lt;br /&gt;
* VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_gfxreconstruct&lt;br /&gt;
* GFXRECON_CAPTURE_TRIGGER=F12&lt;br /&gt;
* GFXRECON_CAPTURE_FILE=/tmp/gfxrecon_capture.gfxr&lt;br /&gt;
&lt;br /&gt;
Once you have the environment variables set up you can then launch a vulkan game. There will be some additional output in the terminal to know when the layer is capturing. You can then press F12 in the application and you'll get a capture in tmp after a few seconds. Be careful as gfxreconstruct will overwrite the capture on each press, so you will want to move each capture file.&lt;br /&gt;
&lt;br /&gt;
== Replay ==&lt;br /&gt;
gfxrecon-replay can be used to replay the capture which is quite useful.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_FEX_with_Signals&amp;diff=441</id>
		<title>Development:Debugging FEX with Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_FEX_with_Signals&amp;diff=441"/>
		<updated>2022-06-22T13:41:52Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
= Signals and you =&lt;br /&gt;
&lt;br /&gt;
FEX uses signals in quite a few ways that may cause debugging to be a bit of a pain. This is necessary for correct operation so it is an evil we must live with.&lt;br /&gt;
&lt;br /&gt;
== Signals that FEX uses ==&lt;br /&gt;
* SIGBUS - The AArch64 JIT generates unaligned loadstore instructions then captures and backpatches these when they fault&lt;br /&gt;
** This is necessary for emulating x86-TSO on AArch64 and can't be dropped without massive performance loses&lt;br /&gt;
* SIGILL - All of the CPU backends generate this fault and is necessary for the emulator to return from a guest signal&lt;br /&gt;
** Going in to a signal happens frequently, gdb will usually ignore the entry when it is SIGALRM or SIGUSR*&lt;br /&gt;
** We could choose a different signal, but this one can be generated in one instruction which makes it nice to use&lt;br /&gt;
** Using a signal to punch back through to the guest return path is necessary since we need to save and restore guest registers when guest signals occur.&lt;br /&gt;
* SIG63 - We use this for various ancillary functions&lt;br /&gt;
** This signal currently tells a thread that it should stop running, to pause its execution, or to resume from its paused frame&lt;br /&gt;
** This is another necessary signal since if we want to safely shutdown the emulator and a thread is in a syscall, there is no way for it to leave without a signal.&lt;br /&gt;
** The stop signal specifically will have the CPU backend long jump from the signal handler to the exit stage of the ASM dispatcher for safe shutdown&lt;br /&gt;
** This slightly increases performance because then there aren't atomic checks per iteration of the execution loop for if we should stop executing&lt;br /&gt;
&lt;br /&gt;
= Debugging FEX =&lt;br /&gt;
Read more here [[Development:Debugging_Crash]]&lt;br /&gt;
&lt;br /&gt;
= Profiling FEX code =&lt;br /&gt;
You'll want to enable a style of JIT code mark-up for perf to annotate with&lt;br /&gt;
* FEX currently has three options for this&lt;br /&gt;
* Depending on what you're trying to profile you will want to enable one of these options&lt;br /&gt;
** FEX_GLOBALJITNAMING&lt;br /&gt;
*** Useful if you want to throw all of FEX JIT space in to a global-ish namespace&lt;br /&gt;
** FEX_LIBRARYJITNAMING&lt;br /&gt;
*** Useful if you want to clump FEX JIT space in to library specific code segments&lt;br /&gt;
*** Can be nice for finding libraries to thunk&lt;br /&gt;
** FEX_BLOCKJITNAMING&lt;br /&gt;
*** This is likely the one you want if you're profiling your application's code&lt;br /&gt;
*** This will give you hot blocks in `perf top`&lt;br /&gt;
&lt;br /&gt;
Enabling one of these will give you some symbols when capturing FEX with `perf top`. The block naming is useful for seeing hot blocks in program space so if something ends up being particularly slow in FEX, it can get more isolated.&lt;br /&gt;
* We don't currently have an option to relate JIT code directly to function symbols in the ELF at this point.&lt;br /&gt;
&lt;br /&gt;
= Debugging the guest application =&lt;br /&gt;
When FEX is started with the -G argument it will open a gdbstub socket listening on port 8086. This can be connected to with gdbserver, ida, ghidra, or binary ninja.&lt;br /&gt;
&lt;br /&gt;
This is currently only useful for inspection, gdbstub doesn't yet send guest signals over through gdbstub!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=440</id>
		<title>Development:Debugging Crash In Thunks</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=440"/>
		<updated>2022-06-22T13:41:44Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Once Thunks are enabled ==&lt;br /&gt;
* Once you've verified your crash is in a thunk then this becomes quite a bit easier&lt;br /&gt;
&lt;br /&gt;
  gdb --args FEXInterpreter /usr/bin/vulkaninfo&lt;br /&gt;
  Thread 1 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  #1  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #2  0x0000007fe25e4028 in ?? ()&lt;br /&gt;
  Backtrace stopped: previous frame inner to this frame (corrupt stack?)&lt;br /&gt;
&lt;br /&gt;
* Okay, that's a direct crash in Turnip, let's rebuild Mesa with a debug build and try again&lt;br /&gt;
  Thread 1 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  1632       memset(ptr, 0x42, 16);&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  #1  0x0000007fc80eab9c in vk_tramp_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at src/vulkan/runtime/vk_dispatch_trampolines.c:78&lt;br /&gt;
  #2  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #3  0x0000007fe25e426c in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay the crash is at.. `tu_device:1632`, let's go and debug that line&lt;br /&gt;
&lt;br /&gt;
  1631    void* ptr = (void*)1;&lt;br /&gt;
  1632    memset(ptr, 0x42, 16);&lt;br /&gt;
&lt;br /&gt;
* Who put that in there?!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=439</id>
		<title>Development:Debugging Crash</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=439"/>
		<updated>2022-06-22T13:41:39Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
* Debug an application with `gdb --args FEXInterpreter &amp;lt;application full path&amp;gt;`&lt;br /&gt;
* Under GDB make sure to do `handle SIGBUS SIGILL SIG63 noprint`&lt;br /&gt;
** We use signals for various things, check out [[Development:Debugging_FEX_with_Signals|Here]] for more information&lt;br /&gt;
&lt;br /&gt;
== Crash in emulated/JIT code ==&lt;br /&gt;
Walking through debugging a simple test application that is crashing.&lt;br /&gt;
  $ gdb --args FEXInterpreter ./sigsegv_test&lt;br /&gt;
  Reading symbols from FEXInterpreter...&lt;br /&gt;
  (gdb) r&lt;br /&gt;
  Starting program: /usr/bin/FEXInterpreter ./sigsegv_test&lt;br /&gt;
  [Thread debugging using libthread_db enabled]&lt;br /&gt;
  Using host libthread_db library &amp;quot;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;quot;.&lt;br /&gt;
  [New Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  &lt;br /&gt;
  Thread 2 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  [Switching to Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  0x0000007fccfb9ec8 in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay, we have a sigsegv. Let's double check that it is JIT code (aka, guest emulated code)&lt;br /&gt;
  (gdb) disas $pc,+32&lt;br /&gt;
  Dump of assembler code from 0x7fe26ebc20 to 0x7fe26ebc40:&lt;br /&gt;
  =&amp;gt; 0x0000007fe26ebc20:  stlrb   w22, [x21]&lt;br /&gt;
     0x0000007fe26ebc24:  mov     x4, #0x0                        // #0&lt;br /&gt;
     0x0000007fe26ebc28:  ldr     x10, [x20]&lt;br /&gt;
     0x0000007fe26ebc2c:  add     x21, x20, #0x8&lt;br /&gt;
     0x0000007fe26ebc30:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc34:  strb    w22, [x28, #428]&lt;br /&gt;
     0x0000007fe26ebc38:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc3c:  strb    w22, [x28, #431]&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb) info reg x9&lt;br /&gt;
  x9             0x0                 0&lt;br /&gt;
* Looks like JIT code, even doing accesses to x28 which is the FEX CPU state&lt;br /&gt;
* Code has no backtrace which reinforces this&lt;br /&gt;
* Code is doing an atomic store, which reinforces this is FEX emulating the x86 TSO memory model&lt;br /&gt;
&lt;br /&gt;
* Now that we have checked that we are in the JIT code. Where are we in the guest side?&lt;br /&gt;
* Let's dump the FEX CPU state information that is directly pointed to in x28 at all times in JIT code.&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State&lt;br /&gt;
  $3 = {rip = 0x401110, gregs = {0x416eb0, 0x7fe1e3b640, 0xffffffffffffff70, 0x0, 0x7fe1e3bf30, 0x0, 0x416eb0, 0x7fe1e3ae28, 0x0, 0x7fe1e3b640, 0x8, 0x7fe2054cc0, 0x7ff75ff48e, 0x7ff75ff48f, 0x0, 0x7fe163b000}, xmm = {{0x0, 0x0}, {0x0, 0x0}, {0xdeadbeef, 0xbad0dad1} &amp;lt;repeats 14 times&amp;gt;}, es = 0x0, cs = 0x0, ss = 0x0, ds = 0x0, gs = 0x0, fs = 0x7fe1e3b640, flags = {0x0, 0x1, 0x0,&lt;br /&gt;
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 &amp;lt;repeats 38 times&amp;gt;}, mm = {{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}}, gdt = {{base = 0x0} &amp;lt;repeats 32 times&amp;gt;}, FCW = 0x37f, FTW = 0xffff}&lt;br /&gt;
&lt;br /&gt;
* Looks like our guest RIP is currently `0x401110`&lt;br /&gt;
** Consult the `info proc mappings` again&lt;br /&gt;
  0x401000           0x402000     0x1000     0x1000 {...}/sigsegv_test&lt;br /&gt;
* Yep, we are inside our test application&lt;br /&gt;
* For a simple test, let's load the application in gdb-multiarch and disassemble where we are&lt;br /&gt;
  $ gdb-multiarch ./sigsegv_test&lt;br /&gt;
  Reading symbols from ./sigsegv_test...&lt;br /&gt;
  (gdb) set disassembly-flavor intel&lt;br /&gt;
  (gdb) disas 0x401110&lt;br /&gt;
  Dump of assembler code for function main(int, char**):&lt;br /&gt;
     0x0000000000401110 &amp;lt;+0&amp;gt;:     push   rbp&lt;br /&gt;
     0x0000000000401111 &amp;lt;+1&amp;gt;:     mov    rbp,rsp&lt;br /&gt;
     0x0000000000401114 &amp;lt;+4&amp;gt;:     mov    DWORD PTR [rbp-0x4],0x0&lt;br /&gt;
     0x000000000040111b &amp;lt;+11&amp;gt;:    mov    DWORD PTR [rbp-0x8],edi&lt;br /&gt;
     0x000000000040111e &amp;lt;+14&amp;gt;:    mov    QWORD PTR [rbp-0x10],rsi&lt;br /&gt;
     0x0000000000401122 &amp;lt;+18&amp;gt;:    mov    rax,QWORD PTR [rbp-0x10]&lt;br /&gt;
     0x0000000000401126 &amp;lt;+22&amp;gt;:    movsxd rcx,DWORD PTR [rbp-0x8]&lt;br /&gt;
     0x000000000040112a &amp;lt;+26&amp;gt;:    mov    rax,QWORD PTR [rax+rcx*8]&lt;br /&gt;
     0x000000000040112e &amp;lt;+30&amp;gt;:    mov    QWORD PTR [rbp-0x18],rax&lt;br /&gt;
     0x0000000000401132 &amp;lt;+34&amp;gt;:    mov    rax,QWORD PTR [rbp-0x18]&lt;br /&gt;
     0x0000000000401136 &amp;lt;+38&amp;gt;:    mov    BYTE PTR [rax],0x63&lt;br /&gt;
     0x0000000000401139 &amp;lt;+41&amp;gt;:    xor    eax,eax&lt;br /&gt;
     0x000000000040113b &amp;lt;+43&amp;gt;:    pop    rbp&lt;br /&gt;
     0x000000000040113c &amp;lt;+44&amp;gt;:    ret&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb)&lt;br /&gt;
&lt;br /&gt;
* Okay, not super helpful since FEX translates instructions in to blocks, `0x401110` is just our starting address&lt;br /&gt;
** It's in this code somewhere, let's change some FEX settings to get a clearer picture&lt;br /&gt;
* Set block size to one instruction and disable multiblock&lt;br /&gt;
** See the image in FEXConfig to the right&lt;br /&gt;
[[File:FEXConfig 1Inst NoMulti.png|thumb]]&lt;br /&gt;
* Now rerun our test application and find the new RIP&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State.rip&lt;br /&gt;
  $2 = 0x401136&lt;br /&gt;
&lt;br /&gt;
* Alright, now we know the RIP is exactly at `0x401136`&lt;br /&gt;
* Back in gdb-multiarch&lt;br /&gt;
  (gdb) disas 0x401136,+1&lt;br /&gt;
  Dump of assembler code from 0x401136 to 0x401137:&lt;br /&gt;
     0x0000000000401136 &amp;lt;main(int, char**)+38&amp;gt;:   mov    BYTE PTR [rax],0x63&lt;br /&gt;
&lt;br /&gt;
* Looks like something in main is storing 0x63 to a nullptr&lt;br /&gt;
* In this simple case we can now take a look at the test application's source and find the problem.&lt;br /&gt;
** We know the problem is in the first block of main()&lt;br /&gt;
** We know the exact instruction that it is at&lt;br /&gt;
** We know it's something storing a byte to memory&lt;br /&gt;
* For more complex cases it is likely necessary to use reverse engineering tools&lt;br /&gt;
** BinaryNinja, Ghidra, IDA, and Hopper are all examples of tools like this&lt;br /&gt;
&lt;br /&gt;
== What to do from here ==&lt;br /&gt;
Now it becomes a lot harder. You don't get a typical debugging environment or even clean backtraces.&lt;br /&gt;
&lt;br /&gt;
FEX's gdbserver integration is sorely lacking so you can't even use a remote gdb server connecting to FEX right now.&lt;br /&gt;
&lt;br /&gt;
If you enable thunks you can get better backtraces here. [[Development:Debugging_Crash_In_Thunks|Debugging_Crash_In_Thunks]]&lt;br /&gt;
&lt;br /&gt;
== Attempting to use FEX-Emu's gdbserver implementation ==&lt;br /&gt;
'''Here be dragons'''&lt;br /&gt;
&lt;br /&gt;
FEX supports gdbserver as an integration. It's implementation is significantly limited but can still be used for debugging and getting some backtraces.&lt;br /&gt;
* Currently hardcodes the port to use as `8086` and if you have multiple gdbserver processes running then it will encounter problems.&lt;br /&gt;
* Currently does not follow processes through fork/execve at all. No multiprocess support&lt;br /&gt;
** This means you '''must''' only start the process you're caring about debugging&lt;br /&gt;
* Currently starts the process paused and will wait until gdb attach before continuing&lt;br /&gt;
** No way to start a FEX instance then attach at some later point&lt;br /&gt;
* Ctrl-C to stop the FEX process needs to be done twice&lt;br /&gt;
** Maybe with a small delay inbetween because gdb needs to fetch a bunch of data on pause&lt;br /&gt;
** Known bug, unknown why broken at the moment&lt;br /&gt;
&lt;br /&gt;
  FEXLoader -G -- &amp;lt;Application&amp;gt; &amp;lt;Args...&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Double checking if we are in JIT code ==&lt;br /&gt;
  (gdb) info reg pc&lt;br /&gt;
  pc             0x7fccfb9ec8        0x7fccfb9ec8&lt;br /&gt;
  &lt;br /&gt;
  (gdb) info proc mappings&lt;br /&gt;
  ...&lt;br /&gt;
  0x7fccfb9000       0x7fcdfb9000  0x1000000        0x0&lt;br /&gt;
&lt;br /&gt;
* Looks like FEX JIT mapping, we start out at 16MB but scale up to 128MB&lt;br /&gt;
* Depending on version of FEX we can check the base mapping for a unique string &lt;br /&gt;
  (gdb) p (char*)0x7fccfb9000&lt;br /&gt;
  $4 = 0x7fccfb9000 &amp;quot;FEXJIT::Arm64JITCore::&amp;quot;&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=438</id>
		<title>Development:Adding Config Options</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=438"/>
		<updated>2022-06-22T13:41:16Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
Configuration options are programatically generated from json.&lt;br /&gt;
&lt;br /&gt;
This file lives in `FEXCore/Source/Interface/Config/Config.json`&lt;br /&gt;
&lt;br /&gt;
= Options section =&lt;br /&gt;
To add a configuration option that can be set from JSON, FEXLoader arguments, or Environment variables you need to add the option to this file.&lt;br /&gt;
&lt;br /&gt;
Currently FEX has six groups to group configs&lt;br /&gt;
* CPU&lt;br /&gt;
* Emulation&lt;br /&gt;
* Debug&lt;br /&gt;
* Logging&lt;br /&gt;
* Hacks&lt;br /&gt;
* Misc&lt;br /&gt;
&lt;br /&gt;
== Configuration option object ==&lt;br /&gt;
Each JSON object under a group becomes a configuration.&lt;br /&gt;
&lt;br /&gt;
'''Object Layout'''&lt;br /&gt;
* Key:&lt;br /&gt;
  * Becomes the C++ enum. eg. 'Multiblock' becomes `FEXCore::Config::ConfigOption::CONFIG_MULTIBLOCK`&lt;br /&gt;
  * Also used for the environment variable. Becomes `FEX_MULTIBLOCK`&lt;br /&gt;
  * Also becomes the FEXLoader argument. Becomes `--multiblock`&lt;br /&gt;
  * If the object type is boolean then a negated argument also is generated. `--no-multiblock`&lt;br /&gt;
&lt;br /&gt;
* ShortArg:&lt;br /&gt;
  * This is the string that is used for FEXLoader short arguments&lt;br /&gt;
  * eg. Multiblock uses m, which turns in to -m in FEXLoader&lt;br /&gt;
&lt;br /&gt;
* Type:&lt;br /&gt;
  * Can be `[bool, uint8, int32, uint32, uint64, str, strarray]`&lt;br /&gt;
  * This is what the argument type ends up being once loaded from a configuration backing&lt;br /&gt;
&lt;br /&gt;
* Default:&lt;br /&gt;
  * Default value that matches this object&lt;br /&gt;
  * Used to generate code so needs to handle being codified. Compilation will fail otherwise&lt;br /&gt;
  * If Type is str or strarray then this string will be automatically wrapped with double-quotes when generated&lt;br /&gt;
&lt;br /&gt;
* TextDefault:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * If the `Default` option which is used in code can't be represented by text. Like an enum being used.&lt;br /&gt;
  * eg. `Core` has a `Default` which is an enum. `TextDefault` is set to `irjit` for the user to handle this case&lt;br /&gt;
&lt;br /&gt;
* Choices:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * Allows us to represent the textual options that a argument can accept&lt;br /&gt;
  * FEXLoader validates that a choice is supported otherwise errors out&lt;br /&gt;
  * eg. `Core` supports `[ &amp;quot;irint&amp;quot;, &amp;quot;irjit&amp;quot;, &amp;quot;host&amp;quot; ]`&lt;br /&gt;
&lt;br /&gt;
* ArgumentHandler:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * If an argument option needs some special handling to be parsed then this points to a C++ function in the argument loader&lt;br /&gt;
  * `Core` uses it to convert the textual representation in to an enum&lt;br /&gt;
  * '''Don't''' use this as a way to modify other configuration options from FEXLoader&lt;br /&gt;
    * Do fix-ups in the ReloadMetaLayer function in FEXCore/Config.cpp instead&lt;br /&gt;
&lt;br /&gt;
* Desc:&lt;br /&gt;
  * Short description of what this option does&lt;br /&gt;
  * This is used to generate the help text with `FEXLoader --help` and also the text in the man pages&lt;br /&gt;
&lt;br /&gt;
== UnnamedOptions section ==&lt;br /&gt;
These are configuration options that can '''NOT''' be set by user means. There won't be any FEXLoader, Environment variable, or json helpers generated to load these.&lt;br /&gt;
&lt;br /&gt;
These need to exist as a way to have internal configuration options existing in the same global space as user options. Allows us to pull internal configuration options the same way as user configurations.&lt;br /&gt;
&lt;br /&gt;
These can exist under any group config. Currently only `Misc` is used. Only three things need to be set for these&lt;br /&gt;
* Key: This is only used to generate the enum in code&lt;br /&gt;
* Type: Same supported types as the regular options&lt;br /&gt;
* Default: The default value of this configuration&lt;br /&gt;
&lt;br /&gt;
== Getting configurations in FEX code ==&lt;br /&gt;
FEX provides a `FEX_CONFIG_OPT` define to help developers get configuration options.&lt;br /&gt;
* FEX_CONFIG_OPT(name, enum)&lt;br /&gt;
  * eg: `FEX_CONFIG_OPT(Cores, THREADS);`&lt;br /&gt;
  * This will load the THREADS configuration option from the configuration directory and save the value in to local value called `Cores`&lt;br /&gt;
* Gotchas:&lt;br /&gt;
  * Construction of the object queries the the global configuration layer. This can be slow so be careful with its use.&lt;br /&gt;
  * Upon construction of the `FEXCore::Config::Value&amp;lt;T&amp;gt;` object it will pull the string configuration&lt;br /&gt;
  * Then it will convert that value in to whatever type the value needs&lt;br /&gt;
  * In high performance code, keep constructor instantiation outside of the hot code path&lt;br /&gt;
  * Construct the configuration inside of a class definition so it only pulls the configuration once&lt;br /&gt;
* Caveats:&lt;br /&gt;
  * If the configuration changes then this doesn't pick up the change&lt;br /&gt;
  * Configuration isn't meant to change live in FEX so this is typically a non-issue&lt;br /&gt;
  * Frontend object loader needs to be careful with its configuration loading to ensure the meta layer stays in sync&lt;br /&gt;
  * ELFLoader.cpp for examples here&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=437</id>
		<title>Development:Adding Config Options</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Adding_Config_Options&amp;diff=437"/>
		<updated>2022-06-22T13:40:25Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
Configuration options are programatically generated from json.&lt;br /&gt;
&lt;br /&gt;
This file lives in `FEXCore/Source/Interface/Config/Config.json`&lt;br /&gt;
&lt;br /&gt;
= Options section =&lt;br /&gt;
To add a configuration option that can be set from JSON, FEXLoader arguments, or Environment variables you need to add the option to this file.&lt;br /&gt;
&lt;br /&gt;
Currently FEX has six groups to group configs&lt;br /&gt;
* CPU&lt;br /&gt;
* Emulation&lt;br /&gt;
* Debug&lt;br /&gt;
* Logging&lt;br /&gt;
* Hacks&lt;br /&gt;
* Misc&lt;br /&gt;
&lt;br /&gt;
== Configuration option object ==&lt;br /&gt;
Each JSON object under a group becomes a configuration.&lt;br /&gt;
&lt;br /&gt;
'''Object Layout'''&lt;br /&gt;
* Key:&lt;br /&gt;
  * Becomes the C++ enum. eg. 'Multiblock' becomes `FEXCore::Config::ConfigOption::CONFIG_MULTIBLOCK`&lt;br /&gt;
  * Also used for the environment variable. Becomes `FEX_MULTIBLOCK`&lt;br /&gt;
  * Also becomes the FEXLoader argument. Becomes `--multiblock`&lt;br /&gt;
  * If the object type is boolean then a negated argument also is generated. `--no-multiblock`&lt;br /&gt;
&lt;br /&gt;
* ShortArg:&lt;br /&gt;
  * This is the string that is used for FEXLoader short arguments&lt;br /&gt;
  * eg. Multiblock uses m, which turns in to -m in FEXLoader&lt;br /&gt;
&lt;br /&gt;
* Type:&lt;br /&gt;
  * Can be `[bool, uint8, int32, uint32, uint64, str, strarray]`&lt;br /&gt;
  * This is what the argument type ends up being once loaded from a configuration backing&lt;br /&gt;
&lt;br /&gt;
* Default:&lt;br /&gt;
  * Default value that matches this object&lt;br /&gt;
  * Used to generate code so needs to handle being codified. Compilation will fail otherwise&lt;br /&gt;
  * If Type is str or strarray then this string will be automatically wrapped with double-quotes when generated&lt;br /&gt;
&lt;br /&gt;
* TextDefault:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * If the `Default` option which is used in code can't be represented by text. Like an enum being used.&lt;br /&gt;
  * eg. `Core` has a `Default` which is an enum. `TextDefault` is set to `irjit` for the user to handle this case&lt;br /&gt;
&lt;br /&gt;
* Choices:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * Allows us to represent the textual options that a argument can accept&lt;br /&gt;
  * FEXLoader validates that a choice is supported otherwise errors out&lt;br /&gt;
  * eg. `Core` supports `[ &amp;quot;irint&amp;quot;, &amp;quot;irjit&amp;quot;, &amp;quot;host&amp;quot; ]`&lt;br /&gt;
&lt;br /&gt;
* ArgumentHandler:&lt;br /&gt;
  * Used by FEXLoader argument loading&lt;br /&gt;
  * If an argument option needs some special handling to be parsed then this points to a C++ function in the argument loader&lt;br /&gt;
  * `Core` uses it to convert the textual representation in to an enum&lt;br /&gt;
  * '''Don't''' use this as a way to modify other configuration options from FEXLoader&lt;br /&gt;
    * Do fix-ups in the ReloadMetaLayer function in FEXCore/Config.cpp instead&lt;br /&gt;
&lt;br /&gt;
* Desc:&lt;br /&gt;
  * Short description of what this option does&lt;br /&gt;
  * This is used to generate the help text with `FEXLoader --help` and also the text in the man pages&lt;br /&gt;
&lt;br /&gt;
== UnnamedOptions section ==&lt;br /&gt;
These are configuration options that can '''NOT''' be set by user means. There won't be any FEXLoader, Environment variable, or json helpers generated to load these.&lt;br /&gt;
&lt;br /&gt;
These need to exist as a way to have internal configuration options existing in the same global space as user options. Allows us to pull internal configuration options the same way as user configurations.&lt;br /&gt;
&lt;br /&gt;
These can exist under any group config. Currently only `Misc` is used. Only three things need to be set for these&lt;br /&gt;
* Key: This is only used to generate the enum in code&lt;br /&gt;
* Type: Same supported types as the regular options&lt;br /&gt;
* Default: The default value of this configuration&lt;br /&gt;
&lt;br /&gt;
== Getting configurations in FEX code ==&lt;br /&gt;
FEX provides a `FEX_CONFIG_OPT` define to help developers get configuration options.&lt;br /&gt;
* FEX_CONFIG_OPT(name, enum)&lt;br /&gt;
  * eg: `FEX_CONFIG_OPT(Cores, THREADS);`&lt;br /&gt;
  * This will load the THREADS configuration option from the configuration directory and save the value in to local value called `Cores`&lt;br /&gt;
* Gotchas:&lt;br /&gt;
  * Construction of the object queries the the global configuration layer. This can be slow so be careful with its use.&lt;br /&gt;
  * Upon construction of the `FEXCore::Config::Value&amp;lt;T&amp;gt;` object it will pull the string configuration&lt;br /&gt;
  * Then it will convert that value in to whatever type the value needs&lt;br /&gt;
  * In high performance code, keep constructor instantiation outside of the hot code path&lt;br /&gt;
  * Construct the configuration inside of a class definition so it only pulls the configuration once&lt;br /&gt;
* Caveats:&lt;br /&gt;
  * If the configuration changes then this doesn't pick up the change&lt;br /&gt;
  * Configuration isn't meant to change live in FEX so this is typically a non-issue&lt;br /&gt;
  * Frontend object loader needs to be careful with its configuration loading to ensure the meta layer stays in sync&lt;br /&gt;
  * ELFLoader.cpp for examples here&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=436</id>
		<title>Development:Setting up Library Forwarding</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_Library_Forwarding&amp;diff=436"/>
		<updated>2022-06-22T13:38:33Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Build Dependencies ==&lt;br /&gt;
* g++-x86-64-linux-gnu (For building thunks)&lt;br /&gt;
* '''Development libraries for various thunks'''&lt;br /&gt;
* libdrm-dev&lt;br /&gt;
* libxcb-present-dev&lt;br /&gt;
* libxcb-dri2-0-dev&lt;br /&gt;
* libxcb-dri3-dev&lt;br /&gt;
* libxcb-glx0-dev&lt;br /&gt;
* libxcb-shm0-dev&lt;br /&gt;
* libxshmfence-dev&lt;br /&gt;
* libvulkan-dev &lt;br /&gt;
&lt;br /&gt;
== Building vulkan-docs if your host is too old ==&lt;br /&gt;
If you're host's libvulkan-dev is too old, which is highly likely then you'll need to install a new set of vulkan headers&lt;br /&gt;
&lt;br /&gt;
* git clone https://github.com/KhronosGroup/Vulkan-Headers.git&lt;br /&gt;
* cd Vulkan-Headers&lt;br /&gt;
* mkdir Build&lt;br /&gt;
* cd Build&lt;br /&gt;
* cmake -DCMAKE_INSTALL_PREFIX=/usr ..&lt;br /&gt;
* sudo make install&lt;br /&gt;
&lt;br /&gt;
== Setting cmake to build thunks ==&lt;br /&gt;
Pass in to cmake the option to enable thunk building.&lt;br /&gt;
* -DBUILD_THUNKS=True&lt;br /&gt;
&lt;br /&gt;
== FEX thunk options ==&lt;br /&gt;
* FEX_THUNKHOSTLIBS, -t &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkhostlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkHostLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the host-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/lib/fex-emu/HostThunks/'''&lt;br /&gt;
* FEX_THUNKGUESTLIBS, -j &amp;lt;Thunk Host Libs Path&amp;gt;, --thunkguestlibs=&amp;lt;Thunk Host Libs path&amp;gt;, JSON: '''ThunkGuestLibs:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** Folder to find the guest-side thunking libraries.&lt;br /&gt;
** FEX by default installs these files to: '''/usr/share/fex-emu/GuestThunks/'''&lt;br /&gt;
* FEX_THUNKCONFIG, -k &amp;lt;Thunk Config json path&amp;gt;, --thunkconfig=&amp;lt;Thunk Config json path&amp;gt;, JSON: '''ThunkConfig:&amp;lt;Path&amp;gt;'''&lt;br /&gt;
** A json file specifying where to overlay the thunks.&lt;br /&gt;
** If the filename isn't a path then FEX will search for the file in '''$HOME/.fex-emu/ThunkConfigs/'''&lt;br /&gt;
&lt;br /&gt;
== How to use Thunks ==&lt;br /&gt;
Once Thunks are built and installed then you can can set the three configuration options to the correct paths&lt;br /&gt;
&lt;br /&gt;
* The user can likely set '''ThunkHostLibs''' and '''ThunkGuestLibs''' to the global install path&lt;br /&gt;
** Unless these are set in the '''ThunkConfig''' file, these will be unused&lt;br /&gt;
** Overriding these to another location is useful for application specific hacks if necessary&lt;br /&gt;
* Setting the global application profile for '''ThunkConfig''' is useful for testing but not recommended for long term use&lt;br /&gt;
** Due to the unstable nature of thunks, it is recommended to use application specific profiles to enable thunks&lt;br /&gt;
** This allows the user to test applications first using the global config, then once confirmed it works, generating an application profile&lt;br /&gt;
** Recommended to reduce the application profile to the minimum set of options. FEXConfig will save a full config.&lt;br /&gt;
&lt;br /&gt;
== Thunks Database format ==&lt;br /&gt;
FEX provides a ThunksDB.json file which allows the user to describe a thunk mapping. '''$prefix/share/fex-emu/ThunksDB.json'''&lt;br /&gt;
&lt;br /&gt;
The user can also provide a '''$HOME/.fex-emu/ThunksDB.json''' which will overlay the system installed path&lt;br /&gt;
&lt;br /&gt;
This allows the user to configure the thunk file mapping once, since it is unlikely to change between applications. The user can also mix and match ThunksDB and regular thunks configuration if a complex configuration is necessary.&lt;br /&gt;
&lt;br /&gt;
* ThunksDB.json example&lt;br /&gt;
  {&lt;br /&gt;
      &amp;quot;DB&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;User Defined Name&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;Library&amp;quot;: &amp;quot;&amp;lt;Guest Library Name&amp;gt;.so&amp;quot;,&lt;br /&gt;
          &amp;quot;Depends&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;Other User Defined Name&amp;gt;&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;Overlay&amp;quot;: [&lt;br /&gt;
            &amp;quot;&amp;lt;System Library Path to library&amp;gt;&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Look at the FEX provided library for a real implementation, or just use the provided configuration.&lt;br /&gt;
&lt;br /&gt;
Once the user has a viable ThunksDB provided, now configure FEX with a ThunkConfig filepath with the application thunk configuration.&lt;br /&gt;
&lt;br /&gt;
This thunks configuration file can now enable Thunk definitions using the user defined names.&lt;br /&gt;
&lt;br /&gt;
* ThunkConfig example&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;ThunksDB&amp;quot;: {&lt;br /&gt;
      &amp;quot;GL&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri2&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-dri3&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;X11&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-xfixes&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-shm&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-sync&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xcb-randr&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-present&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;xcb-glx&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;xshmfence&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;drm&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xrender&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xext&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Xfixes&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;Vulkan-lavapipe&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-radeon&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-freedreno&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-intel&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-panfrost&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;Vulkan-virtio&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;asound&amp;quot;: 0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Limitations and problems ==&lt;br /&gt;
* 32-bit thunks aren't available currently&lt;br /&gt;
** Requires kernel patches for ARM64 support&lt;br /&gt;
* Thunks aren't fully stable. Expect missing symbols and crashes.&lt;br /&gt;
&lt;br /&gt;
== Legacy ThunkConfig example ==&lt;br /&gt;
'''This is legacy path and not recommended.'''&lt;br /&gt;
&lt;br /&gt;
This is just an example for how one could lay out the thunks.&lt;br /&gt;
* Save this to a file somewhere and point '''ThunkConfig''' option to it&lt;br /&gt;
** '''$HOME/.fex-emu/ThunkConfigs/''' isn't a bad choice for consistency.&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;thunks&amp;quot;: {&lt;br /&gt;
    &amp;quot;libGL-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libGL.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libasound-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libasound.so.2&amp;quot;],&lt;br /&gt;
    &amp;quot;libX11-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libX11.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXrender-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXrender.so.1&amp;quot;],&lt;br /&gt;
    &amp;quot;libXext-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXext.so.6&amp;quot;],&lt;br /&gt;
    &amp;quot;libXfixes-guest.so&amp;quot;: [&amp;quot;/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;, &amp;quot;/usr/lib/x86_64-linux-gnu/libXfixes.so.3&amp;quot;]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=435</id>
		<title>Development:Debugging Crash In Thunks</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash_In_Thunks&amp;diff=435"/>
		<updated>2022-06-22T13:38:24Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Once Thunks are enabled ==&lt;br /&gt;
* Once you've verified your crash is in a thunk then this becomes quite a bit easier&lt;br /&gt;
&lt;br /&gt;
  gdb --args FEXInterpreter /usr/bin/vulkaninfo&lt;br /&gt;
  Thread 1 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc82240f4 in tu_CreateDevice () from /lib/aarch64-linux-gnu/libvulkan_freedreno.so&lt;br /&gt;
  #1  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #2  0x0000007fe25e4028 in ?? ()&lt;br /&gt;
  Backtrace stopped: previous frame inner to this frame (corrupt stack?)&lt;br /&gt;
&lt;br /&gt;
* Okay, that's a direct crash in Turnip, let's rebuild Mesa with a debug build and try again&lt;br /&gt;
  Thread 1 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  1632       memset(ptr, 0x42, 16);&lt;br /&gt;
  (gdb) bt&lt;br /&gt;
  #0  0x0000007fc80bc600 in tu_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at ../src/freedreno/vulkan/tu_device.c:1632&lt;br /&gt;
  #1  0x0000007fc80eab9c in vk_tramp_CreateDevice (physicalDevice=0x5559947aa0, pCreateInfo=0x7ff75fda20, pAllocator=0x0, pDevice=0x7fcbe7b358) at src/vulkan/runtime/vk_dispatch_trampolines.c:78&lt;br /&gt;
  #2  0x0000007fc8642b94 in function_traits&amp;lt;decltype (&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*)))&amp;gt;::result_t fexfn_type_erased_unpack&amp;lt;&amp;amp;(fexfn_unpack_libvulkan_freedreno_vkCreateDevice(fexfn_packed_args_libvulkan_freedreno_vkCreateDevice*))&amp;gt;(void*) () from /usr/lib/fex-emu/HostThunks//libvulkan_freedreno-host.so&lt;br /&gt;
  #3  0x0000007fe25e426c in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay the crash is at.. `tu_device:1632`, let's go and debug that line&lt;br /&gt;
&lt;br /&gt;
  1631    void* ptr = (void*)1;&lt;br /&gt;
  1632    memset(ptr, 0x42, 16);&lt;br /&gt;
&lt;br /&gt;
* Who put that in there?!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:gfxreconstruct&amp;diff=434</id>
		<title>Development:gfxreconstruct</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:gfxreconstruct&amp;diff=434"/>
		<updated>2022-06-22T13:38:04Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
= gfxreconstruct =&lt;br /&gt;
gfxreconstruct is a Vulkan layer that is useful for capturing a frame in a robust way.&lt;br /&gt;
&lt;br /&gt;
This is usually useful for capturing frames that is more portable than renderdoc.&lt;br /&gt;
&lt;br /&gt;
https://github.com/LunarG/gfxreconstruct&lt;br /&gt;
&lt;br /&gt;
= Setting up gfxreconstruct =&lt;br /&gt;
First thing you must do is build gfxreconstruct from source. Either for your host or guest rootfs, depending on if you're using thunks or not.&lt;br /&gt;
&lt;br /&gt;
If building for the x86 rootfs then make sure to install it in to the rootfs after building. This can be done by just copying the install files over afterwards.&lt;br /&gt;
&lt;br /&gt;
== Set up environment variables ==&lt;br /&gt;
* VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_gfxreconstruct&lt;br /&gt;
* GFXRECON_CAPTURE_TRIGGER=F12&lt;br /&gt;
* GFXRECON_CAPTURE_FILE=/tmp/gfxrecon_capture.gfxr&lt;br /&gt;
&lt;br /&gt;
Once you have the environment variables set up you can then launch a vulkan game. There will be some additional output in the terminal to know when the layer is capturing. You can then press F12 in the application and you'll get a capture in tmp after a few seconds. Be careful as gfxreconstruct will overwrite the capture on each press, so you will want to move each capture file.&lt;br /&gt;
&lt;br /&gt;
== Replay ==&lt;br /&gt;
gfxrecon-replay can be used to replay the capture which is quite useful.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Renderdoc&amp;diff=433</id>
		<title>Development:Renderdoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Renderdoc&amp;diff=433"/>
		<updated>2022-06-22T13:37:53Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: Add development category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
= Getting a capture =&lt;br /&gt;
== Without Thunks ==&lt;br /&gt;
* Ensure Renderdoc is installed in the rootfs&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
* Set LD_PRELOAD=librenderdoc.so as an environment variable&lt;br /&gt;
* This can be done in FEXConfig or an application profile to limit its reach&lt;br /&gt;
&lt;br /&gt;
=== Vulkan ===&lt;br /&gt;
* Ensure the renderdoc layer is installed&lt;br /&gt;
* Set ENABLE_VULKAN_RENDERDOC_CAPTURE=1 as an environment variable&lt;br /&gt;
* This can be done in FEXConfig or an application profile to limit its reach&lt;br /&gt;
&lt;br /&gt;
=== Alternatively ===&lt;br /&gt;
You can use renderdoccmd to launch an application directly.&lt;br /&gt;
* renderdoccmd capture -w &amp;lt;program&amp;gt; &amp;lt;args...&amp;gt;&lt;br /&gt;
As long as this application is installed in your rootfs then it should work for both OpenGL and Vulkan applications.&lt;br /&gt;
&lt;br /&gt;
=== Capture results ===&lt;br /&gt;
* Once you have captured a frame in an application running renderdoc (F12 typically)&lt;br /&gt;
* The results will be in /tmp/RenderDoc/ as *.rdc files&lt;br /&gt;
* Technically these are meant to be moved over to the qrenderdoc application but you can rip them directly&lt;br /&gt;
&lt;br /&gt;
== With Thunks ==&lt;br /&gt;
Likely to be the same as without thunks, but instead of adding environment variables inside of FEX. One needs to do it outside of FEX instead&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=432</id>
		<title>Development:Debugging Crash</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_Crash&amp;diff=432"/>
		<updated>2022-06-22T13:37:42Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
* Debug an application with `gdb --args FEXInterpreter &amp;lt;application full path&amp;gt;`&lt;br /&gt;
* Under GDB make sure to do `handle SIGBUS SIGILL SIG63 noprint`&lt;br /&gt;
** We use signals for various things, check out [[Development:Debugging_FEX_with_Signals|Here]] for more information&lt;br /&gt;
&lt;br /&gt;
== Crash in emulated/JIT code ==&lt;br /&gt;
Walking through debugging a simple test application that is crashing.&lt;br /&gt;
  $ gdb --args FEXInterpreter ./sigsegv_test&lt;br /&gt;
  Reading symbols from FEXInterpreter...&lt;br /&gt;
  (gdb) r&lt;br /&gt;
  Starting program: /usr/bin/FEXInterpreter ./sigsegv_test&lt;br /&gt;
  [Thread debugging using libthread_db enabled]&lt;br /&gt;
  Using host libthread_db library &amp;quot;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;quot;.&lt;br /&gt;
  [New Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  &lt;br /&gt;
  Thread 2 &amp;quot;FEXInterpreter&amp;quot; received signal SIGSEGV, Segmentation fault.&lt;br /&gt;
  [Switching to Thread 0x7fccb75f30 (LWP 90107)]&lt;br /&gt;
  0x0000007fccfb9ec8 in ?? ()&lt;br /&gt;
&lt;br /&gt;
* Okay, we have a sigsegv. Let's double check that it is JIT code (aka, guest emulated code)&lt;br /&gt;
  (gdb) disas $pc,+32&lt;br /&gt;
  Dump of assembler code from 0x7fe26ebc20 to 0x7fe26ebc40:&lt;br /&gt;
  =&amp;gt; 0x0000007fe26ebc20:  stlrb   w22, [x21]&lt;br /&gt;
     0x0000007fe26ebc24:  mov     x4, #0x0                        // #0&lt;br /&gt;
     0x0000007fe26ebc28:  ldr     x10, [x20]&lt;br /&gt;
     0x0000007fe26ebc2c:  add     x21, x20, #0x8&lt;br /&gt;
     0x0000007fe26ebc30:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc34:  strb    w22, [x28, #428]&lt;br /&gt;
     0x0000007fe26ebc38:  mov     x22, #0x0                       // #0&lt;br /&gt;
     0x0000007fe26ebc3c:  strb    w22, [x28, #431]&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb) info reg x9&lt;br /&gt;
  x9             0x0                 0&lt;br /&gt;
* Looks like JIT code, even doing accesses to x28 which is the FEX CPU state&lt;br /&gt;
* Code has no backtrace which reinforces this&lt;br /&gt;
* Code is doing an atomic store, which reinforces this is FEX emulating the x86 TSO memory model&lt;br /&gt;
&lt;br /&gt;
* Now that we have checked that we are in the JIT code. Where are we in the guest side?&lt;br /&gt;
* Let's dump the FEX CPU state information that is directly pointed to in x28 at all times in JIT code.&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State&lt;br /&gt;
  $3 = {rip = 0x401110, gregs = {0x416eb0, 0x7fe1e3b640, 0xffffffffffffff70, 0x0, 0x7fe1e3bf30, 0x0, 0x416eb0, 0x7fe1e3ae28, 0x0, 0x7fe1e3b640, 0x8, 0x7fe2054cc0, 0x7ff75ff48e, 0x7ff75ff48f, 0x0, 0x7fe163b000}, xmm = {{0x0, 0x0}, {0x0, 0x0}, {0xdeadbeef, 0xbad0dad1} &amp;lt;repeats 14 times&amp;gt;}, es = 0x0, cs = 0x0, ss = 0x0, ds = 0x0, gs = 0x0, fs = 0x7fe1e3b640, flags = {0x0, 0x1, 0x0,&lt;br /&gt;
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0 &amp;lt;repeats 38 times&amp;gt;}, mm = {{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}}, gdt = {{base = 0x0} &amp;lt;repeats 32 times&amp;gt;}, FCW = 0x37f, FTW = 0xffff}&lt;br /&gt;
&lt;br /&gt;
* Looks like our guest RIP is currently `0x401110`&lt;br /&gt;
** Consult the `info proc mappings` again&lt;br /&gt;
  0x401000           0x402000     0x1000     0x1000 {...}/sigsegv_test&lt;br /&gt;
* Yep, we are inside our test application&lt;br /&gt;
* For a simple test, let's load the application in gdb-multiarch and disassemble where we are&lt;br /&gt;
  $ gdb-multiarch ./sigsegv_test&lt;br /&gt;
  Reading symbols from ./sigsegv_test...&lt;br /&gt;
  (gdb) set disassembly-flavor intel&lt;br /&gt;
  (gdb) disas 0x401110&lt;br /&gt;
  Dump of assembler code for function main(int, char**):&lt;br /&gt;
     0x0000000000401110 &amp;lt;+0&amp;gt;:     push   rbp&lt;br /&gt;
     0x0000000000401111 &amp;lt;+1&amp;gt;:     mov    rbp,rsp&lt;br /&gt;
     0x0000000000401114 &amp;lt;+4&amp;gt;:     mov    DWORD PTR [rbp-0x4],0x0&lt;br /&gt;
     0x000000000040111b &amp;lt;+11&amp;gt;:    mov    DWORD PTR [rbp-0x8],edi&lt;br /&gt;
     0x000000000040111e &amp;lt;+14&amp;gt;:    mov    QWORD PTR [rbp-0x10],rsi&lt;br /&gt;
     0x0000000000401122 &amp;lt;+18&amp;gt;:    mov    rax,QWORD PTR [rbp-0x10]&lt;br /&gt;
     0x0000000000401126 &amp;lt;+22&amp;gt;:    movsxd rcx,DWORD PTR [rbp-0x8]&lt;br /&gt;
     0x000000000040112a &amp;lt;+26&amp;gt;:    mov    rax,QWORD PTR [rax+rcx*8]&lt;br /&gt;
     0x000000000040112e &amp;lt;+30&amp;gt;:    mov    QWORD PTR [rbp-0x18],rax&lt;br /&gt;
     0x0000000000401132 &amp;lt;+34&amp;gt;:    mov    rax,QWORD PTR [rbp-0x18]&lt;br /&gt;
     0x0000000000401136 &amp;lt;+38&amp;gt;:    mov    BYTE PTR [rax],0x63&lt;br /&gt;
     0x0000000000401139 &amp;lt;+41&amp;gt;:    xor    eax,eax&lt;br /&gt;
     0x000000000040113b &amp;lt;+43&amp;gt;:    pop    rbp&lt;br /&gt;
     0x000000000040113c &amp;lt;+44&amp;gt;:    ret&lt;br /&gt;
  End of assembler dump.&lt;br /&gt;
  (gdb)&lt;br /&gt;
&lt;br /&gt;
* Okay, not super helpful since FEX translates instructions in to blocks, `0x401110` is just our starting address&lt;br /&gt;
** It's in this code somewhere, let's change some FEX settings to get a clearer picture&lt;br /&gt;
* Set block size to one instruction and disable multiblock&lt;br /&gt;
** See the image in FEXConfig to the right&lt;br /&gt;
[[File:FEXConfig 1Inst NoMulti.png|thumb]]&lt;br /&gt;
* Now rerun our test application and find the new RIP&lt;br /&gt;
&lt;br /&gt;
  (gdb) p/x ((FEXCore::Core::CpuStateFrame*)$x28)-&amp;gt;State.rip&lt;br /&gt;
  $2 = 0x401136&lt;br /&gt;
&lt;br /&gt;
* Alright, now we know the RIP is exactly at `0x401136`&lt;br /&gt;
* Back in gdb-multiarch&lt;br /&gt;
  (gdb) disas 0x401136,+1&lt;br /&gt;
  Dump of assembler code from 0x401136 to 0x401137:&lt;br /&gt;
     0x0000000000401136 &amp;lt;main(int, char**)+38&amp;gt;:   mov    BYTE PTR [rax],0x63&lt;br /&gt;
&lt;br /&gt;
* Looks like something in main is storing 0x63 to a nullptr&lt;br /&gt;
* In this simple case we can now take a look at the test application's source and find the problem.&lt;br /&gt;
** We know the problem is in the first block of main()&lt;br /&gt;
** We know the exact instruction that it is at&lt;br /&gt;
** We know it's something storing a byte to memory&lt;br /&gt;
* For more complex cases it is likely necessary to use reverse engineering tools&lt;br /&gt;
** BinaryNinja, Ghidra, IDA, and Hopper are all examples of tools like this&lt;br /&gt;
&lt;br /&gt;
== What to do from here ==&lt;br /&gt;
Now it becomes a lot harder. You don't get a typical debugging environment or even clean backtraces.&lt;br /&gt;
&lt;br /&gt;
FEX's gdbserver integration is sorely lacking so you can't even use a remote gdb server connecting to FEX right now.&lt;br /&gt;
&lt;br /&gt;
If you enable thunks you can get better backtraces here. [[Development:Debugging_Crash_In_Thunks|Debugging_Crash_In_Thunks]]&lt;br /&gt;
&lt;br /&gt;
== Attempting to use FEX-Emu's gdbserver implementation ==&lt;br /&gt;
'''Here be dragons'''&lt;br /&gt;
&lt;br /&gt;
FEX supports gdbserver as an integration. It's implementation is significantly limited but can still be used for debugging and getting some backtraces.&lt;br /&gt;
* Currently hardcodes the port to use as `8086` and if you have multiple gdbserver processes running then it will encounter problems.&lt;br /&gt;
* Currently does not follow processes through fork/execve at all. No multiprocess support&lt;br /&gt;
** This means you '''must''' only start the process you're caring about debugging&lt;br /&gt;
* Currently starts the process paused and will wait until gdb attach before continuing&lt;br /&gt;
** No way to start a FEX instance then attach at some later point&lt;br /&gt;
* Ctrl-C to stop the FEX process needs to be done twice&lt;br /&gt;
** Maybe with a small delay inbetween because gdb needs to fetch a bunch of data on pause&lt;br /&gt;
** Known bug, unknown why broken at the moment&lt;br /&gt;
&lt;br /&gt;
  FEXLoader -G -- &amp;lt;Application&amp;gt; &amp;lt;Args...&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Double checking if we are in JIT code ==&lt;br /&gt;
  (gdb) info reg pc&lt;br /&gt;
  pc             0x7fccfb9ec8        0x7fccfb9ec8&lt;br /&gt;
  &lt;br /&gt;
  (gdb) info proc mappings&lt;br /&gt;
  ...&lt;br /&gt;
  0x7fccfb9000       0x7fcdfb9000  0x1000000        0x0&lt;br /&gt;
&lt;br /&gt;
* Looks like FEX JIT mapping, we start out at 16MB but scale up to 128MB&lt;br /&gt;
* Depending on version of FEX we can check the base mapping for a unique string &lt;br /&gt;
  (gdb) p (char*)0x7fccfb9000&lt;br /&gt;
  $4 = 0x7fccfb9000 &amp;quot;FEXJIT::Arm64JITCore::&amp;quot;&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Debugging_FEX_with_Signals&amp;diff=431</id>
		<title>Development:Debugging FEX with Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Debugging_FEX_with_Signals&amp;diff=431"/>
		<updated>2022-06-22T13:37:36Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
= Signals and you =&lt;br /&gt;
&lt;br /&gt;
FEX uses signals in quite a few ways that may cause debugging to be a bit of a pain. This is necessary for correct operation so it is an evil we must live with.&lt;br /&gt;
&lt;br /&gt;
== Signals that FEX uses ==&lt;br /&gt;
* SIGBUS - The AArch64 JIT generates unaligned loadstore instructions then captures and backpatches these when they fault&lt;br /&gt;
** This is necessary for emulating x86-TSO on AArch64 and can't be dropped without massive performance loses&lt;br /&gt;
* SIGILL - All of the CPU backends generate this fault and is necessary for the emulator to return from a guest signal&lt;br /&gt;
** Going in to a signal happens frequently, gdb will usually ignore the entry when it is SIGALRM or SIGUSR*&lt;br /&gt;
** We could choose a different signal, but this one can be generated in one instruction which makes it nice to use&lt;br /&gt;
** Using a signal to punch back through to the guest return path is necessary since we need to save and restore guest registers when guest signals occur.&lt;br /&gt;
* SIG63 - We use this for various ancillary functions&lt;br /&gt;
** This signal currently tells a thread that it should stop running, to pause its execution, or to resume from its paused frame&lt;br /&gt;
** This is another necessary signal since if we want to safely shutdown the emulator and a thread is in a syscall, there is no way for it to leave without a signal.&lt;br /&gt;
** The stop signal specifically will have the CPU backend long jump from the signal handler to the exit stage of the ASM dispatcher for safe shutdown&lt;br /&gt;
** This slightly increases performance because then there aren't atomic checks per iteration of the execution loop for if we should stop executing&lt;br /&gt;
&lt;br /&gt;
= Debugging FEX =&lt;br /&gt;
Read more here [[Development:Debugging_Crash]]&lt;br /&gt;
&lt;br /&gt;
= Profiling FEX code =&lt;br /&gt;
You'll want to enable a style of JIT code mark-up for perf to annotate with&lt;br /&gt;
* FEX currently has three options for this&lt;br /&gt;
* Depending on what you're trying to profile you will want to enable one of these options&lt;br /&gt;
** FEX_GLOBALJITNAMING&lt;br /&gt;
*** Useful if you want to throw all of FEX JIT space in to a global-ish namespace&lt;br /&gt;
** FEX_LIBRARYJITNAMING&lt;br /&gt;
*** Useful if you want to clump FEX JIT space in to library specific code segments&lt;br /&gt;
*** Can be nice for finding libraries to thunk&lt;br /&gt;
** FEX_BLOCKJITNAMING&lt;br /&gt;
*** This is likely the one you want if you're profiling your application's code&lt;br /&gt;
*** This will give you hot blocks in `perf top`&lt;br /&gt;
&lt;br /&gt;
Enabling one of these will give you some symbols when capturing FEX with `perf top`. The block naming is useful for seeing hot blocks in program space so if something ends up being particularly slow in FEX, it can get more isolated.&lt;br /&gt;
* We don't currently have an option to relate JIT code directly to function symbols in the ELF at this point.&lt;br /&gt;
&lt;br /&gt;
= Debugging the guest application =&lt;br /&gt;
When FEX is started with the -G argument it will open a gdbstub socket listening on port 8086. This can be connected to with gdbserver, ida, ghidra, or binary ninja.&lt;br /&gt;
&lt;br /&gt;
This is currently only useful for inspection, gdbstub doesn't yet send guest signals over through gdbstub!&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
	<entry>
		<id>https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=430</id>
		<title>Development:Setting up RootFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.fex-emu.com/index.php?title=Development:Setting_up_RootFS&amp;diff=430"/>
		<updated>2022-06-22T13:37:28Z</updated>

		<summary type="html">&lt;p&gt;Neobrain: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
= Setting up a RootFS =&lt;br /&gt;
'''For AArch64 hosts you are required to have an x86-64 rootfs'''. With or without 32bit compatibility libraries.&lt;br /&gt;
&lt;br /&gt;
This isn't strictly required for testing on x86-64 host environments but is useful for ensuring correct behaviour there.&lt;br /&gt;
&lt;br /&gt;
= Quick Setup with FEXRootFSFetch =&lt;br /&gt;
FEX comes with a FEXRootFSFetcher tool that can download an official preconfigured rootfs from the FEX servers.&lt;br /&gt;
This tool operates as either a terminal application or a Zenity application depending on if it is launched from terminal or not.&lt;br /&gt;
&lt;br /&gt;
This tool will walk you through selecting a RootFS for FEX:&lt;br /&gt;
* If your host OS matches one in the download list then it will recommend that one&lt;br /&gt;
* After selecting the RootFS, it will download it&lt;br /&gt;
** This downloads to the default location in '''$HOME/.fex-emu/RootFS/'''&lt;br /&gt;
* After downloading the RootFS the tool will ask if you want to use the SquashFS file directly or extract it&lt;br /&gt;
* It will then ask if you want to set the downloaded RootFS as your default&lt;br /&gt;
** This writes to the default configuration in '''$HOME/.fex-emu/Config.json'''&lt;br /&gt;
&lt;br /&gt;
You can skip the rest of the guide if you used FEXRootFSFetcher to download the rootfs.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
* The squashfs image will fail to extract if you don't have unsquashfs installed&lt;br /&gt;
** Install the squashfs-tools package to get this application&lt;br /&gt;
&lt;br /&gt;
* '''SquashFS RootFS file corrupted?'''&lt;br /&gt;
** Rerun the tool, select the rootfs from the list, and if the rootfs already exists it will ask to verify&lt;br /&gt;
** If verification fails it will ask if you want to redownload&lt;br /&gt;
* '''Want to manually check the hash?'''&lt;br /&gt;
** Run the rootfs file directly through the tool to get a hash&lt;br /&gt;
** '''FEXRootFSFetcher $HOME/.fex-emu/RootFS/Ubuntu_21_10.sqsh'''&lt;br /&gt;
** Ubuntu_21_10.sqsh has hash: bf9507fbdbaec2cf&lt;br /&gt;
* '''Want to use the Zenity UI but still launch through terminal?'''&lt;br /&gt;
** Force Zenity from terminal with '''FEXRootFSFetcher 1&amp;gt; /dev/null'''&lt;br /&gt;
* '''What if my Linux distro isn't listed?'''&lt;br /&gt;
** Don't worry, select one that is most similar to yours or newest&lt;br /&gt;
** This will work in most cases&lt;br /&gt;
* '''How can I trust these images?'''&lt;br /&gt;
** These images are generated by scripts living in our public repo&lt;br /&gt;
** If you want to rebuild them yourself, you are free to do so.&lt;br /&gt;
** https://github.com/FEX-Emu/RootFS&lt;br /&gt;
* '''I want to add a distro'''&lt;br /&gt;
** Follow how our current rootfs is generated and add your own&lt;br /&gt;
** Open a pull request to add the rootfs setup&lt;br /&gt;
** Contact us on the official FEX-Emu Discord to get the RootFS added to the server.&lt;br /&gt;
* '''Where is the raw list of images at?'''&lt;br /&gt;
** The image links live on our website at the following link&lt;br /&gt;
** https://rootfs.fex-emu.org/file/fex-rootfs/RootFS_links_XXH3.txt&lt;br /&gt;
** This file is in a format that our tool understands&lt;br /&gt;
** Generally the format is:&lt;br /&gt;
*** Distro Name&lt;br /&gt;
*** Distro Version&lt;br /&gt;
*** Human readable name&lt;br /&gt;
*** Raw rootfs link&lt;br /&gt;
*** xxhash based file hash&lt;br /&gt;
&lt;br /&gt;
= Making a custom rootfs prerequisites =&lt;br /&gt;
An x86-64 PC or FEX-Emu installed for chrooting&lt;br /&gt;
&lt;br /&gt;
= Getting Started =&lt;br /&gt;
The easiest way to get started is to just download a prebuilt x86-64 rootfs from your favourite distribution and extract it to where you want.&lt;br /&gt;
* Ubuntu - http://cdimage.ubuntu.com/ubuntu-base/releases/&lt;br /&gt;
* Debian Debootstrap guide - https://wiki.debian.org/Debootstrap&lt;br /&gt;
** Debootstrap is more involved and not explained here.&lt;br /&gt;
&lt;br /&gt;
Using chroot you can then enter the rootfs and install applications that you desire for testing purposes.&lt;br /&gt;
It's easiest to set this up on an x86-64 host and then copy it to an AArch64 device.&lt;br /&gt;
&lt;br /&gt;
== Cross architecture chroot ==&lt;br /&gt;
'''You need to have binfmt_misc setup for x86-64 support on your host system.'''&lt;br /&gt;
* ls /proc/sys/fs/binfmt_misc &lt;br /&gt;
** If there are files in this folder then your host supports binfmt_misc&lt;br /&gt;
* Once you have binfmt_misc running and FEX-Emu installed in to it, you can chroot in to an x86-64 rootfs&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to rootfs with FEX-Emu Rootfs ==&lt;br /&gt;
* If you're using a FEX-Emu provided rootfs then we provide two scripts at the start to handle this&lt;br /&gt;
** '''unbreak_chroot.sh''' - This sets up the rootfs and chroots inside of it&lt;br /&gt;
** '''break_chroot.sh''' - This sets up the rootfs for using with FEX generally.&lt;br /&gt;
*** '''Make sure to run this after leaving the chroot!'''&lt;br /&gt;
** The remaining steps in this guide can be skipped&lt;br /&gt;
&lt;br /&gt;
== Chrooting in to custom rootfs with FEX-Emu ==&lt;br /&gt;
* If you're setting up your own rootfs then you need to follow the binding steps that are following.&lt;br /&gt;
** We have a script that if you know what you're doing you can cherry pick parts from [https://github.com/FEX-Emu/RootFS/blob/main/unbreak_chroot.sh here]&lt;br /&gt;
&lt;br /&gt;
= Additional TmpFS folders =&lt;br /&gt;
Depending on what you're doing in the chroot, you may need or want some tmpfs folders that applications are expecting&lt;br /&gt;
&lt;br /&gt;
* sudo mount -t proc /proc ${ROOTFS}/proc/&lt;br /&gt;
* sudo mount --rbind --make-rslave /sys ${ROOTFS}/sys/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev ${ROOTFS}/dev/&lt;br /&gt;
* sudo mount --rbind --make-rslave /dev/pts ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo mount --rbind /lib/ld-linux-aarch64.so.1 ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo mount --rbind /lib/aarch64-linux-gnu ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
Then of course, make sure to unmount these partitions when you're done&lt;br /&gt;
&lt;br /&gt;
* sudo umount ${ROOTFS}/proc/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/sys/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/pts/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/dev/&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/ld-linux-aarch64.so.1&lt;br /&gt;
* sudo umount -R ${ROOTFS}/lib/aarch64-linux-gnu&lt;br /&gt;
&lt;br /&gt;
= Using the rootfs with FEX =&lt;br /&gt;
If you're using FEXLoader then you can pass the full path of the rootfs with the -R option.&lt;br /&gt;
Additionally you can put the rootfs folder inside of $HOME/.fex-emu/RootFS/&amp;lt;RootFS name&amp;gt;/ and FEX supports a &amp;quot;named&amp;quot; rootfs option&lt;br /&gt;
* eq: -R Ubuntu_2104 will use rootfs $HOME/.fex-emu/RootfS/Ubuntu_2104&lt;br /&gt;
* Read the Fex man page with man fex for more information&lt;br /&gt;
&lt;br /&gt;
== Setting RootFS with FEXConfig ==&lt;br /&gt;
[[File:FEXConfig Load Default.png|frameless|Load the default options on first run]]&lt;br /&gt;
On the first run of FEXConfig, select the &amp;quot;Load Default Options&amp;quot; configuration.&lt;br /&gt;
* Subsequent runs should select &amp;quot;Open Default&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[File:FEXConfig RootFS Selection.png|frameless|Select the RootFS from the FEXConfig location]]&lt;br /&gt;
&lt;br /&gt;
FEXConfig will autopopulate the rootfs list with rootfs folders that exist in $HOME/.fex-emu/RootFS/&lt;br /&gt;
&lt;br /&gt;
You can select one from the list or provide a full path in the RootFS: line to set it manually.&lt;br /&gt;
&lt;br /&gt;
''' Make sure to select the File-&amp;gt;Save option after the fact to save'''&lt;br /&gt;
&lt;br /&gt;
= Additional Steps for building a custom rootfs = &lt;br /&gt;
== Running under WSL1 ==&lt;br /&gt;
/etc/hosts and /etc/resolv.conf change on the host side. You'll need to copy those over to the rootfs if you want network functionality to work.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu packages to install ==&lt;br /&gt;
Sample packages to install in the rootfs&lt;br /&gt;
* apt-get install pulseaudio libgles1 libgles2 libglx-mesa0 libgl1-mesa-dri libgl1-mesa-glx mesa-utils mesa-utils-extra&lt;br /&gt;
Pulseaudio specifically is required so pulseaudio will work when talking to the host pulseaudio&lt;br /&gt;
&lt;br /&gt;
== File deletion ==&lt;br /&gt;
Some files need to be deleted from the rootfs otherwise some applications will fail to work.&lt;br /&gt;
&lt;br /&gt;
Note that deleting these files '''WILL''' break the rootfs and you won't be able to chroot in to it anymore.&lt;br /&gt;
&lt;br /&gt;
A likely better route would be a script that moves these files and folders then brings them back when you want to chroot&lt;br /&gt;
&lt;br /&gt;
=== Files to remove ===&lt;br /&gt;
* ${ROOTFS}/etc/hosts&lt;br /&gt;
* ${ROOTFS}/etc/resolv.conf&lt;br /&gt;
* ${ROOTFS}/etc/timezone&lt;br /&gt;
* ${ROOTFS}/etc/localtime&lt;br /&gt;
* ${ROOTFS}/etc/passwd&lt;br /&gt;
&lt;br /&gt;
=== Folders to remove ===&lt;br /&gt;
* ${ROOTFS}/boot&lt;br /&gt;
* ${ROOTFS}/dev&lt;br /&gt;
* ${ROOTFS}/home&lt;br /&gt;
* ${ROOTFS}/media&lt;br /&gt;
* ${ROOTFS}/mnt&lt;br /&gt;
* ${ROOTFS}/proc&lt;br /&gt;
* ${ROOTFS}/root&lt;br /&gt;
* ${ROOTFS}/srv&lt;br /&gt;
* ${ROOTFS}/tmp&lt;br /&gt;
* ${ROOTFS}/var/cache/apt&lt;br /&gt;
* ${ROOTFS}/var/lib/apt&lt;br /&gt;
* ${ROOTFS}/sys&lt;br /&gt;
* ${ROOTFS}/opt&lt;br /&gt;
&lt;br /&gt;
== Creating a Squashfs rootfs from custom rootfs ==&lt;br /&gt;
SquashFS is a great way to do binary distribution of the rootfs. If you have created a rootfs and you want to roll it in to a squashfs like the FEX-Emu provided images then this is information on how to do that.&lt;br /&gt;
&lt;br /&gt;
'''SquashFS is currently only recommended for binary distribution. User should unpack it to not get dangling processes and mounts.'''&lt;br /&gt;
* Offers tooling to mount in userspace&lt;br /&gt;
* Supports ZSTD compression&lt;br /&gt;
* Is a readonly partition that matches FEX's use case&lt;br /&gt;
&lt;br /&gt;
=== Tools that FEX needs to run squashfs ===&lt;br /&gt;
* squashfuse&lt;br /&gt;
* fusermount&lt;br /&gt;
&lt;br /&gt;
=== Making the squashfs image ===&lt;br /&gt;
Making the squashfs image is very straightforward&lt;br /&gt;
* mksquashfs ${ROOTFS}/ Squashfs.sqsh -comp zstd&lt;br /&gt;
&lt;br /&gt;
This creates a file called Squashfs.sqsh that contains the original rootfs that we generated above.&lt;br /&gt;
&lt;br /&gt;
=== Using the squashfs image in FEX ===&lt;br /&gt;
* Copy the resulting sqsh file in to ${XDG_DATA_HOME}/.fex-emu/RootFS/&lt;br /&gt;
** If ${XDG_DATA_HOME} doesn't exist then that will be replaced with ${HOME}&lt;br /&gt;
* Use FEXConfig to select the sqsh file as a named rootfs&lt;br /&gt;
* or pass the name in to the FEX_ROOTFS argument in the various ways FEX supports&lt;br /&gt;
* or the absolute path if you don't want it in the FEX RootFS folder&lt;br /&gt;
&lt;br /&gt;
=== Extracting the squashfs ===&lt;br /&gt;
If you don't want to use squashfs for whatever reason then you can extract it in to the FEX RootFS folder and use the directory directly&lt;br /&gt;
* unsquashfs -f -d NewRootFS/ Squashfs.sqsh&lt;br /&gt;
&lt;br /&gt;
=== If you want to install packages in the squashfs ===&lt;br /&gt;
The squashfs image is immutable and can't be modified.&lt;br /&gt;
* Extract the squashfs first&lt;br /&gt;
* Change the working directory to the rootfs&lt;br /&gt;
* execute `unbreak_chroot.sh`&lt;br /&gt;
* `apt-get update`&lt;br /&gt;
* `apt-get install &amp;lt;Whatever you want&amp;gt;`&lt;br /&gt;
* `exit` to leave the chroot&lt;br /&gt;
* `break_chroot.sh`&lt;br /&gt;
* Use the new extracted chroot directly, or follow the previous steps to recompress it to a squashfs format.&lt;br /&gt;
&lt;br /&gt;
=== Known problems with squashfs ===&lt;br /&gt;
'''FEX automatically mounts your squashfs file and can leave dangling squashfs mounts around in some instances.'''&lt;br /&gt;
* '''This is fairly rare but it can occur. Whenever an instance of FEX is run, it registers with the FEXMountDaemon'''&lt;br /&gt;
** FEXMountDaemon then watches these instances of FEX to ensure they have exited before unmounting&lt;br /&gt;
** There is roughly a ten second grace period of no instances of FEX running before unmounting&lt;br /&gt;
** If an instance of FEX starts running then it will reuse the mount partition and reset the timeout&lt;br /&gt;
* To get rid of these dangling mounts if they do manage to manifest, use the following commands&lt;br /&gt;
** fusermount -u /tmp/.FEXMount* ; rmdir /tmp/.FEXMount*&lt;br /&gt;
** These don't require root to unmount&lt;br /&gt;
* In some cases the unmounting can end up returning busy status and not unmount&lt;br /&gt;
** Check the output of `mount` for any /tmp/.FEXMount folders&lt;br /&gt;
** This is due to either FEXMountDaemon or squashfuse still running in the background&lt;br /&gt;
** Can force the application to exit&lt;br /&gt;
** step 1: kill `pidof squashfuse`&lt;br /&gt;
** This will attempt to send SIGTERM to all squashfuse applications, which will unmount the partition on terminate&lt;br /&gt;
** Failing that, you can try to be more abusive&lt;br /&gt;
** kill -9 `pidof FEXMountDaemon`&lt;br /&gt;
** This will forcibly terminate FEXMountDaemon which should also take out the child mounted process&lt;br /&gt;
* If any instances of the mount still exists then you may need to kill more FEX processes.&lt;br /&gt;
** Any FEXInterpreter process will end up keeping the folder mounted and keep it busy&lt;br /&gt;
&lt;br /&gt;
'''strace breaks squashfs'''&lt;br /&gt;
* If you run FEX with `strace -f` then the process that mounts your rootfs loses its setuid bit.&lt;br /&gt;
** This means you then can't mount the rootFS&lt;br /&gt;
* The only workaround is to not use a squashfs in this instance.&lt;br /&gt;
* Alternatively you can spin up a FEXBash instance to force squashfs to be mounted. Then strace a different FEX instance which will use the mounted squashfs location.&lt;/div&gt;</summary>
		<author><name>Neobrain</name></author>
	</entry>
</feed>