Gcc 链接器脚本中的内存命令以二进制大小膨胀
我想有一个映像,它加载在两个不同的内存位置,所有地址链接都在编译/链接时完成 我想达到的总体目标 为文本和数据定义不同的加载区域 根据加载地址解析所有符号相关性 将文本和数据区域背靠背地放在图像中我的加载程序将在运行时将文本部分放在不同的地址 因此,我创建了以下脚本Gcc 链接器脚本中的内存命令以二进制大小膨胀,gcc,linker,linker-scripts,Gcc,Linker,Linker Scripts,我想有一个映像,它加载在两个不同的内存位置,所有地址链接都在编译/链接时完成 我想达到的总体目标 为文本和数据定义不同的加载区域 根据加载地址解析所有符号相关性 将文本和数据区域背靠背地放在图像中我的加载程序将在运行时将文本部分放在不同的地址 因此,我创建了以下脚本 MEMORY { mem1 : ORIGIN = 0xfff00000, LENGTH = 100K mem2 : ORIGIN = 0xfff80000, LENGTH = 100K } SECTIONS {
MEMORY
{
mem1 : ORIGIN = 0xfff00000, LENGTH = 100K
mem2 : ORIGIN = 0xfff80000, LENGTH = 100K
}
SECTIONS
{
. = 0xfff00000;
_image_base_origin = . - 0;
////////////////////////////////
// TEXT
////////////////////////////////
.text : {
_text_origin = .;
. = ALIGN(4); _text_offset = . - _image_base_origin; *(.vectors) *(.text) *(.eh_frame)
} > mem2
_text_size = . - _text_origin;
////////////////////////////////
// DATA
////////////////////////////////
.data : {
_data_origin = .;
. = ALIGN(8); _data_offset = . - _image_base_origin; *(.data) *(.comment) *(.rodata*) *(.bss*)
} > mem1
_data_size = . - _data_origin;
}
我面临的问题是,当我将图像的文本部分放入mem2时,二进制文件的大小增加了很多倍
如果我在我的文件上运行readelf
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 5] .text PROGBITS fff80000 020000 0017a8 00 AX 0 0 32
[ 6] .data PROGBITS fff00398 010398 0004f8 00 WA 0 0 8
所以图像大小变成80000+17a8。它在图像中添加mem2的偏移量并创建二进制文件。它用零填充所有额外内存
如果我只把文本部分放在mem1中,我的图像大小非常小,它不会给我的图像增加偏移80000
您能在这里帮助我吗。较大的文件大小无疑是为了满足vma%pagesize==文件偏移量%pagesize的分页要求。如果您的系统没有按需分页,那么您可以链接到-n。如果您的系统是按需分页的,则ld默认页面大小可能过大。-z max page size选项可以解决这个问题。谢谢。我的系统没有按需分页。使用-n选项,我可以看到图像大小的改进。但当我使用objcopy从out文件复制到二进制文件时,我面临同样的问题。我想删除elf头并创建一个原始二进制文件。所以我使用了objcopy的-O选项。虽然elf图像的大小现在在-n选项之后变小了,但在objcopy二进制文件扩展到最大文本LMA+文本大小之后仍然如此。我也使用了剖面对齐0,但仍然存在相同的问题。