1

您好,我有一个 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;
4

1 回答 1

1

http://www.sourceware.org/binutils/docs-2.10/ld_3.html#SEC17看来,使用 PROVIDE 命令仅在没有其他声明的情况下才用作声明。好处是符号可以由用户在他们选择时定义(或者如果他们只是不知道符号)。从某种意义上说,如果 PROVIDE 中的定义从未在其他地方定义但仍被引用,它将充当排序的默认值。

鉴于此,我认为这__gnu_textstart意味着它是某种别名,__exidx_start因此Q2的答案是肯定的,因为这些符号引用了相同的位置。

于 2013-12-06T17:01:56.483 回答