可以在C代码中将链接器脚本符号地址作为编译时常量值吗?

Lil*_*lás 7 c embedded gcc bare-metal linker-scripts

我想得到我的程序结束的地址,并在编译/链接器时检查我是否有足够的空间,在代码之后,在执行时间放置一些随机数据.

但是由于PROVIDE关键字提供的符号与C代码中的常规变量一样,我无法在编译时验证它.

在链接器脚本中我有符号:

PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));
Run Code Online (Sandbox Code Playgroud)

所以我可以用这个符号来获取代码结尾的地址:

extern u16 __data_end_rom;
Run Code Online (Sandbox Code Playgroud)

如果我认为结束地址是0xffff,我可以计算可用内存:

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
Run Code Online (Sandbox Code Playgroud)

我正在考虑使用gcc 4.6中提供的_Static_assert(cond,message)检查可用内存

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");
Run Code Online (Sandbox Code Playgroud)

我的问题是:宏AVAILABLE_MEM不是在编译时计算的,所以我收到错误:

error: expression in static assertion is not constant
Run Code Online (Sandbox Code Playgroud)

有没有办法直接在标签中或以其他方式提供__data_end_rom地址?

我知道我无法在编译时得到它,因为符号只会在链接器时间内链接,所以有一些方法可以使链接器失败?

我可以直接在链接器脚本中检查这个,但我不喜欢这样做,因为SIZE_I_WANT_TO_ASSURE是从配置头中的其他宏计算的另一个宏.

Joh*_*ham 6

您可以创建一个包含断言的自定义链接描述文件.看这里

http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html

你想使用'ASSERT'机制.


Mat*_*son 5

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");

error: expression in static assertion is not constant
Run Code Online (Sandbox Code Playgroud)

这里的问题是,您正在尝试比较一个在编译的链接阶段生成的“常量”,该表达式需要一个编译时间常数(即,COMPLER在编译过程中知道的东西)。

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)
Run Code Online (Sandbox Code Playgroud)

编译器将不知道的地址__data_end_rom,只有链接器知道。

不幸的是,我认为在编译时没有任何方法可以使编译器告诉您数据太大。另一方面,读取二进制文件的其他脚本(例如size yourprog,结合使用awk或一点点的东西)应该能够以makefile或类似的方式提供相关信息。