Linker 链接器脚本混乱-为什么需要多个标签?

Linker 链接器脚本混乱-为什么需要多个标签?,linker,linker-scripts,Linker,Linker Scripts,您好,我有一个GNU链接器ld的“链接器脚本”,我有两个相关问题: OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(__start) SECTIONS { . = 0x11029000; .text : { __exidx_start = .; PROVIDE (__gnu_textstart = .);

您好,我有一个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:为什么我们要为同一个地址定义多个标签,如
\uuuuuexidx\ustart
\uuuuugnu\utextstart
?后者是使用
PROVIDE
定义的

Q2:最后,链接器脚本计算图像大小,如下所示:

__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
__image_size = ((__exdix_start - __exidx_end) + 511) & ~ 511;
如果我们这样计算,会得到同样的结果吗

__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
__image_size = ((__exdix_start - __exidx_end) + 511) & ~ 511;
从这个角度看,只有在不使用另一个声明的情况下,使用PROVIDE命令才意味着作为声明。这样做的好处是,用户可以根据自己的选择定义符号(或者如果他们只是不知道符号)。从某种意义上说,如果提供中的定义从未在其他地方定义,但仍被引用,那么它将充当排序的默认值

鉴于此,我假设
\uu gnu\u textstart
\uu exidx\u start
的某种别名,因此Q2的答案是肯定的,因为这些符号引用了相同的位置。

从它看来,只有在不使用另一个声明的情况下,使用“提供”命令才意味着声明。这样做的好处是,用户可以根据自己的选择定义符号(或者如果他们只是不知道符号)。从某种意义上说,如果提供中的定义从未在其他地方定义,但仍被引用,那么它将充当排序的默认值


鉴于此,我假设
\uu gnu\u textstart
\uu exidx\u start
的某种别名,因此Q2的答案是肯定的,因为符号引用相同的位置。

我认为这两个都是指定的,因为您的程序开始地址和文本节都需要定义。我认为这两个都是指定的,因为您的程序开始地址和文本节都需要定义。