如果从部分中删除了NOLOAD,则从elf文件生成的二进制文件会爆炸

时间:2019-03-13 15:09:36

标签: gcc linker linker-scripts objcopy

我们有一个带有自定义部分的链接脚本,出于某些IEC一致性测试的原因而添加了该脚本。但是,自从添加此部分以来,通过objcopy -O binary input output创建的二进制大小已经从〜150kbytes膨胀到了〜512bbytes。

我已将其追溯到缺少(NOLOAD)属性的部分。而且我也可以对为什么二进制文件为512Mbytes有所了解。

我们的记忆如下:

MEMORY
{
    rom    (rx)  : ORIGIN = 0x00000000, LENGTH = 0x00040000
    ram    (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00007580

    CUSTOM_SECTION (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00001000
}

最初定义的部分是:

    CUSTOM_LOCATION:
    {
        CUSTOM_BEGIN = .;
        KEEP(*(CUSTOM_LOCATION));
        CUSTOM_END = .;

    } > CUSTOM_SECTION AT > ram

如果将CUSTOM_LOCATION:替换为CUSTOM_LOCATION (NOLOAD):,则生成的二进制数是正常值。如果没有(NOLOAD),则二进制文件大小约为512Mb。

我正在寻找此二进制文件变得如此大的原因。 (NOLOAD)(或没有它)对于objcopy生成二进制文件意味着什么?

第二个问题,在本节末尾我们说} > CUSTOM_SECTION AT > ram,如果没有此指令,我们可以做什么?可以将其替换为} > ram吗? (这可以从CUSTOM_SECTION部分中删除MEMORY吗?

我发现生成的map文件中没有差异

1 个答案:

答案 0 :(得分:1)

当objcopy创建一个二进制文件时,它基本上与OS ELF加载器执行相同的工作:它将可加载的ELF文件节写入一个表示运行时内存的文件中。

二进制文件将包含代码和数据的每个字节,从基地址到最高字节。如果内存映像稀疏(存在“无”区域),则二进制文件也将包含大的无区域。只能在哑的二进制文件中将其表示为零。

您的elf文件具有从地址0x00000000(ROM的底部)到0x20000fff(CUSTOM_SECTION的顶部)的数据,其范围刚刚超过500MB,因此可以认为二进制文件必须具有那么多字节容纳一切。通过使该部分不可装载,您说的是在运行时不需要数据,因此不需要在二进制映像中。调试信息,注释和其他非程序ELF数据通常是这种情况。

好消息是:a)许多文件系统仅将磁盘空间用于文件的非零部分,因此它使用的磁盘数量不如显示的少(“稀疏文件”),并且b)二进制文件将易于压缩。