基本上,我已经发布了一些有关我的问题的问题。但是,我确实相信这是一个不同的问题。
简单来说,带有某些buildmode选项集的Go工具会创建一个非PIC .o文件(例如app.o)和一个PIC共享库(例如libmain.so)。顾名思义,libmain.so的内部确实具有THE main函数。
然后,Go工具调用编译器驱动程序gcc来链接.o和.so以创建可执行文件,而不一定是PIE。为简化起见,Go工具调用的链接器命令如下:
$ gcc -o app.x -L. -lmain -Wl,-rpath=$PWD -fuse-ld=gold app.o
问题是这个。至少三位专家确认,必须使用Scrt1.o链接它们,因为main位于PIC共享库中。但是,gcc会撤出crt1.o。
我的问题是这是gcc错误还是用户的错误。当然,如果用户在上面的链接命令中添加了“ -pie”选项,则gcc将改用Scrt1.o。但是,用户可能会声称,由于他们可能不需要位置独立的可执行文件,因此添加“ -pie”可能没有太大意义。
我试图在gcc手册中找到适当的信息,但未成功。在这种情况下,用户应该指定“ -pie”吗?或者,是否允许用户制作非PIE可执行文件,以便此问题是gcc错误?
为方便起见,这是一个简单的示例:
$ cat app.c
int foo(int x, int y)
{
volatile int z = x;
return z + y;
}
$ cat main.c
extern int foo(int, int);
int main(int argc, char* argv[])
{
return foo(argc, 4);
}
$ gcc -o app.o -c app.c
$ gcc -o main.o -c -fPIC main.c
$ gcc -o libmain.so -shared main.o
$ gcc -o app.x -L. -lmain -fuse-ld=gold -Wl,-v,-rpath=$PWD app.o
collect2 version 4.8.5 20150623 (Red Hat 4.8.5-36.0.2)
/usr/bin/ld.gold --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -dynamic-linker /lib/ld-linux-aarch64.so.1 -X -o app.x /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o -L. -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5 -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../.. -lmain -v -rpath=/home/aion1223/workspace/shared app.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o
GNU gold (version 2.27-34.base.0.2.el7) 1.12
答案 0 :(得分:0)
此问题已在此处讨论:
我想gcc很清楚,给crt1.o是正确的行为,因为最终的可执行文件是非PIE。似乎根据最终的可执行文件选择crt1.o。
根据评论,gcc这样做是为了给crt1.o。因此,这不是gcc错误。然后,这应该是黄金问题或glibc问题。