【问题标题】:Strange behaviour when linking binary blob with GCC将二进制 blob 与 GCC 链接时的奇怪行为
【发布时间】:2016-07-11 07:01:13
【问题描述】:

我在我的 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 的大小永远不会大于本机数据大小(在我的情况下为 2^32),而不是浪费空间和存储大小 GCC 只是创建了一个指向表示 blob 大小的内存地址。所以这个值是完全随机的,取决于其他代码(我测试过这个)。这似乎是一件聪明的事情,因为大小不占用空间并且指针在编译时被解析。因此,如果不需要尺寸,则不会浪费空间。
我想我会改用(&_binary_index_html_end) - (&_binary_index_html_start),这似乎更好,并且所有编译器都支持。

【问题讨论】:

  • static const size_t html_len = &_binary_index_html_size; 对我来说似乎是一个错误。谁说你需要它?
  • 变量_binary_index_html_size 包含一些随机数据,可以在重新编译时更改。但是这个变量的地址正是blob的大小。
  • 这是一种节省空间的巧妙方法,但它与标准 C 不兼容。也许如果 blob 部分是用汇编编写的,它可以使用这种方法。
  • @n.m.我认为这是正确的,谢谢。如果你把它作为一个答案,我会接受它。

标签: c gcc linker ld


【解决方案1】:

您正在处理的所有符号都是链接器脚本定义的变量,它们的访问方式与您完全一样。对此的解释在ld documentation中给出了非常清楚的说明。

当一个符号用 C 等高级语言声明时,两个 事情发生。首先是编译器在里面预留了足够的空间 程序的内存来保存符号的值。第二个是 编译器在程序的符号表中创建一个条目 保存符号的地址。即符号表包含地址 保存符号值的内存块。

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

相比之下,链接器脚本符号声明在 符号表,但不为它们分配任何内存。因此他们是 没有值的地址。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-20
    • 2018-03-14
    • 2011-12-01
    • 2012-02-18
    • 2011-04-09
    • 2012-04-12
    • 2016-03-25
    • 1970-01-01
    相关资源
    最近更新 更多