您好我有一个GNU链接器ld
的“链接器脚本”,我有两个与之相关的问题:
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(__start)
SECTIONS
{
. = 0x11029000;
.text :
{
__exidx_start = .;
PROVIDE (__gnu_textstart = .);
startup.o(.text .text.*)
*(.text .text.*)
}
.rodata :
{
*(.rodata .rodata.*);
}
__exidx_end = .;
PROVIDE (__gnu_textend = .);
.data :
{
PROVIDE (__gnu_datastart = .);
*(.data .data.*);
PROVIDE (__gnu_dataend = .);
}
.bss :
{
PROVIDE (__gnu_bssstart = .);
*(.bss .bss.*) *(COMMON);
PROVIDE (__gnu_bssend = .);
}
PROVIDE (end = .);
PROVIDE (__end = .);
__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
__EH_FRAME_BEGIN__ = 0;
}
Q1:为什么我们要为同一地址定义多个标签,例如__exidx_start
和__gnu_textstart
?后者使用PROVIDE
定义。
Q2:最后,链接描述文件会像这样计算图像大小:
__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
如果我们像这样计算它,我们会得到相同的结果:
__image_size = ((__exdix_start - __exidx_end) + 511) & ~ 511;
答案 0 :(得分:1)
从http://www.sourceware.org/binutils/docs-2.10/ld_3.html#SEC17开始,看起来使用PROVIDE命令只是在没有其他声明的情况下使用的声明。好处是用户可以选择符号(或者如果他们只是不知道符号)。从某种意义上说,PROVIDE中的定义如果从未在其他地方定义但仍被引用,则将作为各种类型的默认值。
鉴于此,我认为__gnu_textstart
应该是__exidx_start
的别名,因此 Q2 的答案是的,因为符号引用相同的位置。