Search code examples
assemblycrashcortex-mthumbcodewarrior

Can thumb interwork be deactivated on CW 10.6 with ARM toolchain?


I am working on a project with the CodeWarrior for MCU v10.6 IDE. It is an Eclipse based IDE from NXP. The project targets a K21 SoC from NXP (precisely a MK21FN1M0M12, which embeds a cortex-m4, armv7-m). CodeWarrior is configured to use the ARM toolchain.

I am running into a crash related to thumb-interwork. This feature is enabled by the IDE and cannot be deactivated.

Since armv7-m only supports thumb2, using thumb-interwork does not seem to make sense in the first place. But I probably am missing something here. All the code is properly generated in thumb instructions.

I get trouble when making an indirect function call, through a pointer. The function code gets an odd address at link stage, which is OK (this indicates it is thumb code). However, when calling it through a pointer, a BLX instruction gets generated (I suppose the linker updates the original BL into a BLX here) AND the function pointer's value remains even! Since the pointer's value is even, the jump instructs the core to switch to ARM mode. Hence the crash.

I think the linker upgrades the BL into a BLX because of the thumb-interwork feature being activated. On CodeWarrior for MCU v10.6, this is forced, I cannot disable it. I am told that this is "required for processor" by the tool and cannot click the related checkbox (Properties->C/C++ Build->Settings, ARM CPU. The processor is set to "cortex-m4").

I do not understand why, since this is armv7-m. Moreover it seems to lead me into trouble. I think I am missing something here.

Could you please help me understand what is going on and/or tell me if there is a way to disable thumb-interwork on CodeWarrior?

Thanks and best regards,

Pierre


Solution

  • @Notlikethat was right, my question was a bit of an XY problem.

    My problem arose from using libraries built with GCC with CodeWarrior configured to use the Freescale's toolchain (ARM tools).

    The function pointer with the LSB not set came from one of those libraries and was valued at the link stage by CodeWarrior. Since the linker properly put every function from those libs at odd addresses, I guessed that it should miss some information to detect that the faulty pointer was actually a function pointer.

    Long story short, it turned out that the libraries were stripped, especially with the --strip-unneeded flag. I removed that flag and the linker did a perfect job!