我怎样才能让 LD 始终将入口点放在 -Ttext 的位置?

How can i get LD to put always put the entry point at the location of -Ttext?

我正在编写自己的操作系统(静态地址),我努力让链接器始终将我的 _start 函数放在进程中我想要的位置。我在我的构建文件中指定了 -Ttext 0x10000 的位置(对于这个例子,我们只说 0x10000)。

通常这有效,但是当我使用 -O2 时,链接器将我的 main 函数放在这个地址上。

那么我怎样才能确定它是 _start 最终出现在这个地址上的呢? 是否可以不编写链接描述文件?

函数 _start 对所有进程都是通用的,在程序 returns 而不是调用 exit() 的情况下,应该为调度程序强制退出。我脑子里有一个变通解决方案,但我更愿意使用链接器来解决这个问题。

所以我找到了 2 个解决方案。

  1. 在包含 _start
  2. 的文件中设置 .section .text.startup
  3. 在包含_start
  4. 的文件中设置.section .text.mustbefirst(我自己的段名)

在第一个变体中,我只是确保开始代码也包含在与包含 main 的代码相同的顺序中,尽管存在一些歧义,但这在我的情况下确实有效。

在第二个变体中,我修改了默认的链接描述文件以确保我的节符号是第一个。

如果第一个是可靠的(例如,取决于参数的顺序或其他),那么就可以了。作为旁白;有人知道吗?如果没有,那么我会推荐一个新的节符号和修改后的链接描述文件。

将此添加到您的链接描述文件中(例如,如果您的启动文件是 crt0.o,其中包含 _start

STARTUP(crt0.o)

(在 https://wiki.osdev.org/Linker_Scripts#STARTUP 找到)

现在(对我来说是 powerpc)文件开头的反汇编产生:

main.elf:     file format elf32-powerpc

Disassembly of section .text:

01800154 <_start>:
 1800154:       94 21 ff e0     stwu    r1,-32(r1)
 1800158:       7c 08 02 a6     mflr    r0
 180015c:       93 61 00 0c     stw     r27,12(r1)
 1800160:       93 81 00 10     stw     r28,16(r1)

否则,_start 符号要么不存在(如果未指定入口点),要么在文件中间(即使定义了入口点,这也可能是个问题,因为某些加载程序只是忽略入口点信息并在文件开头跳转)