为什么ld在输出文件中包含未在链接命令文件中指定的部分?

3
我很难理解如何让gcc arm嵌入式工具包中的ld做我想要的事情:
举个例子,我有一些.o文件需要链接。假设我只想在输出中包含名为.foo的一个部分。我将此内容放入命令文件link.ld中:
SECTIONS{
  .foo : {*(.text)}
}

然后我使用"ld -T link.ld file1.o fil2.o -o output.o"命令,并在output.o上使用objdump,它只包含输入文件中的每个部分(),绝对没有名为.foo的部分,这是最令人困惑的部分。为什么输出中没有名为.foo的部分?

我阅读了这篇文章http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html,并且看起来很简单,但我无法理解为什么如此简单的链接器脚本根本没有做我想要做的事情。

我一定漏掉了非常明显的东西;有人能解释一下如何精确控制出现在输出文件中的部分以及它们的名称吗?

1个回答

3

嗯,你不能轻易地控制这个-正如你所看到的。如果您不“明确”链接某些部分(在这种情况下,您可以控制诸如顺序、对齐、位置、填充等方面的内容),链接器发现必要的其他所有内容都会被放置“在其后”。这是一种简化,但这通常是这样工作的。

我认为没有办法告诉链接器仅包含您请求的部分。但有一种方法可以告诉它排除一些部分。但问题是,您必须明确要排除的部分。

3.6.7 输出节丢弃

...

特殊的输出节名称/ DISCARD /可用于丢弃输入节。分配给名为/ DISCARD /的输出节的任何输入节都不包括在输出文件中。

也许像这样的东西会起作用?

SECTIONS{
  .foo : {*(.text)}
  /DISCARD/ : {*(*)}
}

1
我认为没有办法告诉链接器仅包含您请求的部分。那么链接器脚本的意义是什么?让我感到困扰的是,我还尝试了-gc-sections -print-gc-sections,它打印“正在删除未使用的部分...”,但这些部分仍然出现在输出中!这些部分与任何其他部分都没有链接/符号。 - Jesse
还有另一个问题:有时,链接器脚本中连续指定的部分似乎会在输出文件中以相同的地址结束。这必须是ld中的一个错误:我所做的只是:.=0x08000000 section1 section2但是第二个部分与第一部分重叠。这种荒谬的事情让我发疯了,我已经花了3天时间尝试解决这些问题,而这应该是最简单的玩具示例链接器脚本。 - Jesse
@Jesse - 链接脚本的目的是告诉链接器如何对数据进行排序,以便代码位于闪存中,向量位于开头,变量位于RAM中,并且这些变量的副本可在闪存中使用(用于初始化)。链接器中没有错误,请相信我。从一个完整的工作链接脚本开始,逐步删除/修改其元素,直到输出与您的期望匹配或执行意外操作为止。这是一个适用于STM32F1的简单脚本- https://gist.github.com/FreddieChopin/3dee4b02b0ba9b9de518f30c14caa884 (由http://distortos.org/生成) - Freddie Chopin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接