使用ld链接动态链接的可执行文件

5

我正在尝试创建一个动态链接的可执行文件(elf_i386),但不使用gcc。该程序非常简单(仅包含一个printf)...以下是命令:

$ gcc -c simple.c
$ ld -o simple -dynamic-linker /lib/ld-linux.so.2 --entry main /usr/lib/crt1.o /usr/lib/crti.o simple.o -lc /usr/lib/crtn.o

可执行文件已创建,file命令和ldd命令也显示了正确的输出...然而,在调用printf后启动程序时,我收到了一个“分段错误”的错误提示...我使用objdump检查了可执行文件,我认为问题出在dtors上...似乎是编译时出了问题:
$gcc -o simple simple.c

在直接使用ld创建的可执行文件中,不存在一个名为.dtors的部分,而在其他情况下存在。

有什么想法吗?


如果你想得到帮助,就需要展示你的代码。 - johnsyweb
2个回答

7
放弃--entry main参数。 main不是你的入口点,_start才是。试试这个:
$ gcc -c hello.c
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o hello.o -lc /usr/lib/crtn.o
$ ./hello
hello, world
$ 

对于x86_64 + C++,请使用以下命令:ld -o hello hello.o --dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o -lstdc++ -lc /usr/lib64/crtn.o -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2/ -lgcc_s -L /usr/lib64将.../x86_64-redhat-linux/目录替换为正确的libstd++.so路径,使用"g++ -print-search-dirs"命令。 - ACyclic
谢谢您,魔法是-dynamic-linker /lib/ld-linux* /lib/crt*。 - Eduen Sarceño

2

我想你不需要包含C运行时环境,除非你在main()函数中使用了return

我们可以去掉CRT并使用以下方法链接:

ld -o hello -lc -dynamic-linker /lib/ld-linux.so.2 hello.o -e main

会起作用。


2
这在Linux上使用glibc可以工作,因为glibc使用动态链接钩子来调用其启动函数。如果您静态链接glibc并调用诸如printf或malloc之类的函数而没有手动调用其init函数,则会出现segfault。https://dev59.com/ZFoU5IYBdhLWcg3w_KmO - Peter Cordes
1
其他平台,如MinGW,没有这个功能,您需要在使用某些函数之前手动从“_start”调用libc init函数。 - Peter Cordes

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