c - 将二进制 blob 与 GCC 链接时的奇怪行为

标签 c gcc linker ld

我将 ARM Cortex-M 的 C 程序中的二进制数据与 GCC 链接起来,如下所示:

arm-none-eabi-ld.exe -r -b binary -o html.o index.html

为了处理数据,我有这些外部变量:

extern const unsigned char _binary_index_html_start;
extern const unsigned char _binary_index_html_end;
extern const uint32_t _binary_index_html_size;

static const char* html = &_binary_index_html_start;
static const size_t html_len = &_binary_index_html_size;

我不明白的是为什么我需要获取 _binary_index_html_size 变量的地址来获得大小值?

这意味着 _binary_index_html_size 变量的内存地址(指针)表示 blob 的大小值(以字节为单位)。当我调试它时它似乎是正确的,但对我来说这似乎是一个非常奇怪的解决方案。

编辑:
我猜原因可能是:因为 blob 的大小永远不能大于 native 数据大小(在我的例子中是 2^32),而不是浪费空间和存储大小 GCC 只是创建一个指向的变量表示 blob 大小的内存地址。所以这个值是完全随机的,取决于其他代码(我测试过这个)。这似乎是一件很聪明的事情,因为大小不占用空间并且指针在编译时被解析。因此,如果不需要该大小,则不会浪费任何空间。
我想我会改用 (&_binary_index_html_end) - (&_binary_index_html_start),这看起来更好并且得到所有编译器的支持。

最佳答案

您正在处理的所有符号都是链接描述文件定义的变量,它们的访问方式与您完全相同。 ld documentation 中对此的解释非常清楚。 .

When a symbol is declared in a high level language such as C, two things happen. The first is that the compiler reserves enough space in the program's memory to hold the value of the symbol. The second is that the compiler creates an entry in the program's symbol table which holds the symbol's address. ie the symbol table contains the address of the block of memory holding the symbol's value.

然后,稍后在文档中,我们可以找到以下内容。

Linker scripts symbol declarations, by contrast, create an entry in the symbol table but do not assign any memory to them. Thus they are an address without a value.

这意味着链接器定义变量的地址确实是它的实际值,这就是为什么您必须采用这样的地址才能读取与链接器符号关联的值。 p>

关于c - 将二进制 blob 与 GCC 链接时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38300908/

相关文章:

python - 如何在 LinuxOS 中从 python 脚本运行/停止 c 程序?

.net - native VC++ 6 应用程序中的托管 DLL

c++ - 在 Ubuntu 上链接 OpenCV 2.3.1

c - 编译动态库时消除对 MinGW 特定 DLL 的依赖

c - 当两个指针以不同方式分配字符串时,strcpy 的行为不同

c - strcpy 的问题

c - 如何使用指针表示法访问动态结构

c - 包含来自静态库的头文件

c - 如何在编译时禁止使用全局变量

c - 为什么我的编译守卫不能阻止多重定义包含?