为什么部分名称以点开头?关于命名部分的问题

问题描述 投票:0回答:1

直到最近我还认为部分名称通常必须以点

.
开头。然而,在研究我的 bare-metal-C-IDE 的示例链接器文件时,我注意到似乎有一个例外:
COMMON
部分。

.text :
{
    KEEP(*(.isr_vector))
    *(.text*)

    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata*)

    KEEP(*(.eh_frame*))
} > ROM

.bss (NOLOAD):
{
    *(.bss*)
    *(COMMON)
} > RAM

这使我得出结论,以

.
开头的部分名称似乎只是一个 约定 而不是 要求

所以,我的问题是:

  • 节名以点开头的原因是什么?我想建立这个公约是有一个(也许是历史上的?)原因的。
  • 为什么
    COMMON
    例外?
  • 为什么输出节通常与输入节同名?让我感到相当困惑的是,我的
    .bss
    输出部分中实际上包含非
    .bss
    部分。
    .text
    部分也是如此。我的
    .text
    输出部分包含大量非
    .text
    部分。为什么为它们提供自己的输出部分并不常见?这样不是更符合逻辑吗?

这背后有什么真正的原因吗?或者事情就是这样吗

c linker ld sections
1个回答
0
投票

节名以点开头的原因是什么?

正如 @cremno 在评论中指出的,之所以使用点作为链接部分的前缀,是因为 ELF(可执行和可链接格式)规范存档)为系统保留它们。在第一本书中,第 14 页。 16(第 30 页):

带点 (.) 前缀的节名称是为系统保留的,尽管应用程序可以使用这些节(如果它们的现有含义令人满意)。应用程序可以使用不带前缀的名称,以避免与系统部分发生冲突。目标文件格式允许定义不在上面列表中的部分。一个目标文件可能有多个同名部分。

该规范还在第一册第 15-16 页(第 29-30 页)中定义了标准部分的名称和含义 -

.text
.rodata
.data
等。

为什么
COMMON
例外?

因为开发人员想要这样做,并且规范允许他们做出例外。在这种情况下,做出这样选择的可能是 Fortran 编译器的开发人员。如上所述,如果标准部分适合应用程序的需要,应用程序“可以”使用标准部分。显然这些开发人员认为需要一个非标准的部分名称。 为什么输出节通常与输入节同名?为什么不为每个输入部分提供单独的输出部分?

您回答第一个问题:“这相当令人困惑......”。确实如此!这种混淆正是定义新节时通常使用输出节名称作为前缀的原因。这样做可以使最终结果更加可预测,并允许开发人员忽略链接描述文件的存在,因为大多数链接描述文件都为这些部分定义了通配符。

输入节可能被放置到不同名称的输出节中的原因是因为给定的(引导)加载程序或应用程序不知道所述节(输入或输出)的存在。也许您有非标准部分,例如示例中的

.ctor

.dtor
部分,并且目标系统仅与
.text
.rodata
.bss
.data
部分加载/交互。或者,也许您正在编写一个代码生成器,并且包含已编译代码片段的
.text
段的某些部分需要放置在
.rodata
段中以进行读取访问。
这背后有什么真正的原因吗?还是事情就是这样?

答案是肯定的。有些人同意以任意方式做事,我们遵循他们的协议,因为他们编写了一堆我们需要完成工作的有用软件。

© www.soinside.com 2019 - 2024. All rights reserved.