当我执行以下命令来制作可执行文件时,就可以了
ld -o xxx a.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o
但是,当我添加如下所示的
--entry
选项时,将生成可执行文件,但是当我执行可执行文件时,出现 Segmentation fault (core dumped)
错误。
ld -o xxx a.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o --entry=main
平台是
gcc-14.1.0
和Ubuntu 22.04.4 LTS
发生这种情况是因为 GNU/linux C 程序开始执行所需的入口符号不是
main
,而是 _start
,其定义在
您正在链接的目标文件 /usr/lib/x86_64-linux-gnu/crt1.o
。其符号表为:
$ readelf -Ws /usr/lib/x86_64-linux-gnu/crt1.o
Symbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 SECTION LOCAL DEFAULT 3 .text
2: 0000000000000000 32 OBJECT LOCAL DEFAULT 2 __abi_tag
3: 0000000000000030 5 FUNC GLOBAL HIDDEN 3 _dl_relocate_static_pie
4: 0000000000000000 38 FUNC GLOBAL DEFAULT 3 _start
5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND main
6: 0000000000000000 0 NOTYPE WEAK DEFAULT 8 data_start
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 5 _IO_stdin_used
9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __libc_start_main
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 8 __data_start
当调用
_start
时,它会执行 重要的运行时初始化,
然后调用 main
(在链接的其他地方定义)来进入你的代码。如果您通过强制输入符号为 main
来跳过这些初始化,那么就会出现段错误。