我正在构建自己的 32 位 x86 操作系统,在其中从 ELF 文件加载用户程序。当编译用户 C 程序时,我使用
-nostdlib
来排除 GLIBC 并链接我自己的 LIBC。问题是,这样做时,程序在编译时没有 _start
标签,导致 entry
(在 ELF 标头中定义)指向文件中的第一段代码,而不是程序的实际条目。
我不确定如何在没有标准库的情况下进行编译,但仍具有程序的有效入口点。
使用
-nostdlib
标志编译时,我得到:
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
ELF 文件:
Entry point address: 0x8049000
如何在没有stdlib的情况下生成
_start
?
我应该并且可以自己编写它并在编译时将其与用户程序链接吗?
我的困惑来自于
_start
函数的来源。显然, _start
函数是标准库的一部分,位于 crt0.S
文件中。
crt0(也称为 c0)是一组链接到 C 程序的执行启动例程,用于在调用程序的主函数之前执行所需的任何初始化工作。
当使用
-nostdlib
标志进行编译时,GCC 会从程序中删除 GLIBC 及其 _start
例程 - 导致链接器引发错误,告知它找不到用于设置条目的符号。
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
我通过在 libc 中创建自己的
crt0.S
文件并在其中创建一个与用户程序链接的自定义 _start
函数来修复此问题。
所以对于我的问题我会回答:
如何在没有stdlib的情况下生成
?我应该并且可以自己编写它并在编译时将其与用户程序链接吗?_start
您应该在操作系统的标准库中提供您自己的
_start
函数定义,并将其与用户程序链接。