Background information

Starting with HighTec TriCore v11.0.0, the following compiler options are enabled by default:

  • -ffunction-sections

  • -fdata-sections

  • -fpragma-function-sections

  • -fpragma-data-sections

As a result, functions and data may be emitted into individual input sections. This also applies to sections selected via pragmas.

Example: iLLD startup code

An Infineon iLLD startup function may look like this:

// ...
#pragma clang section text=".start"
// ...
IFX_SSW_USED void _START(void)
{
    Ifx_Ssw_Start(IFX_CFG_SSW_CSA_USTACK_PTR, __StartUpSoftware);
}
// ...
#pragma clang section text=""
// ...

With toolchains prior to TriCore v11.0.0, the compiler emitted the function _START into the input section:

.start

With TriCore v11.0.0, due to the default -fpragma-function-sections behavior, the compiler emits the function into a generated subsection:

.start._START

If the linker script contains an exact input section match such as:

.start_tc0 (LCF_STARTPTR_NC_CPU0) : { KEEP (*(.start)); } > prram0_nc

then the linker matches only .start, but not .start._START.

Therefore, the output section .start_tc0 may become empty. For startup sections this can lead to a non-booting application or a runtime trap.

The issue is not limited to .start. It can affect any user-defined section referenced in the linker script without a wildcard.

For example:

#pragma clang section text=".my_code"
void MyFunction(void)
{
}
#pragma clang section text=""

may now produce:

.my_code.MyFunction

Similarly, user-defined data sections may receive variable-specific suffixes.