链接器脚本:调试策略?

时间:2013-12-11 18:09:37

标签: linker ld linker-scripts

我正在尝试在编写内核时调试我所拥有的链接器问题。

问题是我有一个我无法使用的变量SCAN_CODE_MAPPING - 它似乎是空的或其他东西。我可以通过改变链接程序的方式来解决这个问题,但我不知道为什么。

当我使用objdump查看生成的二进制文件时,变量的数据肯定存在,所以只有一些内容被引用。

带有两个链接描述文件的

Here's a gist和两个文件之间不同的符号表部分。

令我困惑的是,两个符号表都具有相同的符号,它们的长度都相同,并且它们似乎包含正确的数据。我能看到的唯一区别是它们的顺序不一样。

到目前为止,我已经尝试了

  • 检查SCAN_CODE_MAPPING内存位置以确保它具有我期望的数据并且未被清零
  • 检查所有符号是否相同
  • 检查所有符号内容的长度是否相同
  • 查看.data.rel.ro.local以确保其具有数据地址

一个可能的线索就是这个警告:

warning: uninitialized space declared in non-BSS section `.text': zeroing

我在破碎和正确的案件中都得到了。

我接下来应该尝试什么?

2 个答案:

答案 0 :(得分:5)

这里的问题原来是我正在编写一个操作系统,只有12k的操作系统被加载而不是整个操作系统。所以链接器脚本实际上工作正常。

我用来理解二进制文件的主要工具是:

  • 纳米
  • objdump的
  • readelf

答案 1 :(得分:4)

使用“readelf”可以获得更多信息。

特别是,请看一下程序标题:

readelf -l program

您的BSS部分与标准部分完全不同,可能会引发警告。这是我的系统上的默认设置:

  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 64 / 8 : 1);
  }

如果输入节与链接描述文件中的任何内容都不匹配,则链接器仍然必须将其放在某处。确保覆盖所有输入部分。

请注意,各个部分和细分受众群之间存在差异。链接器使用节,但程序加载器唯一看到的是段。文本段包括文本部分,但也包括其他部分。进入同一段的段必须相邻。所以订单很重要。

rodata部分通常在文本部分之后。它们在执行期间都是只读的,并且会在程序头中显示一次,作为带有读取和放大的LOAD条目。执行权限。该LOAD条目是文本段。

bss部分通常在数据部分之后。它们在执行期间都是可写的,并且会在程序头中显示一次,作为带有读取和放大的LOAD条目。写权限。 LOAD条目是数据段。

如果更改顺序,则会影响链接器生成程序头的方式。在执行程序之前加载程序时,将使用程序头而不是节头。使用自定义链接描述文件时,请务必检查程序头。

如果你能详细说明你的实际症状,那么它会更容易帮助。