1

In a bootloader I have a version string that is not explicitly used, but must be present at a specific location in ROM for access by the application loaded by said bootloader. In a source file version.cpp I have:

// Place version string at end of bootrom less 16 bytes
#define VERSION_STRING "090600.01.00.00"
#define MAX_VERSION_STRING_LENGTH 0x10

const char bootmainVersionString[MAX_VERSION_STRING_LENGTH] __attribute__((used)) = VERSION_STRING ;

And the location is achieved via the scatter file:

LR_VERSION_IROM1 0x08001FF0 0x00000010  
{                         
  VERSION_IROM1 0x08001FF0 0x00000010 
  {
    version.o (+RO)
  }
}

This may seem rather convoluted but previous methods valid in armcc v5 are no longer supported in the LLVM/Clang based v6.

However, while the __attribute__((used)) prevents the unused object being removed normally, the linker removes it when LTO (Link-time Optimisation) is enabled. Since I am trying to keep the bootrom inside 8Kb in this case, LTO is otherwise useful.

I get a linker warning:

.\bootrom.sct(21): warning: L6314W: No section matches pattern version.o(RO).

so VERSION_IROM1 is empty, whereas without LTO enabled it is located as required, but not using adds ~560 bytes to the image size in this case.

Toolchain details:

Toolchain:          MDK-ARM Plus  Version: 5.36.0.0
C Compiler:         ArmClang.exe  V6.16
Linker/Locator:     ArmLink.exe   V6.16

Is there a means of preventing LTO from removing this object file?

I have tried using a volatile qualifier, and including a dummy reference in the code, to no avail.


Further I have tried the linker option --keep=bootmainVersionString, but that does not work either with LTO enabled, and has no effect otherwise that __attribute__((used)) does not achieve.

However I have noticed that the object is present in the link, but not located per the scatter file. In the map file I have:

Without LTO (located as intended):

bootmainVersionString    0x08001ff0   Data   16  version.o(.rodata.bootmainVersionString)

with LTO (located by the linker):


bootmainVersionString    0x0800130c   Data   16  lto-llvm-dbc16f.o(.rodata)
Clifford
  • 88,407
  • 13
  • 85
  • 165

1 Answers1

1

.\bootrom.sct(21): warning: L6314W: No section matches pattern version.o(RO).

You cannot use object name explicitily in the scatter file when LTO is enabled as the linker can only see the bytecode instead of object files.

You could solve the problem by:

  1. use __attribute__((section("version"))) to modify VERSION_STRING
  2. change the scatter file snippet to something like:
LR_VERSION_IROM1 0x08001FF0 0x00000010  
{                         
  VERSION_IROM1 0x08001FF0 0x00000010 
  {
    version (+RO, +FIRST)
  }
}
cartman
  • 732
  • 2
  • 8
  • 20
  • I'll give that a go, but I think that was one of the methods I tried previously. I recall that the linker refused to fit the variable when the section was exactly the same size as the variable. Making the section larger by a few bytes allowed to fit but then the actual location was ambiguous. However this is a newer tool chain so perhaps it will differ. – Clifford Sep 10 '22 at 14:20
  • Hmmm. I have `__attribute__((used,section("version")))` and the scatter file change you suggested and: `error: L6236E: No section matches selector - no section to be FIRST/LAST.` and without `+FIRST` simply: `warning: L6314W: No section matches pattern version(RO).`. Both occur with or without LTO. Which is probably where I started. – Clifford Sep 13 '22 at 15:43