在引导加载器中,我有一个没有显式使用的版本字符串,但必须出现在ROM中的特定位置,以便由所述引导加载程序加载的应用程序访问。在源文件version.cpp中,我有:
// 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 ;
通过散射文件实现位置:
LR_VERSION_IROM1 0x08001FF0 0x00000010
{
VERSION_IROM1 0x08001FF0 0x00000010
{
version.o (+RO)
}
}
这看起来很复杂,但在基于LLVM/Clang的v5中不再支持以前在armcc v6中有效的方法。
然而,当__attribute__((used))
阻止未使用的对象正常被删除时,当LTO (链接-时间优化)被启用时,链接器就会删除它。因为在本例中,我试图将引导保持在8Kb内,所以LTO在其他方面是有用的。
我收到链接器警告:
.\bootrom.sct(21): warning: L6314W: No section matches pattern version.o(RO).
因此,VERSION_IROM1
是空的,而如果没有启用LTO,则按需要定位它,但在本例中不使用向图像大小添加560字节。
工具链详细信息:
Toolchain: MDK-ARM Plus Version: 5.36.0.0
C Compiler: ArmClang.exe V6.16
Linker/Locator: ArmLink.exe V6.16
是否有防止LTO删除此对象文件的方法?
我尝试使用volatile
限定符,并在代码中包含一个虚拟引用,但都没有效果。
此外,我尝试了链接器选项--keep=bootmainVersionString
,但在启用LTO的情况下,这两种方法都不起作用,而且也不会产生__attribute__((used))
无法达到的效果。
但是,我注意到该对象存在于链接中,但不在散布文件的位置。在地图文件中:
没有LTO (如预期的位置):
bootmainVersionString 0x08001ff0 Data 16 version.o(.rodata.bootmainVersionString)
与LTO (由链接器定位):
bootmainVersionString 0x0800130c Data 16 lto-llvm-dbc16f.o(.rodata)
发布于 2022-09-10 11:08:35
.\bootrom.sct(21):警告: L6314W:没有部分匹配模式version.o(RO)。
启用LTO时,不能在分散文件中明确使用对象名称,因为链接器只能看到字节码,而不能看到对象文件。
你可以通过以下方式解决这个问题:
VERSION_STRING
__attribute__((section("version")))
将分散文件片段修改为:LR_VERSION_IROM1 0x08001FF00x000010{ VERSION_IROM1 0x08001F0x000010{ version (+RO,+FIRST) } }
https://stackoverflow.com/questions/73407563
复制相似问题