我正在尝试外部程序和各种链接方法,以更好地理解链接过程。
我有三个文件:
foo.c:
#include "foo.h"
int a = 4;
测试.c:
#include <stdio.h>
#include "foo.h"
int main(int, char**);
int mymain();
int mymain() {
main(0, 0);
printf("test\r\n");
return 0;
}
int main(int argc, char** argv) {
printf("extern a has %d\r\n", a);
return 0;
}
foo.h:
extern int a; // defined in foo.c
如果我将每个文件构建在一起并在编译时使用 gcc 进行链接,如下所示:
gcc *.c -o final.bin
我可以执行final.bin:
./final.bin
并获得预期输出
extern a has 4
但是,如果我分别编译(但不链接)test.c 和 foo.c,然后尝试在运行时将对象文件链接在一起以生成二进制文件,则会出现段错误 11(来 self 的信息)可以收集到一些通用的内存损坏错误,例如正常的段错误(?)
这是我用来单独编译和链接的 makefile。注意我指定了我自己的入口点并链接到 libc 以获取 printf()...
all: test.o foo.o
@echo "Making all..."
ld test.o foo.o -o together.bin -lc -e _mymain
test.o: test.c
@echo "Making test..."
gcc -c test.c -o test.o
foo.o: foo.c
@echo "Making foo..."
gcc -c foo.c -o foo.o
运行“together.bin”时的输出:
./together.bin
extern a has 4
test
Segmentation fault: 11
也许我的“mymain”函数签名是错误的?我的猜测是我的“myentry”用法有问题。
此外,如果有人对链接器和加载器如何工作有任何好书推荐,我肯定会在市场上寻找一本。我听说过关于“链接器和加载器”的好坏参半的事情,所以在我专门花时间在那本书上之前,我正在等待更多的意见。
感谢您对此的任何帮助...至少可以说,我对链接器的理解是低于标准的。
最佳答案
除非您有充分的理由这样做,否则只需使用 gcc 进行链接:
$ gcc test.o foo.o "-Wl,-e,_mymain" -o ./final.bin; ./final.bin
extern a has 4
test
gcc 调用 ld——不过,参数比您在示例中提供的参数多一些。如果您想确切地知道 gcc 如何调用 ld,请使用 -v
选项。示例:
$ gcc -v test.o foo.o "-Wl,-e,_mymain" -o ./final.bin
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -o ./final.bin test.o foo.o -e _mymain -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
关于c - 将两个目标文件链接在一起会导致段错误 11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39693962/