gemarcano / libctr9

Baremetal ARM9 library for the Nintendo 3DS
https://gemarcano.github.io/libctr9
Other
26 stars 2 forks source link

ARM vs Thumb and LTO -- Toolchain hell #2

Closed gemarcano closed 8 years ago

gemarcano commented 8 years ago

So, using GCC 5.3, which is what devkitarm uses, I can place ARM specific functions (stuff using inline assembly that only works in ARM) in a file and compile that as ARM. If I link the final application with a non-lto version, this arrangement works. Enabling LTO causes GCC to freak out. So there seems to be a problem with LTO and mixing object code targets. I'm guessing the problem is that no object code is generated until the final link phase for LTO, so whatever target is specified then, is used for all objects. Which is not what I want.

In the end I see three options:

  1. Force the library to compile as ARM, period. This allows for LTO to be enabled.
  2. Disable LTO and let the library be compiled however, and separate ARM only code to a separate file so I can then give it its own target CFLAGS during compilation.
  3. Enable LTO and add some shim code to the library, along with compile time checks to enable the shims to allow switching from Thumb to ARM and back. Since the shims are enabled at library compile time, if the library is compiled in Thumb mode, any executable linked to it will work. If the library is compiled in ARM mode, only executables compiled in ARM mode can link with it.

There is no winning this war. I think I'm leaning towards option 3. Since compiling with Thumb enables the highest level of interoperability, it is possible I'll release Thumb libraries here. I'll have to document in the README the details of option 3.

gemarcano commented 8 years ago

After sleeping on it, 1 is the sane option for making sure that everyone can link to it. 3 has the possibly bad consequence, when compiled for Thumb, of the outro shim switching back to Thumb regardless of whether the executable is in Thumb or ARM.

gemarcano commented 8 years ago

And after seconds more of thinking, nope. 1 has a problem, it being that the architecture of the LTO output seems to be set when the LTO library is linked. So all approaches are flawed, wonderful. 2 or 3 are the sane solutions.

gemarcano commented 8 years ago

I've posted a reduced version of my problems here: https://gcc.gnu.org/ml/gcc-help/2016-06/msg00014.html

gemarcano commented 8 years ago

For now, I've integrated -ffunction-sections and -Wl,--gc-sections to do something similar to what LTO does. This was added in commit b56311e24a26d9a688d85181b9257f7fe6260b96.