Change the section attribute at link stage / prevent initialization of sections

15-Nov-2024

This article is for the TriCore product. A similar approach applies to our other products as they use the same linker script language.

The C compiler adds section attributes to all code and data sections it creates. The available section attributes are:

  • r  readable sections
  • w writable sections
  • x executable sections
  • i  initialized sections
  • b sections that should be cleared at program startup
  • s scratch sections (not cleared and not initialized)
  • p  protected sections

For more information, see the section Selecting sections for a group in the TriCore user guide.

If you need to change the section attributes or disable the initialization of sections, but the C source code of a module is unavailable or cannot be changed by re-compiling it, then this can be solved during the link stage.


Possible solution

To prevent the initialization of a section, you can use the group entry keyword nocopy.

Possible link stage operations are:
  • Prevent cleanup of non-initialized variables by adding the s (scratch) attribute. Then the linker will not add a copy table entry for those sections and the startup code will not touch them.
  • Prevent initialization of initialized variables by adding the nocopy keyword. In this case, the linker will not add a copy table entry for those sections and the startup code will not touch them. Furthermore, the linker will not create ROM copy sections including the initialization values. Possible use cases might be:
    • A debugger is used which can load the value directly into RAM.
    • The complete application is loaded into RAM. 
  • Prevent unreferenced sections from automated removal by adding the p (protect) attribute. This is applicable when the linker optimization Delete unreferenced sections from the output file is enabled, and although the section is not referenced in the application code, it should not be removed from the linker output.

Adding an attributes entry to a group definition in the LSL file will allow performing these link stage operations.                   

An LSL example demonstrating the use of the nocopy keyword and the s (scratch) attribute:

section_layout :vtc:linear
{
#ifdef DO_NOT_INITIALIZE_CALIB_VALUE
// nocopy is added here to remove the ROM copy section for this initialized data
// and the copy table entry
group CALIBRATION_VALUE ( ordered, run_addr = mem:mpe:dspr0, nocopy )
{
select ".data.file_1.calib_value";
}
#else
group CALIBRATION_VALUE ( ordered, run_addr = mem:mpe:dspr0 )
{
select ".data.file_1.calib_value";
}
#endif

#ifdef DO_NOT_CLEAR_VAR_1
// the scratch attribute 's' is added here to prevent a copy table entry
// to clear this section
group VAR_1 ( ordered, run_addr = mem:mpe:dspr0, attributes = rws )
{
select ".bss.file_1.var_1";
}
#else
group VAR_1 ( ordered, run_addr = mem:mpe:dspr0 )
{
select ".bss.file_1.var_1";
}
#endif
}


The following output shows part of the map file when the non-initialized section .bss.file_1.var_1 is cleared. The size of the copy table section table is 0x90 bytes:

+ Space mpe:vtc:linear (MAU = 8bit)
+------------------------------------------------------------------------------------------------------------------------+
| Chip | Group | Section | Size (MAU) | Space addr | Chip addr | Alignment |
|========================================================================================================================|
...
| mpe:dspr0 | VAR_1 | .bss.file_1.var_1 (171) | 0x00000004 | 0x70000004 | 0x00000004 | 0x00000002 |
...
| mpe:pflash0 | | table (368) | 0x00000090 | 0x8000002c | 0x0000002c | 0x00000004 |
...


The following output shows part of the map file when the non-initialized section .bss.file_1.var_1 is not cleared. This is achieved by defining the DO_NOT_CLEAR_VAR_1 macro in the LSL file.

+ Space mpe:vtc:linear (MAU = 8bit)
+------------------------------------------------------------------------------------------------------------------------+
| Chip | Group | Section | Size (MAU) | Space addr | Chip addr | Alignment |
|========================================================================================================================|
...
| mpe:dspr0 | VAR_1 | .bss.file_1.var_1 (171) | 0x00000004 | 0x70000004 | 0x00000004 | 0x00000002 |
...
| mpe:pflash0 | | table (368) | 0x00000080 | 0x8000002c | 0x0000002c | 0x00000004 |
...

Here, the size of the copy table section table is 0x80 bytes which is smaller because the clear entry for the section .bss.file_1.var_1 is no longer included.

On checking the map file to see what happens to the ROM copy section for the initialized section .data.file_1.calib_value when the initialization is switched off, you can see that the ROM copy section [.data.file_1.calib_value] has disappeared. ROM copy sections of initialized sections have the same name as the initialized section enclosed in square brackets.


Example

The zip file change_section_attributes includes a buildable example using a command line invocation. It can be extracted into an empty folder. The HLL dump tool (hldumptc.exe) is used to dump the copy table section content into a human-readable format. The copy table includes copy and clear entries for sections that need to be initialized or cleared (initialized with zeroes). You can compare the copy table dump files of the individual use cases, to verify the changes in the copy table content.

The gen.bat batch file can be invoked to create the various versions for a later comparison of the map files. A
prerequisite is to add the path to the ctc\bin sub-directory which includes the binaries of the compiler product to the PATH environment variable.

To achieve it, you can use the following command in a command prompt:

set PATH=<path to the ctc\bin folder>;%PATH%

 For example, if the TriCore tools have been installed in the directory C:\Program Files\TASKING\TriCore v6.3r1 then use the command:

set PATH=C:\Program Files\TASKING\TriCore v6.3r1\ctc\bin;%PATH%

When comparing the content of the files named result_var_1_not_cleared.map and result_var_1_cleared.map you'll notice that the
Memory usage in bytes section included in the map file shows only 4 bytes for result_var_1_not_cleared.map instead of the expected 8 bytes. This is due to a known issue related to scratch sections. Those sections are counted as reserved sections by the linker instead of counting them as data sections. The related issue is TCVX-43538 Linker counts scratch sections as reserved sections under 'Memory usage in bytes'.



More resources

Was this answer helpful?