Arm: Investigate Thumb2/Arm interworking
Arm (32 bit) has two commonly used instruction sets; Thumb2 and Arm. The former is encoded in two bytes per instruction and the latter in four bytes. The CPU also has a bit in the flags register specifyng which code execution mode the CPU is currently in. The important thing to note is that executing Arm code when in Thumb2 mode (or vice versa) will sooner or later result in an illegal insruction or segfault.
During debugging of #10375 (closed), I found that Haskell code compiled via the LLVM backend was generating Arm instructions, while C code compiled via GCC was generating Thumb2 code. When object code from these two paths are linked by the system linker everything is fine because the system linker knows how to link Thumb code to Arm code to produce a valid binary.
The problem in #10375 (closed) was that in GHCi, the runtime linker was loading object files without the correct fixups between Thumb2 and Arm so that Thumb2 code in the
StgRun function was jumping correctly into Arm code in the loaded object and returning to the Thumb2 code in
StgRun while still in Arm execution mode and then crashing.
In commit [changeset:"933adc0f/ghc" 933adc0f/ghc] I fixed GHCi for Arm by forcing GHC to generate only Arm code. As discussed in the associated D1323 it would be nice to investigate this further to see if its possible to make GHC generate Thumb2 code (which potentially has some performance benefits since it encodes all instructions in two bytes) and/or fix Thumb2/Arm interop. However, that interop may not be possible. In one of the comments in the D1323, @bgamari said:
That being said, I don't think we'll ever be able to support linking of Thumb Haskell code with ARM Haskell code. The reason for this is that interop requires the use of a trampoline, which breaks tables-next-to-code.
Two possible outcomes for this ticket are:
- We somehow get proper Thumb2/Arm code interoperation working.
- We decide that interop is too difficult or not worthwhile and a) document this somewhere in the code and b) remove the Thumb2 relocation code in
rts/Linker.cand all other references to Thumb2.